| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "base/message_loop/message_loop.h" | 5 #include "base/message_loop/message_loop.h" |
| 6 #include "base/prefs/pref_service.h" | 6 #include "base/prefs/pref_service.h" |
| 7 #include "base/strings/stringprintf.h" | 7 #include "base/strings/stringprintf.h" |
| 8 #include "base/task_runner.h" | 8 #include "base/task_runner.h" |
| 9 #include "chrome/browser/browser_process.h" | 9 #include "chrome/browser/browser_process.h" |
| 10 #include "chrome/browser/chrome_notification_types.h" | 10 #include "chrome/browser/chrome_notification_types.h" |
| 11 #include "chrome/browser/chromeos/customization_document.h" | 11 #include "chrome/browser/chromeos/customization_document.h" |
| 12 #include "chrome/browser/chromeos/input_method/input_method_util.h" | 12 #include "chrome/browser/chromeos/input_method/input_method_util.h" |
| 13 #include "chrome/browser/chromeos/login/login_manager_test.h" |
| 13 #include "chrome/browser/chromeos/login/login_wizard.h" | 14 #include "chrome/browser/chromeos/login/login_wizard.h" |
| 14 #include "chrome/browser/chromeos/login/test/js_checker.h" | 15 #include "chrome/browser/chromeos/login/test/js_checker.h" |
| 15 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" | 16 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" |
| 16 #include "chrome/common/pref_names.h" | 17 #include "chrome/common/pref_names.h" |
| 17 #include "chrome/test/base/in_process_browser_test.h" | 18 #include "chrome/test/base/in_process_browser_test.h" |
| 18 #include "chromeos/ime/extension_ime_util.h" | 19 #include "chromeos/ime/extension_ime_util.h" |
| 19 #include "chromeos/ime/input_method_manager.h" | 20 #include "chromeos/ime/input_method_manager.h" |
| 20 #include "chromeos/ime/input_method_whitelist.h" | 21 #include "chromeos/ime/input_method_whitelist.h" |
| 21 #include "chromeos/system/statistics_provider.h" | 22 #include "chromeos/system/statistics_provider.h" |
| 22 #include "content/public/browser/notification_service.h" | 23 #include "content/public/browser/notification_service.h" |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 | 83 |
| 83 virtual void Shutdown() override { | 84 virtual void Shutdown() override { |
| 84 } | 85 } |
| 85 | 86 |
| 86 std::string initial_locale_; | 87 std::string initial_locale_; |
| 87 std::string keyboard_layout_; | 88 std::string keyboard_layout_; |
| 88 }; | 89 }; |
| 89 | 90 |
| 90 } // namespace system | 91 } // namespace system |
| 91 | 92 |
| 92 class OobeLocalizationTest : public InProcessBrowserTest { | 93 struct LocalizationTestParams { |
| 94 const char* initial_locale; |
| 95 const char* keyboard_layout; |
| 96 const char* expected_locale; |
| 97 const char* expected_keyboard_layout; |
| 98 const char* expected_keyboard_select_control; |
| 99 } const oobe_localization_test_parameters[] = { |
| 100 // ------------------ Non-Latin setup |
| 101 // For a non-Latin keyboard layout like Russian, we expect to see the US |
| 102 // keyboard. |
| 103 {"ru", "xkb:ru::rus", "ru", kUSLayout, "xkb:us::eng"}, |
| 104 {"ru", "xkb:us::eng,xkb:ru::rus", "ru", kUSLayout, "xkb:us::eng"}, |
| 105 |
| 106 // IMEs do not load at OOBE, so we just expect to see the (Latin) Japanese |
| 107 // keyboard. |
| 108 {"ja", "xkb:jp::jpn", "ja", "xkb:jp::jpn", "xkb:jp::jpn,[xkb:us::eng]"}, |
| 109 |
| 110 // We don't use the Icelandic locale but the Icelandic keyboard layout |
| 111 // should still be selected when specified as the default. |
| 112 {"en-US", |
| 113 "xkb:is::ice", |
| 114 "en-US", |
| 115 "xkb:is::ice", |
| 116 "xkb:is::ice,[xkb:us::eng,xkb:us:intl:eng,xkb:us:altgr-intl:eng," |
| 117 "xkb:us:dvorak:eng,xkb:us:colemak:eng]"}, |
| 118 // ------------------ Full Latin setup |
| 119 // French Swiss keyboard. |
| 120 {"fr", |
| 121 "xkb:ch:fr:fra", |
| 122 "fr", |
| 123 "xkb:ch:fr:fra", |
| 124 "xkb:ch:fr:fra,[xkb:fr::fra,xkb:be::fra,xkb:ca::fra," |
| 125 "xkb:ca:multix:fra,xkb:us::eng]"}, |
| 126 |
| 127 // German Swiss keyboard. |
| 128 {"de", |
| 129 "xkb:ch::ger", |
| 130 "de", |
| 131 "xkb:ch::ger", |
| 132 "xkb:ch::ger,[xkb:de::ger,xkb:de:neo:ger,xkb:be::ger,xkb:us::eng]"}, |
| 133 |
| 134 // NetworkScreenMultipleLocales |
| 135 {"es,en-US,nl", |
| 136 "xkb:be::nld", |
| 137 "es,en-US,nl", |
| 138 "xkb:be::nld", |
| 139 "xkb:be::nld,[xkb:es::spa,xkb:latam::spa,xkb:us::eng]"}, |
| 140 |
| 141 {"ru,de", "xkb:ru::rus", "ru,de", kUSLayout, "xkb:us::eng"}, |
| 142 |
| 143 // ------------------ Regional Locales |
| 144 // Syntetic example to test correct merging of different locales. |
| 145 {"fr-CH,it-CH,de-CH", |
| 146 "xkb:fr::fra,xkb:it::ita,xkb:de::ger", |
| 147 "fr-CH,it-CH,de-CH", |
| 148 "xkb:fr::fra", |
| 149 "xkb:fr::fra,xkb:it::ita,xkb:de::ger,[xkb:be::fra,xkb:ca::fra," |
| 150 "xkb:ch:fr:fra,xkb:ca:multix:fra,xkb:us::eng]"}, |
| 151 |
| 152 // Another syntetic example. Check that british keyboard is available. |
| 153 {"en-AU", |
| 154 "xkb:us::eng", |
| 155 "en-AU", |
| 156 "xkb:us::eng", |
| 157 "xkb:us::eng,[xkb:gb:extd:eng,xkb:gb:dvorak:eng]"}, |
| 158 }; |
| 159 |
| 160 class OobeLocalizationTest |
| 161 : public LoginManagerTest, |
| 162 public testing::WithParamInterface<const LocalizationTestParams*> { |
| 93 public: | 163 public: |
| 94 OobeLocalizationTest(); | 164 OobeLocalizationTest(); |
| 95 virtual ~OobeLocalizationTest(); | 165 virtual ~OobeLocalizationTest(); |
| 96 | 166 |
| 97 // Verifies that the comma-separated |values| corresponds with the first | 167 // Verifies that the comma-separated |values| corresponds with the first |
| 98 // values in |select_id|, optionally checking for an options group label after | 168 // values in |select_id|, optionally checking for an options group label after |
| 99 // the first set of options. | 169 // the first set of options. |
| 100 bool VerifyInitialOptions(const char* select_id, | 170 bool VerifyInitialOptions(const char* select_id, |
| 101 const char* values, | 171 const char* values, |
| 102 bool check_separator); | 172 bool check_separator); |
| 103 | 173 |
| 104 // Verifies that |value| exists in |select_id|. | 174 // Verifies that |value| exists in |select_id|. |
| 105 bool VerifyOptionExists(const char* select_id, const char* value); | 175 bool VerifyOptionExists(const char* select_id, const char* value); |
| 106 | 176 |
| 107 // Dumps OOBE select control (language or keyboard) to string. | 177 // Dumps OOBE select control (language or keyboard) to string. |
| 108 std::string DumpOptions(const char* select_id); | 178 std::string DumpOptions(const char* select_id); |
| 109 | 179 |
| 110 protected: | 180 protected: |
| 111 // Runs the test for the given locale and keyboard layout. | 181 // Runs the test for the given locale and keyboard layout. |
| 112 void RunLocalizationTest(const std::string& initial_locale, | 182 void RunLocalizationTest(); |
| 113 const std::string& keyboard_layout, | 183 |
| 114 const std::string& expected_locale, | 184 void WaitUntilJSIsReady() { |
| 115 const std::string& expected_keyboard_layout, | 185 LoginDisplayHostImpl* host = static_cast<LoginDisplayHostImpl*>( |
| 116 const std::string& expected_keyboard_select_control); | 186 LoginDisplayHostImpl::default_host()); |
| 187 if (!host) |
| 188 return; |
| 189 chromeos::OobeUI* oobe_ui = host->GetOobeUI(); |
| 190 if (!oobe_ui) |
| 191 return; |
| 192 base::RunLoop run_loop; |
| 193 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); |
| 194 if (!oobe_ui_ready) |
| 195 run_loop.Run(); |
| 196 } |
| 117 | 197 |
| 118 private: | 198 private: |
| 119 scoped_ptr<system::FakeStatisticsProvider> statistics_provider_; | 199 scoped_ptr<system::FakeStatisticsProvider> statistics_provider_; |
| 120 test::JSChecker checker; | 200 test::JSChecker checker; |
| 121 | 201 |
| 122 DISALLOW_COPY_AND_ASSIGN(OobeLocalizationTest); | 202 DISALLOW_COPY_AND_ASSIGN(OobeLocalizationTest); |
| 123 }; | 203 }; |
| 124 | 204 |
| 125 OobeLocalizationTest::OobeLocalizationTest() { | 205 OobeLocalizationTest::OobeLocalizationTest() : LoginManagerTest(false) { |
| 126 statistics_provider_.reset(new system::FakeStatisticsProvider()); | 206 statistics_provider_.reset(new system::FakeStatisticsProvider()); |
| 127 // Set the instance returned by GetInstance() for testing. | 207 // Set the instance returned by GetInstance() for testing. |
| 128 system::StatisticsProvider::SetTestProvider(statistics_provider_.get()); | 208 system::StatisticsProvider::SetTestProvider(statistics_provider_.get()); |
| 209 |
| 210 statistics_provider_->set_locale(GetParam()->initial_locale); |
| 211 statistics_provider_->set_keyboard_layout(GetParam()->keyboard_layout); |
| 129 } | 212 } |
| 130 | 213 |
| 131 OobeLocalizationTest::~OobeLocalizationTest() { | 214 OobeLocalizationTest::~OobeLocalizationTest() { |
| 132 system::StatisticsProvider::SetTestProvider(NULL); | 215 system::StatisticsProvider::SetTestProvider(NULL); |
| 133 } | 216 } |
| 134 | 217 |
| 135 bool OobeLocalizationTest::VerifyInitialOptions(const char* select_id, | 218 bool OobeLocalizationTest::VerifyInitialOptions(const char* select_id, |
| 136 const char* values, | 219 const char* values, |
| 137 bool check_separator) { | 220 bool check_separator) { |
| 138 const std::string expression = base::StringPrintf( | 221 const std::string expression = base::StringPrintf( |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 229 std::string repl_old = "xkb:"; | 312 std::string repl_old = "xkb:"; |
| 230 std::string repl_new = | 313 std::string repl_new = |
| 231 extension_ime_util::GetInputMethodIDByEngineID("xkb:"); | 314 extension_ime_util::GetInputMethodIDByEngineID("xkb:"); |
| 232 while ((pos = result.find(repl_old, pos)) != std::string::npos) { | 315 while ((pos = result.find(repl_old, pos)) != std::string::npos) { |
| 233 result.replace(pos, repl_old.length(), repl_new); | 316 result.replace(pos, repl_old.length(), repl_new); |
| 234 pos += repl_new.length(); | 317 pos += repl_new.length(); |
| 235 } | 318 } |
| 236 return result; | 319 return result; |
| 237 } | 320 } |
| 238 | 321 |
| 239 void OobeLocalizationTest::RunLocalizationTest( | 322 void OobeLocalizationTest::RunLocalizationTest() { |
| 240 const std::string& initial_locale, | 323 const std::string initial_locale(GetParam()->initial_locale); |
| 241 const std::string& keyboard_layout, | 324 const std::string keyboard_layout(GetParam()->keyboard_layout); |
| 242 const std::string& expected_locale, | 325 const std::string expected_locale(GetParam()->expected_locale); |
| 243 const std::string& expected_keyboard_layout, | 326 const std::string expected_keyboard_layout( |
| 244 const std::string& expected_keyboard_select_control) { | 327 GetParam()->expected_keyboard_layout); |
| 245 statistics_provider_->set_locale(initial_locale); | 328 const std::string expected_keyboard_select_control( |
| 246 statistics_provider_->set_keyboard_layout(keyboard_layout); | 329 GetParam()->expected_keyboard_select_control); |
| 247 | |
| 248 // Initialize StartupCustomizationDocument with fake statistics provider. | |
| 249 StartupCustomizationDocument::GetInstance()->Init( | |
| 250 statistics_provider_.get()); | |
| 251 | |
| 252 g_browser_process->local_state()->SetString( | |
| 253 prefs::kHardwareKeyboardLayout, keyboard_layout); | |
| 254 | |
| 255 input_method::InputMethodManager::Get() | |
| 256 ->GetInputMethodUtil() | |
| 257 ->InitXkbInputMethodsForTesting(); | |
| 258 | 330 |
| 259 const std::string expected_keyboard_select = | 331 const std::string expected_keyboard_select = |
| 260 TranslateXKB2Extension(expected_keyboard_select_control); | 332 TranslateXKB2Extension(expected_keyboard_select_control); |
| 261 | 333 |
| 262 // Bring up the OOBE network screen. | 334 WaitUntilJSIsReady(); |
| 263 chromeos::ShowLoginWizard(chromeos::WizardController::kNetworkScreenName); | 335 |
| 264 content::WindowedNotificationObserver( | 336 const std::string first_language = |
| 265 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, | 337 expected_locale.substr(0, expected_locale.find(',')); |
| 266 content::NotificationService::AllSources()).Wait(); | 338 bool done = false; |
| 339 const std::string waiting_script = base::StringPrintf( |
| 340 "var screenElement = document.getElementById('language-select');" |
| 341 "function SendReplyIfAcceptEnabled() {" |
| 342 " if ($('language-select').value != '%s')" |
| 343 " return false;" |
| 344 " domAutomationController.send(true);" |
| 345 " observer.disconnect();" |
| 346 " return true;" |
| 347 "}" |
| 348 "var observer = new MutationObserver(SendReplyIfAcceptEnabled);" |
| 349 "if (!SendReplyIfAcceptEnabled()) {" |
| 350 " var options = { attributes: true };" |
| 351 " observer.observe(screenElement, options);" |
| 352 "}", |
| 353 first_language.c_str()); |
| 354 |
| 355 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
| 356 static_cast<chromeos::LoginDisplayHostImpl*>( |
| 357 chromeos::LoginDisplayHostImpl::default_host()) |
| 358 ->GetOobeUI() |
| 359 ->web_ui() |
| 360 ->GetWebContents(), |
| 361 waiting_script, |
| 362 &done)); |
| 267 | 363 |
| 268 checker.set_web_contents(static_cast<chromeos::LoginDisplayHostImpl*>( | 364 checker.set_web_contents(static_cast<chromeos::LoginDisplayHostImpl*>( |
| 269 chromeos::LoginDisplayHostImpl::default_host())-> | 365 chromeos::LoginDisplayHostImpl::default_host())-> |
| 270 GetOobeUI()->web_ui()->GetWebContents()); | 366 GetOobeUI()->web_ui()->GetWebContents()); |
| 271 | 367 |
| 272 if (!VerifyInitialOptions(kLocaleSelect, expected_locale.c_str(), true)) { | 368 if (!VerifyInitialOptions(kLocaleSelect, expected_locale.c_str(), true)) { |
| 273 LOG(ERROR) << "Actual value of " << kLocaleSelect << ":\n" | 369 LOG(ERROR) << "Actual value of " << kLocaleSelect << ":\n" |
| 274 << DumpOptions(kLocaleSelect); | 370 << DumpOptions(kLocaleSelect); |
| 275 } | 371 } |
| 276 if (!VerifyInitialOptions( | 372 if (!VerifyInitialOptions( |
| (...skipping 18 matching lines...) Expand all Loading... |
| 295 | 391 |
| 296 // Shut down the display host. | 392 // Shut down the display host. |
| 297 chromeos::LoginDisplayHostImpl::default_host()->Finalize(); | 393 chromeos::LoginDisplayHostImpl::default_host()->Finalize(); |
| 298 base::MessageLoopForUI::current()->RunUntilIdle(); | 394 base::MessageLoopForUI::current()->RunUntilIdle(); |
| 299 | 395 |
| 300 // Clear the locale pref so the statistics provider is pinged next time. | 396 // Clear the locale pref so the statistics provider is pinged next time. |
| 301 g_browser_process->local_state()->SetString(prefs::kApplicationLocale, | 397 g_browser_process->local_state()->SetString(prefs::kApplicationLocale, |
| 302 std::string()); | 398 std::string()); |
| 303 } | 399 } |
| 304 | 400 |
| 305 IN_PROC_BROWSER_TEST_F(OobeLocalizationTest, NetworkScreenNonLatin) { | 401 IN_PROC_BROWSER_TEST_P(OobeLocalizationTest, LocalizationTest) { |
| 306 // For a non-Latin keyboard layout like Russian, we expect to see the US | 402 RunLocalizationTest(); |
| 307 // keyboard. | |
| 308 RunLocalizationTest("ru", "xkb:ru::rus", | |
| 309 "ru", kUSLayout, | |
| 310 "xkb:us::eng"); | |
| 311 | |
| 312 RunLocalizationTest("ru", "xkb:us::eng,xkb:ru::rus", | |
| 313 "ru", kUSLayout, | |
| 314 "xkb:us::eng"); | |
| 315 | |
| 316 // IMEs do not load at OOBE, so we just expect to see the (Latin) Japanese | |
| 317 // keyboard. | |
| 318 RunLocalizationTest("ja", "xkb:jp::jpn", | |
| 319 "ja", "xkb:jp::jpn", | |
| 320 "xkb:jp::jpn,[xkb:us::eng]"); | |
| 321 } | 403 } |
| 322 | 404 |
| 323 IN_PROC_BROWSER_TEST_F(OobeLocalizationTest, NetworkScreenKeyboardLayout) { | 405 INSTANTIATE_TEST_CASE_P( |
| 324 // We don't use the Icelandic locale but the Icelandic keyboard layout | 406 StructSequence, |
| 325 // should still be selected when specified as the default. | 407 OobeLocalizationTest, |
| 326 RunLocalizationTest("en-US", "xkb:is::ice", | 408 testing::Range(&oobe_localization_test_parameters[0], |
| 327 "en-US", "xkb:is::ice", | 409 &oobe_localization_test_parameters[arraysize( |
| 328 "xkb:is::ice,[" | 410 oobe_localization_test_parameters)])); |
| 329 "xkb:us::eng,xkb:us:intl:eng,xkb:us:altgr-intl:eng," | |
| 330 "xkb:us:dvorak:eng,xkb:us:colemak:eng]"); | |
| 331 } | |
| 332 | |
| 333 IN_PROC_BROWSER_TEST_F(OobeLocalizationTest, NetworkScreenFullLatin) { | |
| 334 // French Swiss keyboard. | |
| 335 RunLocalizationTest("fr", "xkb:ch:fr:fra", | |
| 336 "fr", "xkb:ch:fr:fra", | |
| 337 "xkb:ch:fr:fra,[" | |
| 338 "xkb:fr::fra,xkb:be::fra,xkb:ca::fra," | |
| 339 "xkb:ca:multix:fra,xkb:us::eng]"); | |
| 340 | |
| 341 // German Swiss keyboard. | |
| 342 RunLocalizationTest("de", "xkb:ch::ger", | |
| 343 "de", "xkb:ch::ger", | |
| 344 "xkb:ch::ger,[" | |
| 345 "xkb:de::ger,xkb:de:neo:ger,xkb:be::ger,xkb:us::eng" | |
| 346 "]"); | |
| 347 } | |
| 348 | |
| 349 IN_PROC_BROWSER_TEST_F(OobeLocalizationTest, NetworkScreenMultipleLocales) { | |
| 350 RunLocalizationTest("es,en-US,nl", "xkb:be::nld", | |
| 351 "es,en-US,nl", "xkb:be::nld", | |
| 352 "xkb:be::nld,[xkb:es::spa,xkb:latam::spa,xkb:us::eng]"); | |
| 353 | |
| 354 RunLocalizationTest("ru,de", "xkb:ru::rus", | |
| 355 "ru,de", kUSLayout, | |
| 356 "xkb:us::eng"); | |
| 357 } | |
| 358 | |
| 359 IN_PROC_BROWSER_TEST_F(OobeLocalizationTest, NetworkScreenRegionalLocales) { | |
| 360 // Syntetic example to test correct merging of different locales. | |
| 361 RunLocalizationTest("fr-CH,it-CH,de-CH", | |
| 362 "xkb:fr::fra,xkb:it::ita,xkb:de::ger", | |
| 363 "fr-CH,it-CH,de-CH", | |
| 364 "xkb:fr::fra", | |
| 365 "xkb:fr::fra,xkb:it::ita,xkb:de::ger,[" | |
| 366 "xkb:be::fra,xkb:ca::fra,xkb:ch:fr:fra," | |
| 367 "xkb:ca:multix:fra,xkb:us::eng" | |
| 368 "]"); | |
| 369 // Another syntetic example. Check that british keyboard is available. | |
| 370 RunLocalizationTest("en-AU", | |
| 371 "xkb:us::eng", | |
| 372 "en-AU", | |
| 373 "xkb:us::eng", | |
| 374 "xkb:us::eng,[xkb:gb:extd:eng,xkb:gb:dvorak:eng]"); | |
| 375 } | |
| 376 | |
| 377 } // namespace chromeos | 411 } // namespace chromeos |
| OLD | NEW |