API::PageConfiguration may have conflicting preference values between WebPreferences and WebPreferencesStore::ValueMap instance variables
<https://webkit.org/b/209678>
<rdar://problem/60981271>

Reviewed by Brent Fulgham.

Source/WebKit:

We fix this bug by removing
API::PageConfiguration::m_preferenceValues and
WebPageProxy::m_configurationPreferenceValues, and instead set
values directly on the WebPreferences object, which holds values
in its WebPreferencesStore instance variable.  This change only
requires that the API::PageConfiguration object has
m_preferences set to a valid WebPreferences object before using
the settings APIs.

Covered by WKAttachment TestWebKitAPI tests and
editing/undo-manager layout tests, among others.

* UIProcess/API/APIPageConfiguration.cpp:
(API::PageConfiguration::copy const):
- Remove use of m_preferenceValues instance variable.
* UIProcess/API/APIPageConfiguration.h:
- Update headers after removing WebPreferencesStore.h.
(API::PageConfiguration::preferenceValues): Delete.
- Remove use of m_preferenceValues instance variable.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _setupPageConfiguration:]):
- Switch to use WebPreferences methods for settings.

* UIProcess/API/mac/WKView.mm:
(-[WKView initWithFrame:contextRef:pageGroupRef:relatedToPage:]):
- Create WebPreferences object for API::PageConfiguration
  object.  This is what WebProcessPool::createWebPage() does
  when creating a WebPageProxy object.
- Switch to use WebPreferences method to set
  SystemLayoutDirection.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::WebPageProxy):
- Remove initialization of m_configurationPreferenceValues.
- Switch to use WebPreferences method to set
  DisableScreenSizeOverride.
(WebKit::WebPageProxy::preferencesStore const):
- Simplify this method after removing
  m_configurationPreferenceValues.
* UIProcess/WebPageProxy.h:
- Remove m_configurationPreferenceValues.

Tools:

* TestWebKitAPI/Tests/WebKit/mac/GetBackingScaleFactor.mm:
(TestWebKitAPI::TEST):
- Fix WKView constructor to pass a valid WKPageGroupRef.

* WebKitTestRunner/TestController.cpp:
(WTR::updateTestOptionsFromTestHeader):
* WebKitTestRunner/TestOptions.h:
(WTR::TestOptions::hasSameInitializationOptions const):
* WebKitTestRunner/cocoa/TestControllerCocoa.mm:
(WTR::TestController::platformCreateWebView):
- Remove support for custom "enableUndoManagerAPI" setting since
  layout tests should use "internal:UndoManagerAPIEnabled"
  instead.

LayoutTests:

* editing/undo-manager/undo-manager-add-item-exceptions.html:
* editing/undo-manager/undo-manager-add-item.html:
* editing/undo-manager/undo-manager-delete-stale-undo-items.html:
* editing/undo-manager/undo-manager-interfaces.html:
* editing/undo-manager/undo-manager-item-labels.html:
* editing/undo-manager/undo-manager-keeps-wrapper-alive.html:
* editing/undo-manager/undo-manager-undo-redo-after-garbage-collection.html:
- Fix tests to use "internal:UndoManagerAPIEnabled=true" instead
  of custom "enableUndoManagerAPI=true" setting, which is being
  removed since it doesn't work after the changes to WebKit.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@259399 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index da1e1c9..794f1f3 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,22 @@
+2020-04-02  David Kilzer  <ddkilzer@apple.com>
+
+        API::PageConfiguration may have conflicting preference values between WebPreferences and WebPreferencesStore::ValueMap instance variables
+        <https://webkit.org/b/209678>
+        <rdar://problem/60981271>
+
+        Reviewed by Brent Fulgham.
+
+        * editing/undo-manager/undo-manager-add-item-exceptions.html:
+        * editing/undo-manager/undo-manager-add-item.html:
+        * editing/undo-manager/undo-manager-delete-stale-undo-items.html:
+        * editing/undo-manager/undo-manager-interfaces.html:
+        * editing/undo-manager/undo-manager-item-labels.html:
+        * editing/undo-manager/undo-manager-keeps-wrapper-alive.html:
+        * editing/undo-manager/undo-manager-undo-redo-after-garbage-collection.html:
+        - Fix tests to use "internal:UndoManagerAPIEnabled=true" instead
+          of custom "enableUndoManagerAPI=true" setting, which is being
+          removed since it doesn't work after the changes to WebKit.
+
 2020-04-02  Chris Dumez  <cdumez@apple.com>
 
         [ Mac wk1 ] fast/loader/child-frame-add-after-back-forward.html  is flaky timing out.
diff --git a/LayoutTests/editing/undo-manager/undo-manager-add-item-exceptions.html b/LayoutTests/editing/undo-manager/undo-manager-add-item-exceptions.html
index 6e653e1..404ec02 100644
--- a/LayoutTests/editing/undo-manager/undo-manager-add-item-exceptions.html
+++ b/LayoutTests/editing/undo-manager/undo-manager-add-item-exceptions.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html> <!-- webkit-test-runner [ enableUndoManagerAPI=true ] -->
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:UndoManagerAPIEnabled=true ] -->
 <html>
     <meta charset="utf8">
     <head>
diff --git a/LayoutTests/editing/undo-manager/undo-manager-add-item.html b/LayoutTests/editing/undo-manager/undo-manager-add-item.html
index a326c8e..8819416 100644
--- a/LayoutTests/editing/undo-manager/undo-manager-add-item.html
+++ b/LayoutTests/editing/undo-manager/undo-manager-add-item.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html> <!-- webkit-test-runner [ enableUndoManagerAPI=true ] -->
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:UndoManagerAPIEnabled=true ] -->
 <html>
     <head>
         <script src="../../resources/js-test.js"></script>
diff --git a/LayoutTests/editing/undo-manager/undo-manager-delete-stale-undo-items.html b/LayoutTests/editing/undo-manager/undo-manager-delete-stale-undo-items.html
index e528900..71fbe4f 100644
--- a/LayoutTests/editing/undo-manager/undo-manager-delete-stale-undo-items.html
+++ b/LayoutTests/editing/undo-manager/undo-manager-delete-stale-undo-items.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html> <!-- webkit-test-runner [ enableUndoManagerAPI=true ] -->
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:UndoManagerAPIEnabled=true ] -->
 <html>
     <meta charset="utf8">
     <head>
diff --git a/LayoutTests/editing/undo-manager/undo-manager-interfaces.html b/LayoutTests/editing/undo-manager/undo-manager-interfaces.html
index 93b2ca7..0bfc7e0 100644
--- a/LayoutTests/editing/undo-manager/undo-manager-interfaces.html
+++ b/LayoutTests/editing/undo-manager/undo-manager-interfaces.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html> <!-- webkit-test-runner [ enableUndoManagerAPI=true ] -->
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:UndoManagerAPIEnabled=true ] -->
 <html>
     <head>
         <script src="../../resources/js-test.js"></script>
diff --git a/LayoutTests/editing/undo-manager/undo-manager-item-labels.html b/LayoutTests/editing/undo-manager/undo-manager-item-labels.html
index 84a7f17..5ac698b 100644
--- a/LayoutTests/editing/undo-manager/undo-manager-item-labels.html
+++ b/LayoutTests/editing/undo-manager/undo-manager-item-labels.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html> <!-- webkit-test-runner [ enableUndoManagerAPI=true ] -->
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:UndoManagerAPIEnabled=true ] -->
 <html>
     <meta charset="utf8">
     <head>
diff --git a/LayoutTests/editing/undo-manager/undo-manager-keeps-wrapper-alive.html b/LayoutTests/editing/undo-manager/undo-manager-keeps-wrapper-alive.html
index bccce51..801dd9e 100644
--- a/LayoutTests/editing/undo-manager/undo-manager-keeps-wrapper-alive.html
+++ b/LayoutTests/editing/undo-manager/undo-manager-keeps-wrapper-alive.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html> <!-- webkit-test-runner [ enableUndoManagerAPI=true ] -->
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:UndoManagerAPIEnabled=true ] -->
 <html>
     <head>
         <script src="../../resources/js-test.js"></script>
diff --git a/LayoutTests/editing/undo-manager/undo-manager-undo-redo-after-garbage-collection.html b/LayoutTests/editing/undo-manager/undo-manager-undo-redo-after-garbage-collection.html
index cad0ced..b250e7c 100644
--- a/LayoutTests/editing/undo-manager/undo-manager-undo-redo-after-garbage-collection.html
+++ b/LayoutTests/editing/undo-manager/undo-manager-undo-redo-after-garbage-collection.html
@@ -1,4 +1,4 @@
-<!DOCTYPE html> <!-- webkit-test-runner [ enableUndoManagerAPI=true ] -->
+<!DOCTYPE html> <!-- webkit-test-runner [ internal:UndoManagerAPIEnabled=true ] -->
 <html>
     <meta charset="utf8">
     <head>
diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog
index 5fc3d0f..550725b 100644
--- a/Source/WebKit/ChangeLog
+++ b/Source/WebKit/ChangeLog
@@ -1,3 +1,54 @@
+2020-04-02  David Kilzer  <ddkilzer@apple.com>
+
+        API::PageConfiguration may have conflicting preference values between WebPreferences and WebPreferencesStore::ValueMap instance variables
+        <https://webkit.org/b/209678>
+        <rdar://problem/60981271>
+
+        Reviewed by Brent Fulgham.
+
+        We fix this bug by removing
+        API::PageConfiguration::m_preferenceValues and
+        WebPageProxy::m_configurationPreferenceValues, and instead set
+        values directly on the WebPreferences object, which holds values
+        in its WebPreferencesStore instance variable.  This change only
+        requires that the API::PageConfiguration object has
+        m_preferences set to a valid WebPreferences object before using
+        the settings APIs.
+
+        Covered by WKAttachment TestWebKitAPI tests and
+        editing/undo-manager layout tests, among others.
+
+        * UIProcess/API/APIPageConfiguration.cpp:
+        (API::PageConfiguration::copy const):
+        - Remove use of m_preferenceValues instance variable.
+        * UIProcess/API/APIPageConfiguration.h:
+        - Update headers after removing WebPreferencesStore.h.
+        (API::PageConfiguration::preferenceValues): Delete.
+        - Remove use of m_preferenceValues instance variable.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _setupPageConfiguration:]):
+        - Switch to use WebPreferences methods for settings.
+
+        * UIProcess/API/mac/WKView.mm:
+        (-[WKView initWithFrame:contextRef:pageGroupRef:relatedToPage:]):
+        - Create WebPreferences object for API::PageConfiguration
+          object.  This is what WebProcessPool::createWebPage() does
+          when creating a WebPageProxy object.
+        - Switch to use WebPreferences method to set
+          SystemLayoutDirection.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::WebPageProxy):
+        - Remove initialization of m_configurationPreferenceValues.
+        - Switch to use WebPreferences method to set
+          DisableScreenSizeOverride.
+        (WebKit::WebPageProxy::preferencesStore const):
+        - Simplify this method after removing
+          m_configurationPreferenceValues.
+        * UIProcess/WebPageProxy.h:
+        - Remove m_configurationPreferenceValues.
+
 2020-04-02  Per Arne Vollan  <pvollan@apple.com>
 
         [macOS] Remove redundant call to check in with Launch Services
diff --git a/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp b/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp
index c8d10b7..50ea13a 100644
--- a/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp
+++ b/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp
@@ -68,7 +68,6 @@
     copy->m_userContentController = this->m_userContentController;
     copy->m_pageGroup = this->m_pageGroup;
     copy->m_preferences = this->m_preferences;
-    copy->m_preferenceValues = this->m_preferenceValues;
     copy->m_relatedPage = this->m_relatedPage;
     copy->m_visitedLinkStore = this->m_visitedLinkStore;
     copy->m_websiteDataStore = this->m_websiteDataStore;
diff --git a/Source/WebKit/UIProcess/API/APIPageConfiguration.h b/Source/WebKit/UIProcess/API/APIPageConfiguration.h
index ff58c91..aa03ecf 100644
--- a/Source/WebKit/UIProcess/API/APIPageConfiguration.h
+++ b/Source/WebKit/UIProcess/API/APIPageConfiguration.h
@@ -26,11 +26,12 @@
 #pragma once
 
 #include "APIObject.h"
-#include "WebPreferencesStore.h"
 #include "WebViewCategory.h"
 #include <wtf/Forward.h>
 #include <wtf/GetPtr.h>
+#include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
+#include <wtf/text/WTFString.h>
 
 #if PLATFORM(IOS_FAMILY)
 OBJC_PROTOCOL(_UIClickInteractionDriving);
@@ -77,8 +78,6 @@
     WebKit::WebPreferences* preferences();
     void setPreferences(WebKit::WebPreferences*);
 
-    WebKit::WebPreferencesStore::ValueMap& preferenceValues() { return m_preferenceValues; }
-
     WebKit::WebPageProxy* relatedPage() const;
     void setRelatedPage(WebKit::WebPageProxy*);
 
@@ -162,7 +161,6 @@
     RefPtr<WebKit::WebUserContentControllerProxy> m_userContentController;
     RefPtr<WebKit::WebPageGroup> m_pageGroup;
     RefPtr<WebKit::WebPreferences> m_preferences;
-    WebKit::WebPreferencesStore::ValueMap m_preferenceValues;
     RefPtr<WebKit::WebPageProxy> m_relatedPage;
     RefPtr<WebKit::VisitedLinkStore> m_visitedLinkStore;
 
diff --git a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
index 53a0f99..c2cc653 100644
--- a/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
+++ b/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
@@ -89,7 +89,7 @@
 #import "WebFullScreenManagerProxy.h"
 #import "WebPageGroup.h"
 #import "WebPageProxy.h"
-#import "WebPreferencesKeys.h"
+#import "WebPreferences.h"
 #import "WebProcessPool.h"
 #import "WebProcessProxy.h"
 #import "WebURLSchemeHandlerCocoa.h"
@@ -436,95 +436,95 @@
 
     pageConfiguration->setAdditionalSupportedImageTypes(WebCore::webCoreStringVectorFromNSStringArray([_configuration _additionalSupportedImageTypes]));
 
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::suppressesIncrementalRenderingKey(), WebKit::WebPreferencesStore::Value(!![_configuration suppressesIncrementalRendering]));
+    pageConfiguration->preferences()->setSuppressesIncrementalRendering(!![_configuration suppressesIncrementalRendering]);
 
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::shouldRespectImageOrientationKey(), WebKit::WebPreferencesStore::Value(!![_configuration _respectsImageOrientation]));
+    pageConfiguration->preferences()->setShouldRespectImageOrientation(!![_configuration _respectsImageOrientation]);
 #if !PLATFORM(MAC)
     // FIXME: Expose WKPreferences._shouldPrintBackgrounds on iOS, adopt it in all iOS clients, and remove this and WKWebViewConfiguration._printsBackgrounds.
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::shouldPrintBackgroundsKey(), WebKit::WebPreferencesStore::Value(!![_configuration _printsBackgrounds]));
+    pageConfiguration->preferences()->setShouldPrintBackgrounds(!![_configuration _printsBackgrounds]);
 #endif
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::incrementalRenderingSuppressionTimeoutKey(), WebKit::WebPreferencesStore::Value([_configuration _incrementalRenderingSuppressionTimeout]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::javaScriptMarkupEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowsJavaScriptMarkup]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::shouldConvertPositionStyleOnCopyKey(), WebKit::WebPreferencesStore::Value(!![_configuration _convertsPositionStyleOnCopy]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::httpEquivEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowsMetaRefresh]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowUniversalAccessFromFileURLsKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowUniversalAccessFromFileURLs]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowTopNavigationToDataURLsKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowTopNavigationToDataURLs]));
+    pageConfiguration->preferences()->setIncrementalRenderingSuppressionTimeout([_configuration _incrementalRenderingSuppressionTimeout]);
+    pageConfiguration->preferences()->setJavaScriptMarkupEnabled(!![_configuration _allowsJavaScriptMarkup]);
+    pageConfiguration->preferences()->setShouldConvertPositionStyleOnCopy(!![_configuration _convertsPositionStyleOnCopy]);
+    pageConfiguration->preferences()->setHTTPEquivEnabled(!![_configuration _allowsMetaRefresh]);
+    pageConfiguration->preferences()->setAllowUniversalAccessFromFileURLs(!![_configuration _allowUniversalAccessFromFileURLs]);
+    pageConfiguration->preferences()->setAllowTopNavigationToDataURLs(!![_configuration _allowTopNavigationToDataURLs]);
     pageConfiguration->setWaitsForPaintAfterViewDidMoveToWindow([_configuration _waitsForPaintAfterViewDidMoveToWindow]);
     pageConfiguration->setDrawsBackground([_configuration _drawsBackground]);
     pageConfiguration->setControlledByAutomation([_configuration _isControlledByAutomation]);
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::incompleteImageBorderEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _incompleteImageBorderEnabled]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::shouldDeferAsynchronousScriptsUntilAfterDocumentLoadOrFirstPaintKey(), WebKit::WebPreferencesStore::Value(!![_configuration _shouldDeferAsynchronousScriptsUntilAfterDocumentLoad]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::shouldRestrictBaseURLSchemesKey(), WebKit::WebPreferencesStore::Value(shouldRestrictBaseURLSchemes()));
+    pageConfiguration->preferences()->setIncompleteImageBorderEnabled(!![_configuration _incompleteImageBorderEnabled]);
+    pageConfiguration->preferences()->setShouldDeferAsynchronousScriptsUntilAfterDocumentLoadOrFirstPaint(!![_configuration _shouldDeferAsynchronousScriptsUntilAfterDocumentLoad]);
+    pageConfiguration->preferences()->setShouldRestrictBaseURLSchemes(shouldRestrictBaseURLSchemes());
 
 #if PLATFORM(MAC)
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::showsURLsInToolTipsEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _showsURLsInToolTips]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::serviceControlsEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _serviceControlsEnabled]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::imageControlsEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _imageControlsEnabled]));
+    pageConfiguration->preferences()->setShowsURLsInToolTipsEnabled(!![_configuration _showsURLsInToolTips]);
+    pageConfiguration->preferences()->setServiceControlsEnabled(!![_configuration _serviceControlsEnabled]);
+    pageConfiguration->preferences()->setImageControlsEnabled(!![_configuration _imageControlsEnabled]);
 
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::userInterfaceDirectionPolicyKey(), WebKit::WebPreferencesStore::Value(convertUserInterfaceDirectionPolicy([_configuration userInterfaceDirectionPolicy])));
+    pageConfiguration->preferences()->setUserInterfaceDirectionPolicy(convertUserInterfaceDirectionPolicy([_configuration userInterfaceDirectionPolicy]));
     // We are in the View's initialization routine, so our client hasn't had time to set our user interface direction.
     // Therefore, according to the docs[1], "this property contains the value reported by the app's userInterfaceLayoutDirection property."
     // [1] http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/index.html#//apple_ref/doc/uid/20000014-SW222
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::systemLayoutDirectionKey(), WebKit::WebPreferencesStore::Value(convertSystemLayoutDirection(self.userInterfaceLayoutDirection)));
+    pageConfiguration->preferences()->setSystemLayoutDirection(convertSystemLayoutDirection(self.userInterfaceLayoutDirection));
 #endif
 
 #if PLATFORM(IOS_FAMILY)
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowsInlineMediaPlaybackKey(), WebKit::WebPreferencesStore::Value(!![_configuration allowsInlineMediaPlayback]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowsInlineMediaPlaybackAfterFullscreenKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowsInlineMediaPlaybackAfterFullscreen]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::inlineMediaPlaybackRequiresPlaysInlineAttributeKey(), WebKit::WebPreferencesStore::Value(!![_configuration _inlineMediaPlaybackRequiresPlaysInlineAttribute]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowsPictureInPictureMediaPlaybackKey(), WebKit::WebPreferencesStore::Value(!![_configuration allowsPictureInPictureMediaPlayback] && shouldAllowPictureInPictureMediaPlayback()));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::userInterfaceDirectionPolicyKey(), WebKit::WebPreferencesStore::Value(static_cast<uint32_t>(WebCore::UserInterfaceDirectionPolicy::Content)));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::systemLayoutDirectionKey(), WebKit::WebPreferencesStore::Value(static_cast<uint32_t>(WebCore::TextDirection::LTR)));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowSettingAnyXHRHeaderFromFileURLsKey(), WebKit::WebPreferencesStore::Value(shouldAllowSettingAnyXHRHeaderFromFileURLs()));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::shouldDecidePolicyBeforeLoadingQuickLookPreviewKey(), WebKit::WebPreferencesStore::Value(!![_configuration _shouldDecidePolicyBeforeLoadingQuickLookPreview]));
+    pageConfiguration->preferences()->setAllowsInlineMediaPlayback(!![_configuration allowsInlineMediaPlayback]);
+    pageConfiguration->preferences()->setAllowsInlineMediaPlaybackAfterFullscreen(!![_configuration _allowsInlineMediaPlaybackAfterFullscreen]);
+    pageConfiguration->preferences()->setInlineMediaPlaybackRequiresPlaysInlineAttribute(!![_configuration _inlineMediaPlaybackRequiresPlaysInlineAttribute]);
+    pageConfiguration->preferences()->setAllowsPictureInPictureMediaPlayback(!![_configuration allowsPictureInPictureMediaPlayback] && shouldAllowPictureInPictureMediaPlayback());
+    pageConfiguration->preferences()->setUserInterfaceDirectionPolicy(static_cast<uint32_t>(WebCore::UserInterfaceDirectionPolicy::Content));
+    pageConfiguration->preferences()->setSystemLayoutDirection(static_cast<uint32_t>(WebCore::TextDirection::LTR));
+    pageConfiguration->preferences()->setAllowSettingAnyXHRHeaderFromFileURLs(shouldAllowSettingAnyXHRHeaderFromFileURLs());
+    pageConfiguration->preferences()->setShouldDecidePolicyBeforeLoadingQuickLookPreview(!![_configuration _shouldDecidePolicyBeforeLoadingQuickLookPreview]);
 #if ENABLE(DEVICE_ORIENTATION)
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::deviceOrientationPermissionAPIEnabledKey(), WebKit::WebPreferencesStore::Value(linkedOnOrAfter(WebKit::SDKVersion::FirstWithDeviceOrientationAndMotionPermissionAPI)));
+    pageConfiguration->preferences()->setDeviceOrientationPermissionAPIEnabled(linkedOnOrAfter(WebKit::SDKVersion::FirstWithDeviceOrientationAndMotionPermissionAPI));
 #endif
 #if USE(SYSTEM_PREVIEW)
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::systemPreviewEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _systemPreviewEnabled]));
+    pageConfiguration->preferences()->setSystemPreviewEnabled(!![_configuration _systemPreviewEnabled]);
 #endif
 #endif // PLATFORM(IOS_FAMILY)
 
     WKAudiovisualMediaTypes mediaTypesRequiringUserGesture = [_configuration mediaTypesRequiringUserActionForPlayback];
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::requiresUserGestureForVideoPlaybackKey(), WebKit::WebPreferencesStore::Value((mediaTypesRequiringUserGesture & WKAudiovisualMediaTypeVideo) == WKAudiovisualMediaTypeVideo));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::requiresUserGestureForAudioPlaybackKey(), WebKit::WebPreferencesStore::Value(((mediaTypesRequiringUserGesture & WKAudiovisualMediaTypeAudio) == WKAudiovisualMediaTypeAudio)));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::requiresUserGestureToLoadVideoKey(), WebKit::WebPreferencesStore::Value(shouldRequireUserGestureToLoadVideo()));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::mainContentUserGestureOverrideEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _mainContentUserGestureOverrideEnabled]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::invisibleAutoplayNotPermittedKey(), WebKit::WebPreferencesStore::Value(!![_configuration _invisibleAutoplayNotPermitted]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::mediaDataLoadsAutomaticallyKey(), WebKit::WebPreferencesStore::Value(!![_configuration _mediaDataLoadsAutomatically]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::attachmentElementEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _attachmentElementEnabled]));
+    pageConfiguration->preferences()->setRequiresUserGestureForVideoPlayback((mediaTypesRequiringUserGesture & WKAudiovisualMediaTypeVideo) == WKAudiovisualMediaTypeVideo);
+    pageConfiguration->preferences()->setRequiresUserGestureForAudioPlayback(((mediaTypesRequiringUserGesture & WKAudiovisualMediaTypeAudio) == WKAudiovisualMediaTypeAudio));
+    pageConfiguration->preferences()->setRequiresUserGestureToLoadVideo(shouldRequireUserGestureToLoadVideo());
+    pageConfiguration->preferences()->setMainContentUserGestureOverrideEnabled(!![_configuration _mainContentUserGestureOverrideEnabled]);
+    pageConfiguration->preferences()->setInvisibleAutoplayNotPermitted(!![_configuration _invisibleAutoplayNotPermitted]);
+    pageConfiguration->preferences()->setMediaDataLoadsAutomatically(!![_configuration _mediaDataLoadsAutomatically]);
+    pageConfiguration->preferences()->setAttachmentElementEnabled(!![_configuration _attachmentElementEnabled]);
 
 #if ENABLE(DATA_DETECTION) && PLATFORM(IOS_FAMILY)
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::dataDetectorTypesKey(), WebKit::WebPreferencesStore::Value(static_cast<uint32_t>(fromWKDataDetectorTypes([_configuration dataDetectorTypes]))));
+    pageConfiguration->preferences()->setDataDetectorTypes(static_cast<uint32_t>(fromWKDataDetectorTypes([_configuration dataDetectorTypes])));
 #endif
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowsAirPlayForMediaPlaybackKey(), WebKit::WebPreferencesStore::Value(!![_configuration allowsAirPlayForMediaPlayback]));
+    pageConfiguration->preferences()->setAllowsAirPlayForMediaPlayback(!![_configuration allowsAirPlayForMediaPlayback]);
 #endif
 
 #if ENABLE(APPLE_PAY)
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::applePayEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _applePayEnabled]));
+    pageConfiguration->preferences()->setApplePayEnabled(!![_configuration _applePayEnabled]);
 #endif
 
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::needsStorageAccessFromFileURLsQuirkKey(), WebKit::WebPreferencesStore::Value(!![_configuration _needsStorageAccessFromFileURLsQuirk]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::mediaContentTypesRequiringHardwareSupportKey(), WebKit::WebPreferencesStore::Value(String([_configuration _mediaContentTypesRequiringHardwareSupport])));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowMediaContentTypesRequiringHardwareSupportAsFallbackKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowMediaContentTypesRequiringHardwareSupportAsFallback]));
+    pageConfiguration->preferences()->setNeedsStorageAccessFromFileURLsQuirk(!![_configuration _needsStorageAccessFromFileURLsQuirk]);
+    pageConfiguration->preferences()->setMediaContentTypesRequiringHardwareSupport(String([_configuration _mediaContentTypesRequiringHardwareSupport]));
+    pageConfiguration->preferences()->setAllowMediaContentTypesRequiringHardwareSupportAsFallback(!![_configuration _allowMediaContentTypesRequiringHardwareSupportAsFallback]);
 
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::colorFilterEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _colorFilterEnabled]));
+    pageConfiguration->preferences()->setColorFilterEnabled(!![_configuration _colorFilterEnabled]);
 
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::editableImagesEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _editableImagesEnabled]));
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::undoManagerAPIEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _undoManagerAPIEnabled]));
+    pageConfiguration->preferences()->setEditableImagesEnabled(!![_configuration _editableImagesEnabled]);
+    pageConfiguration->preferences()->setUndoManagerAPIEnabled(!![_configuration _undoManagerAPIEnabled]);
 
 #if ENABLE(LEGACY_ENCRYPTED_MEDIA)
-    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::legacyEncryptedMediaAPIEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _legacyEncryptedMediaAPIEnabled]));
+    pageConfiguration->preferences()->setLegacyEncryptedMediaAPIEnabled(!![_configuration _legacyEncryptedMediaAPIEnabled]);
 #endif
 
 #if PLATFORM(IOS_FAMILY) && ENABLE(SERVICE_WORKER)
     if (!WTF::processHasEntitlement("com.apple.developer.WebKit.ServiceWorkers"))
-        pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::serviceWorkersEnabledKey(), WebKit::WebPreferencesStore::Value(false));
+        pageConfiguration->preferences()->setServiceWorkersEnabled(false);
 #endif
 
     if (!linkedOnOrAfter(WebKit::SDKVersion::FirstWhereSiteSpecificQuirksAreEnabledByDefault))
-        pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::needsSiteSpecificQuirksKey(), WebKit::WebPreferencesStore::Value(false));
+        pageConfiguration->preferences()->setNeedsSiteSpecificQuirks(false);
 }
 
 - (void)_setUpSQLiteDatabaseTrackerClient
diff --git a/Source/WebKit/UIProcess/API/mac/WKView.mm b/Source/WebKit/UIProcess/API/mac/WKView.mm
index b42757f..629c845 100644
--- a/Source/WebKit/UIProcess/API/mac/WKView.mm
+++ b/Source/WebKit/UIProcess/API/mac/WKView.mm
@@ -39,7 +39,7 @@
 #import "WebKit2Initialize.h"
 #import "WebPageGroup.h"
 #import "WebPageProxy.h"
-#import "WebPreferencesKeys.h"
+#import "WebPreferences.h"
 #import "WebProcessPool.h"
 #import "WebViewImpl.h"
 #import "_WKLinkIconParametersInternal.h"
@@ -1194,7 +1194,8 @@
     configuration->setPageGroup(WebKit::toImpl(pageGroupRef));
     configuration->setRelatedPage(WebKit::toImpl(relatedPage));
 #if PLATFORM(MAC)
-    configuration->preferenceValues().set(WebKit::WebPreferencesKey::systemLayoutDirectionKey(), WebKit::WebPreferencesStore::Value(static_cast<uint32_t>(toUserInterfaceLayoutDirection(self.userInterfaceLayoutDirection))));
+    configuration->setPreferences(&configuration->pageGroup()->preferences());
+    configuration->preferences()->setSystemLayoutDirection(static_cast<uint32_t>(toUserInterfaceLayoutDirection(self.userInterfaceLayoutDirection)));
 #endif
 
     return [self initWithFrame:frame processPool:*WebKit::toImpl(contextRef) configuration:WTFMove(configuration)];
diff --git a/Source/WebKit/UIProcess/WebPageProxy.cpp b/Source/WebKit/UIProcess/WebPageProxy.cpp
index efa2ba4..283ac48 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.cpp
+++ b/Source/WebKit/UIProcess/WebPageProxy.cpp
@@ -474,7 +474,6 @@
     , m_isSmartInsertDeleteEnabled(TextChecker::isSmartInsertDeleteEnabled())
 #endif
     , m_pageLoadState(*this)
-    , m_configurationPreferenceValues(m_configuration->preferenceValues())
     , m_inspectorController(makeUnique<WebPageInspectorController>(*this))
 #if ENABLE(REMOTE_INSPECTOR)
     , m_inspectorDebuggable(makeUnique<WebPageDebuggable>(*this))
@@ -517,7 +516,7 @@
     m_process->addMessageReceiver(Messages::WebPageProxy::messageReceiverName(), m_webPageID, *this);
 
 #if PLATFORM(IOS_FAMILY)
-    DeprecatedGlobalSettings::setDisableScreenSizeOverride(preferencesStore().getBoolValueForKey(WebPreferencesKey::disableScreenSizeOverrideKey()));
+    DeprecatedGlobalSettings::setDisableScreenSizeOverride(m_preferences->disableScreenSizeOverride());
 #endif
 
 #if PLATFORM(COCOA)
@@ -2765,14 +2764,7 @@
 
 WebPreferencesStore WebPageProxy::preferencesStore() const
 {
-    if (m_configurationPreferenceValues.isEmpty())
-        return m_preferences->store();
-
-    WebPreferencesStore store = m_preferences->store();
-    for (const auto& preference : m_configurationPreferenceValues)
-        store.m_values.set(preference.key, preference.value);
-
-    return store;
+    return m_preferences->store();
 }
 
 #if ENABLE(NETSCAPE_PLUGIN_API)
diff --git a/Source/WebKit/UIProcess/WebPageProxy.h b/Source/WebKit/UIProcess/WebPageProxy.h
index 56be34e..d3bed1a 100644
--- a/Source/WebKit/UIProcess/WebPageProxy.h
+++ b/Source/WebKit/UIProcess/WebPageProxy.h
@@ -2644,7 +2644,6 @@
 
     ActivityStateChangeID m_currentActivityStateChangeID { ActivityStateChangeAsynchronous };
 
-    WebPreferencesStore::ValueMap m_configurationPreferenceValues;
     OptionSet<WebCore::ActivityState::Flag> m_potentiallyChangedActivityStateFlags;
     bool m_activityStateChangeWantsSynchronousReply { false };
     Vector<CallbackID> m_nextActivityStateChangeCallbacks;
diff --git a/Tools/ChangeLog b/Tools/ChangeLog
index a5386d6..c026fd8 100644
--- a/Tools/ChangeLog
+++ b/Tools/ChangeLog
@@ -1,3 +1,25 @@
+2020-04-02  David Kilzer  <ddkilzer@apple.com>
+
+        API::PageConfiguration may have conflicting preference values between WebPreferences and WebPreferencesStore::ValueMap instance variables
+        <https://webkit.org/b/209678>
+        <rdar://problem/60981271>
+
+        Reviewed by Brent Fulgham.
+
+        * TestWebKitAPI/Tests/WebKit/mac/GetBackingScaleFactor.mm:
+        (TestWebKitAPI::TEST):
+        - Fix WKView constructor to pass a valid WKPageGroupRef.
+
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::updateTestOptionsFromTestHeader):
+        * WebKitTestRunner/TestOptions.h:
+        (WTR::TestOptions::hasSameInitializationOptions const):
+        * WebKitTestRunner/cocoa/TestControllerCocoa.mm:
+        (WTR::TestController::platformCreateWebView):
+        - Remove support for custom "enableUndoManagerAPI" setting since
+          layout tests should use "internal:UndoManagerAPIEnabled"
+          instead.
+
 2020-04-02  Alex Christensen  <achristensen@webkit.org>
 
         Add SPI to restrict loading to main resources or non-network loads
diff --git a/Tools/TestWebKitAPI/Tests/WebKit/mac/GetBackingScaleFactor.mm b/Tools/TestWebKitAPI/Tests/WebKit/mac/GetBackingScaleFactor.mm
index ed40758..4268a24 100644
--- a/Tools/TestWebKitAPI/Tests/WebKit/mac/GetBackingScaleFactor.mm
+++ b/Tools/TestWebKitAPI/Tests/WebKit/mac/GetBackingScaleFactor.mm
@@ -68,7 +68,8 @@
 {
     WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("GetBackingScaleFactorTest"));
     setInjectedBundleClient(context.get());
-    RetainPtr<WKView> view = adoptNS([[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) contextRef:context.get() pageGroupRef:0]);
+    auto pageGroup = adoptWK(WKPageGroupCreateWithIdentifier(Util::toWK("GetBackingScaleFactorPageGroup").get()));
+    auto view = adoptNS([[WKView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) contextRef:context.get() pageGroupRef:pageGroup.get()]);
     [[view browsingContextController] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"about:blank"]]];
 
     RetainPtr<SyntheticBackingScaleFactorWindow> window1 = createWindow();
diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp
index 2a9bcb6..77a6443 100644
--- a/Tools/WebKitTestRunner/TestController.cpp
+++ b/Tools/WebKitTestRunner/TestController.cpp
@@ -1484,8 +1484,6 @@
             testOptions.enableEditableImages = parseBooleanTestHeaderValue(value);
         else if (key == "editable")
             testOptions.editable = parseBooleanTestHeaderValue(value);
-        else if (key == "enableUndoManagerAPI")
-            testOptions.enableUndoManagerAPI = parseBooleanTestHeaderValue(value);
         else if (key == "shouldHandleRunOpenPanel")
             testOptions.shouldHandleRunOpenPanel = parseBooleanTestHeaderValue(value);
         else if (key == "shouldPresentPopovers")
diff --git a/Tools/WebKitTestRunner/TestOptions.h b/Tools/WebKitTestRunner/TestOptions.h
index bcc0b85..b94f8f7 100644
--- a/Tools/WebKitTestRunner/TestOptions.h
+++ b/Tools/WebKitTestRunner/TestOptions.h
@@ -93,7 +93,6 @@
     bool enableServiceControls { false };
     bool enableEditableImages { false };
     bool editable { false };
-    bool enableUndoManagerAPI { false };
     bool shouldHandleRunOpenPanel { true };
     bool shouldPresentPopovers { true };
     bool enableAppNap { false };
@@ -157,7 +156,6 @@
             || shouldIgnoreMetaViewport != options.shouldIgnoreMetaViewport
             || enableEditableImages != options.enableEditableImages
             || editable != options.editable
-            || enableUndoManagerAPI != options.enableUndoManagerAPI
             || shouldHandleRunOpenPanel != options.shouldHandleRunOpenPanel
             || shouldPresentPopovers != options.shouldPresentPopovers
             || contentInsetTop != options.contentInsetTop
diff --git a/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm b/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm
index 98a586c..548fe73 100644
--- a/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm
+++ b/Tools/WebKitTestRunner/cocoa/TestControllerCocoa.mm
@@ -149,9 +149,6 @@
     if (options.enableEditableImages)
         [copiedConfiguration _setEditableImagesEnabled:YES];
 
-    if (options.enableUndoManagerAPI)
-        [copiedConfiguration _setUndoManagerAPIEnabled:YES];
-
     if (options.useEphemeralSession) {
         auto ephemeralWebsiteDataStore = [WKWebsiteDataStore nonPersistentDataStore];
         [ephemeralWebsiteDataStore _setResourceLoadStatisticsEnabled:YES];