[Cocoa] Allow testing with the system language
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 13 Sep 2015 03:47:56 +0000 (03:47 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 13 Sep 2015 03:47:56 +0000 (03:47 +0000)
https://bugs.webkit.org/show_bug.cgi?id=148671

Reviewed by Anders Carlsson and Alexey Proskuryakov.

Source/WebKit2:

This patch adds two new SPI functions for setting and retrieving a vector of
override languages to/from the WKContextConfiguration. The implementation of
these functions holds state inside WebProcessPoolConfiguration. Then, when
we launch a process, the WebProcessProxy will inject these override languages
into the ProcessLauncher::LaunchOptions so that the ProcessLauncher can
inject these languages into the XPC Bootstrap message. Then, in the Web
Process's main(), the XPC Boostrap message is read, and the platform
languages are set via NSUserDefaults setting a volatile domain.

* Shared/EntryPointUtilities/mac/XPCService/XPCServiceMain.Development.mm:
(main): Set the volatile domain with NSUserDefaults.
* UIProcess/API/APIProcessPoolConfiguration.cpp:
(API::ProcessPoolConfiguration::copy):
* UIProcess/API/APIProcessPoolConfiguration.h: Hold state for the override
languages.
* UIProcess/API/C/WKContextConfigurationRef.cpp:
(WKContextConfigurationCopyOverrideLanguages): SPI.
(WKContextConfigurationSetOverrideLanguages): Ditto.
* UIProcess/API/C/WKContextConfigurationRef.h:
* UIProcess/Launcher/mac/ProcessLauncherMac.mm:
(WebKit::connectToService): Inject the languages into the XPC Bootstrap
message.
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::getLaunchOptions): Inject the override languages
into the ProcessLauncher::LaunchOptions.

Tools:

React to tests marked with language=lang1,lang2,etc in their header.
Once this information is parsed, pass it to
WKContextConfigurationSetOverrideLanguages().

* WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm:
(WTR::InjectedBundle::platformInitialize): Don't clobber the language
list.
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::createWebViewWithOptions): Call
WKContextConfigurationSetOverrideLanguages().
(WTR::updateTestOptionsFromTestHeader): Inspect the language option.
* WebKitTestRunner/TestOptions.h:
* WebKitTestRunner/ios/PlatformWebViewIOS.mm:
(WTR::PlatformWebView::viewSupportsOptions): Cause a differing language
option to restart the web process.
* WebKitTestRunner/mac/PlatformWebViewMac.mm:
(WTR::PlatformWebView::viewSupportsOptions): Ditto.

LayoutTests:

Add a test for the declarative form of setting the system language.

* fast/text/international/system-language/declarative-language-expected.txt: Added.
* fast/text/international/system-language/declarative-language.html: Added.
* platform/efl/TestExpectations:
* platform/gtk/TestExpectations:
* platform/mac-wk1/TestExpectations:
* platform/mac/TestExpectations:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@189669 268f45cc-cd09-0410-ab3c-d52691b4dbfc

21 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/text/international/system-language/declarative-language-expected.txt [new file with mode: 0644]
LayoutTests/fast/text/international/system-language/declarative-language.html [new file with mode: 0644]
LayoutTests/platform/efl/TestExpectations
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/mac/TestExpectations
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/EntryPointUtilities/mac/XPCService/XPCServiceMain.Development.mm
Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.cpp
Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h
Source/WebKit2/UIProcess/API/C/WKContextConfigurationRef.cpp
Source/WebKit2/UIProcess/API/C/WKContextConfigurationRef.h
Source/WebKit2/UIProcess/Launcher/mac/ProcessLauncherMac.mm
Source/WebKit2/UIProcess/WebProcessProxy.cpp
Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/TestOptions.h
Tools/WebKitTestRunner/ios/PlatformWebViewIOS.mm
Tools/WebKitTestRunner/mac/PlatformWebViewMac.mm

index 2eea525..b72c684 100644 (file)
@@ -1,3 +1,19 @@
+2015-09-12  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [Cocoa] Allow testing with the system language
+        https://bugs.webkit.org/show_bug.cgi?id=148671
+
+        Reviewed by Anders Carlsson and Alexey Proskuryakov.
+
+        Add a test for the declarative form of setting the system language.
+
+        * fast/text/international/system-language/declarative-language-expected.txt: Added.
+        * fast/text/international/system-language/declarative-language.html: Added.
+        * platform/efl/TestExpectations:
+        * platform/gtk/TestExpectations:
+        * platform/mac-wk1/TestExpectations:
+        * platform/mac/TestExpectations:
+
 2015-09-12  Chris Dumez  <cdumez@apple.com>
 
         window.EventTarget should exist
diff --git a/LayoutTests/fast/text/international/system-language/declarative-language-expected.txt b/LayoutTests/fast/text/international/system-language/declarative-language-expected.txt
new file mode 100644 (file)
index 0000000..f35d5f4
--- /dev/null
@@ -0,0 +1,8 @@
+PASS internals.userPreferredLanguages().length is 2
+PASS internals.userPreferredLanguages()[0].startsWith('ko') is true
+PASS internals.userPreferredLanguages()[1].startsWith('zh') is true
+PASS internals.userPreferredLanguages().length is 3
+PASS internals.userPreferredLanguages()[0] is "hi"
+PASS internals.userPreferredLanguages()[1] is "jp"
+PASS internals.userPreferredLanguages()[2] is "in"
+
diff --git a/LayoutTests/fast/text/international/system-language/declarative-language.html b/LayoutTests/fast/text/international/system-language/declarative-language.html
new file mode 100644 (file)
index 0000000..d2b2d20
--- /dev/null
@@ -0,0 +1,21 @@
+<!DOCTYPE html><!-- webkit-test-runner [ language=ko,zh ] -->
+<html>
+<head>
+<script src="../../../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+if (window.internals) {
+    shouldBe("internals.userPreferredLanguages().length", "2");
+    shouldBeTrue("internals.userPreferredLanguages()[0].startsWith('ko')");
+    shouldBeTrue("internals.userPreferredLanguages()[1].startsWith('zh')");
+    internals.setUserPreferredLanguages(["hi", "jp", "in"]);
+    shouldBe("internals.userPreferredLanguages().length", "3");
+    shouldBeEqualToString("internals.userPreferredLanguages()[0]", "hi");
+    shouldBeEqualToString("internals.userPreferredLanguages()[1]", "jp");
+    shouldBeEqualToString("internals.userPreferredLanguages()[2]", "in");
+}
+</script>
+<script src="../../../resources/js-test-post.js"></script>
+</body>
+</html>
index 5a0d526..141ea1e 100644 (file)
@@ -2548,3 +2548,6 @@ webkit.org/b/148470 svg/text/select-x-list-with-tspans-2.svg [ Failure ]
 webkit.org/b/148470 svg/text/select-x-list-with-tspans-3.svg [ Failure ]
 webkit.org/b/148470 svg/text/select-x-list-with-tspans-4.svg [ Failure ]
 webkit.org/b/148470 svg/text/selection-doubleclick.svg [ Failure ]
+
+# Mocking the system language is not implemented in EFL.
+fast/text/international/system-language [ Failure ]
index bb7a9fc..fabdb77 100644 (file)
@@ -2612,3 +2612,6 @@ css3/line-break-language-sensitive [ Pass ImageOnlyFailure ]
 
 # Media controls tests are OS X only
 media/controls [ Skip ]
+
+# Mocking the system language is not implemented in GTK.
+fast/text/international/system-language [ Failure ]
index 3db23e4..c17aa94 100644 (file)
@@ -141,3 +141,6 @@ loader/navigation-policy [ Skip ]
 
 # This test is WebKit2-only
 http/tests/contentfiltering/load-substitute-data-from-appcache.html
+
+# Testing the system language declaratively only makes sense in WK2, because it's implemented in WebKitTestRunner by launching a new WebContent process.
+fast/text/international/system-language [ Failure ]
index 05936d9..4cd440c 100644 (file)
@@ -1284,3 +1284,6 @@ webkit.org/b/143258 [ Mavericks ] http/tests/cache/disk-cache/disk-cache-validat
 
 # Colorspaces on CA OpenGL layers not available in Mavericks and Yosemite
 [ Mavericks Yosemite ] fast/canvas/webgl/match-page-color-space.html [ Skip ]
+
+# Mocking the system language relies on Bootstrap XPC messages, which are not supported in Mavericks.
+[ Mavericks ] fast/text/international/system-language [ Failure ]
index 2e0be8a..8fe956a 100644 (file)
@@ -1,3 +1,36 @@
+2015-09-12  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [Cocoa] Allow testing with the system language
+        https://bugs.webkit.org/show_bug.cgi?id=148671
+
+        Reviewed by Anders Carlsson and Alexey Proskuryakov.
+
+        This patch adds two new SPI functions for setting and retrieving a vector of
+        override languages to/from the WKContextConfiguration. The implementation of
+        these functions holds state inside WebProcessPoolConfiguration. Then, when
+        we launch a process, the WebProcessProxy will inject these override languages
+        into the ProcessLauncher::LaunchOptions so that the ProcessLauncher can
+        inject these languages into the XPC Bootstrap message. Then, in the Web
+        Process's main(), the XPC Boostrap message is read, and the platform
+        languages are set via NSUserDefaults setting a volatile domain.
+
+        * Shared/EntryPointUtilities/mac/XPCService/XPCServiceMain.Development.mm:
+        (main): Set the volatile domain with NSUserDefaults.
+        * UIProcess/API/APIProcessPoolConfiguration.cpp:
+        (API::ProcessPoolConfiguration::copy):
+        * UIProcess/API/APIProcessPoolConfiguration.h: Hold state for the override
+        languages.
+        * UIProcess/API/C/WKContextConfigurationRef.cpp:
+        (WKContextConfigurationCopyOverrideLanguages): SPI.
+        (WKContextConfigurationSetOverrideLanguages): Ditto.
+        * UIProcess/API/C/WKContextConfigurationRef.h:
+        * UIProcess/Launcher/mac/ProcessLauncherMac.mm:
+        (WebKit::connectToService): Inject the languages into the XPC Bootstrap
+        message.
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::getLaunchOptions): Inject the override languages
+        into the ProcessLauncher::LaunchOptions.
+
 2015-09-12  Alexey Proskuryakov  <ap@apple.com>
 
         [iOS] Allow UDP networking
index a996fac..6fcd988 100644 (file)
@@ -32,6 +32,7 @@
 #import <stdio.h>
 #import <stdlib.h>
 #import <wtf/OSObjectPtr.h>
+#import <wtf/RetainPtr.h>
 #import <wtf/spi/darwin/XPCSPI.h>
 
 namespace WebKit {
@@ -159,6 +160,22 @@ using namespace WebKit;
 
 int main(int argc, char** argv)
 {
+#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
+    if (auto bootstrap = adoptOSObject(xpc_copy_bootstrap())) {
+        if (xpc_object_t languages = xpc_dictionary_get_value(bootstrap.get(), "OverrideLanguages")) {
+            NSDictionary *existingArguments = [[NSUserDefaults standardUserDefaults] volatileDomainForName:NSArgumentDomain];
+            NSMutableDictionary *newArguments = [existingArguments mutableCopy];
+            RetainPtr<NSMutableArray *> newLanguages = adoptNS([[NSMutableArray alloc] init]);
+            xpc_array_apply(languages, ^(size_t index, xpc_object_t value) {
+                [newLanguages addObject:[NSString stringWithCString:xpc_string_get_string_ptr(value) encoding:NSUTF8StringEncoding]];
+                return true;
+            });
+            [newArguments setValue:newLanguages.get() forKey:@"AppleLanguages"];
+            [[NSUserDefaults standardUserDefaults] setVolatileDomain:newArguments forName:NSArgumentDomain];
+        }
+    }
+#endif
+
 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
 #pragma clang diagnostic push
 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
index 0b4186b..0dc8e29 100644 (file)
@@ -88,6 +88,7 @@ Ref<ProcessPoolConfiguration> ProcessPoolConfiguration::copy()
     copy->m_webSQLDatabaseDirectory = this->m_webSQLDatabaseDirectory;
     copy->m_cachePartitionedURLSchemes = this->m_cachePartitionedURLSchemes;
     copy->m_fullySynchronousModeIsAllowedForTesting = this->m_fullySynchronousModeIsAllowedForTesting;
+    copy->m_overrideLanguages = this->m_overrideLanguages;
     
     return copy;
 }
index 4a7a49f..6dc9f2a 100644 (file)
@@ -90,6 +90,9 @@ public:
     bool fullySynchronousModeIsAllowedForTesting() const { return m_fullySynchronousModeIsAllowedForTesting; }
     void setFullySynchronousModeIsAllowedForTesting(bool allowed) { m_fullySynchronousModeIsAllowedForTesting = allowed; }
 
+    const Vector<WTF::String>& overrideLanguages() const { return m_overrideLanguages; }
+    void setOverrideLanguages(Vector<WTF::String>&& languages) { m_overrideLanguages = WTF::move(languages); }
+
 private:
     bool m_shouldHaveLegacyDataStore { false };
 
@@ -108,6 +111,7 @@ private:
     WTF::String m_mediaKeysStorageDirectory;
     Vector<WTF::String> m_cachePartitionedURLSchemes;
     bool m_fullySynchronousModeIsAllowedForTesting { false };
+    Vector<WTF::String> m_overrideLanguages;
 };
 
 } // namespace API
index f607cbf..fe4f913 100644 (file)
@@ -121,3 +121,13 @@ void WKContextConfigurationSetFullySynchronousModeIsAllowedForTesting(WKContextC
 {
     toImpl(configuration)->setFullySynchronousModeIsAllowedForTesting(allowed);
 }
+
+WKArrayRef WKContextConfigurationCopyOverrideLanguages(WKContextConfigurationRef configuration)
+{
+    return toAPI(&API::Array::createStringArray(toImpl(configuration)->overrideLanguages()).leakRef());
+}
+
+void WKContextConfigurationSetOverrideLanguages(WKContextConfigurationRef configuration, WKArrayRef overrideLanguages)
+{
+    toImpl(configuration)->setOverrideLanguages(toImpl(overrideLanguages)->toStringVector());
+}
index 7019104..1ee343a 100644 (file)
@@ -58,6 +58,9 @@ WK_EXPORT void WKContextConfigurationSetMediaKeysStorageDirectory(WKContextConfi
 WK_EXPORT bool WKContextConfigurationFullySynchronousModeIsAllowedForTesting(WKContextConfigurationRef configuration);
 WK_EXPORT void WKContextConfigurationSetFullySynchronousModeIsAllowedForTesting(WKContextConfigurationRef configuration, bool allowed);
 
+WK_EXPORT WKArrayRef WKContextConfigurationCopyOverrideLanguages(WKContextConfigurationRef configuration);
+WK_EXPORT void WKContextConfigurationSetOverrideLanguages(WKContextConfigurationRef configuration, WKArrayRef overrideLanguages);
+
 #ifdef __cplusplus
 }
 #endif
index 3d4e170..4536848 100644 (file)
@@ -243,6 +243,17 @@ static void connectToService(const ProcessLauncher::LaunchOptions& launchOptions
         xpc_dictionary_set_string(containerEnvironmentVariables.get(), "TMPDIR", environmentTMPDIR);
     xpc_dictionary_set_value(initializationMessage.get(), "ContainerEnvironmentVariables", containerEnvironmentVariables.get());
 #endif
+
+    auto languagesIterator = launchOptions.extraInitializationData.find("OverrideLanguages");
+    if (languagesIterator != launchOptions.extraInitializationData.end()) {
+        auto languages = adoptOSObject(xpc_array_create(nullptr, 0));
+        Vector<String> languageVector;
+        languagesIterator->value.split(",", false, languageVector);
+        for (auto& language : languageVector)
+            xpc_array_set_string(languages.get(), XPC_ARRAY_APPEND, language.utf8().data());
+        xpc_dictionary_set_value(initializationMessage.get(), "OverrideLanguages", languages.get());
+    }
+
     xpc_connection_set_bootstrap(connection.get(), initializationMessage.get());
 #endif
 
index b4d0f59..d00c85a 100644 (file)
@@ -129,8 +129,21 @@ WebProcessProxy::~WebProcessProxy()
 void WebProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions)
 {
     launchOptions.processType = ProcessLauncher::WebProcess;
+
     if (WebInspectorProxy::isInspectorProcessPool(m_processPool))
         launchOptions.extraInitializationData.add(ASCIILiteral("inspector-process"), ASCIILiteral("1"));
+
+    auto overrideLanguages = m_processPool->configuration().overrideLanguages();
+    if (overrideLanguages.size()) {
+        StringBuilder languageString;
+        for (size_t i = 0; i < overrideLanguages.size(); ++i) {
+            if (i)
+                languageString.append(',');
+            languageString.append(overrideLanguages[i]);
+        }
+        launchOptions.extraInitializationData.add(ASCIILiteral("OverrideLanguages"), languageString.toString());
+    }
+
     platformGetLaunchOptions(launchOptions);
 }
 
index d89660d..995ec42 100644 (file)
@@ -1,5 +1,30 @@
 2015-09-12  Myles C. Maxfield  <mmaxfield@apple.com>
 
+        [Cocoa] Allow testing with the system language
+        https://bugs.webkit.org/show_bug.cgi?id=148671
+
+        Reviewed by Anders Carlsson and Alexey Proskuryakov.
+
+        React to tests marked with language=lang1,lang2,etc in their header.
+        Once this information is parsed, pass it to
+        WKContextConfigurationSetOverrideLanguages().
+
+        * WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm:
+        (WTR::InjectedBundle::platformInitialize): Don't clobber the language
+        list.
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::createWebViewWithOptions): Call
+        WKContextConfigurationSetOverrideLanguages().
+        (WTR::updateTestOptionsFromTestHeader): Inspect the language option.
+        * WebKitTestRunner/TestOptions.h:
+        * WebKitTestRunner/ios/PlatformWebViewIOS.mm:
+        (WTR::PlatformWebView::viewSupportsOptions): Cause a differing language
+        option to restart the web process.
+        * WebKitTestRunner/mac/PlatformWebViewMac.mm:
+        (WTR::PlatformWebView::viewSupportsOptions): Ditto.
+
+2015-09-12  Myles C. Maxfield  <mmaxfield@apple.com>
+
         [WKTR] Allow changing the WKContextConfiguration between successive tests
         https://bugs.webkit.org/show_bug.cgi?id=148833
 
index ffe7112..c3b4a69 100644 (file)
@@ -42,6 +42,11 @@ void InjectedBundle::platformInitialize(WKTypeRef)
     static const int NoFontSmoothing = 0;
     static const int BlueTintedAppearance = 1;
 
+    // Language was set up earlier in main(). Don't clobber it.
+    NSArray *languages = [[[NSUserDefaults standardUserDefaults] volatileDomainForName:NSArgumentDomain] valueForKey:@"AppleLanguages"];
+    if (!languages)
+        languages = @[ @"en" ];
+
     NSDictionary *dict = @{
         @"AppleAntiAliasingThreshold": @4,
         // FIXME: Setting AppleFontSmoothing is likely unnecessary and ineffective. WebKit2 has its own preference for font smoothing, which is
@@ -56,7 +61,7 @@ void InjectedBundle::platformInitialize(WKTypeRef)
         @"NSButtonAnimationsEnabled": @NO, // Ideally, we should find a way to test animations, but for now, make sure that the dumped snapshot matches actual state.
         // FIXME (<rdar://problem/13396515>): It is too late to set AppleLanguages here, as loaded frameworks localizations cannot be changed.
         // This breaks some accessibility tests on machines with non-English user language.
-        @"AppleLanguages": @[ @"en" ],
+        @"AppleLanguages": languages,
         @"NSPreferredSpellServerLanguage": @"en_US",
         @"NSUserDictionaryReplacementItems": @[],
         @"NSTestCorrectionDictionary": @{
index bec727f..ccd34f0 100644 (file)
@@ -463,7 +463,12 @@ WKRetainPtr<WKPageConfigurationRef> TestController::generatePageConfiguration(WK
 void TestController::createWebViewWithOptions(const TestOptions& options)
 {
     auto contextConfiguration = generateContextConfiguration();
-    // Modify contextConfiguration here.
+
+    WKRetainPtr<WKMutableArrayRef> overrideLanguages = adoptWK(WKMutableArrayCreate());
+    for (auto& language : options.overrideLanguages)
+        WKArrayAppendItem(overrideLanguages.get(), adoptWK(WKStringCreateWithUTF8CString(language.utf8().data())).get());
+    WKContextConfigurationSetOverrideLanguages(contextConfiguration.get(), overrideLanguages.get());
+
     auto configuration = generatePageConfiguration(contextConfiguration.get());
 
     // Some preferences (notably mock scroll bars setting) currently cannot be re-applied to an existing view, so we need to set them now.
@@ -856,7 +861,8 @@ static void updateTestOptionsFromTestHeader(TestOptions& testOptions, const Test
         }
         auto key = pairString.substr(pairStart, equalsLocation - pairStart);
         auto value = pairString.substr(equalsLocation + 1, pairEnd - (equalsLocation + 1));
-        // Options processing to modify testOptions goes here.
+        if (key == "language")
+            String(value.c_str()).split(",", false, testOptions.overrideLanguages);
         pairStart = pairEnd + 1;
     }
 }
index eb801ce..f1137cb 100644 (file)
@@ -26,6 +26,9 @@
 #ifndef TestOptions_h
 #define TestOptions_h
 
+#include <wtf/Vector.h>
+#include <wtf/text/WTFString.h>
+
 namespace WTR {
 
 struct TestOptions {
@@ -34,6 +37,7 @@ struct TestOptions {
     bool shouldShowWebView { false };
 
     bool useFixedLayout { false };
+    Vector<String> overrideLanguages;
 };
 
 }
index 6a1f47a..ecb0cd3 100644 (file)
@@ -204,6 +204,9 @@ WKRetainPtr<WKImageRef> PlatformWebView::windowSnapshotImage()
 
 bool PlatformWebView::viewSupportsOptions(const TestOptions& options) const
 {
+    if (m_options.overrideLanguages != options.overrideLanguages)
+        return false;
+
     return true;
 }
 
index e974dda..0e40bb1 100644 (file)
@@ -242,7 +242,7 @@ WKRetainPtr<WKImageRef> PlatformWebView::windowSnapshotImage()
 
 bool PlatformWebView::viewSupportsOptions(const TestOptions& options) const
 {
-    if (m_options.useThreadedScrolling != options.useThreadedScrolling)
+    if (m_options.useThreadedScrolling != options.useThreadedScrolling || m_options.overrideLanguages != options.overrideLanguages)
         return false;
 
     return true;