OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 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 <map> | 5 #include <map> |
6 #include <set> | |
7 #include <string> | 6 #include <string> |
8 #include <vector> | |
9 | 7 |
10 #include "apps/app_window_registry.h" | 8 #include "apps/app_window_registry.h" |
11 #include "apps/ui/native_app_window.h" | 9 #include "apps/ui/native_app_window.h" |
12 #include "ash/shell.h" | 10 #include "ash/shell.h" |
13 #include "ash/system/chromeos/session/logout_confirmation_controller.h" | 11 #include "ash/system/chromeos/session/logout_confirmation_controller.h" |
14 #include "ash/system/chromeos/session/logout_confirmation_dialog.h" | 12 #include "ash/system/chromeos/session/logout_confirmation_dialog.h" |
15 #include "base/basictypes.h" | 13 #include "base/basictypes.h" |
16 #include "base/bind.h" | 14 #include "base/bind.h" |
17 #include "base/bind_helpers.h" | 15 #include "base/bind_helpers.h" |
18 #include "base/callback.h" | 16 #include "base/callback.h" |
(...skipping 10 matching lines...) Expand all Loading... |
29 #include "base/message_loop/message_loop_proxy.h" | 27 #include "base/message_loop/message_loop_proxy.h" |
30 #include "base/path_service.h" | 28 #include "base/path_service.h" |
31 #include "base/prefs/pref_change_registrar.h" | 29 #include "base/prefs/pref_change_registrar.h" |
32 #include "base/prefs/pref_service.h" | 30 #include "base/prefs/pref_service.h" |
33 #include "base/run_loop.h" | 31 #include "base/run_loop.h" |
34 #include "base/sequenced_task_runner.h" | 32 #include "base/sequenced_task_runner.h" |
35 #include "base/strings/string_number_conversions.h" | 33 #include "base/strings/string_number_conversions.h" |
36 #include "base/strings/string_util.h" | 34 #include "base/strings/string_util.h" |
37 #include "base/strings/stringprintf.h" | 35 #include "base/strings/stringprintf.h" |
38 #include "base/strings/utf_string_conversions.h" | 36 #include "base/strings/utf_string_conversions.h" |
39 #include "base/threading/sequenced_worker_pool.h" | |
40 #include "base/values.h" | 37 #include "base/values.h" |
41 #include "chrome/browser/browser_process.h" | 38 #include "chrome/browser/browser_process.h" |
42 #include "chrome/browser/chrome_notification_types.h" | 39 #include "chrome/browser/chrome_notification_types.h" |
43 #include "chrome/browser/chromeos/extensions/device_local_account_external_polic
y_loader.h" | 40 #include "chrome/browser/chromeos/extensions/device_local_account_external_polic
y_loader.h" |
44 #include "chrome/browser/chromeos/extensions/external_cache.h" | 41 #include "chrome/browser/chromeos/extensions/external_cache.h" |
45 #include "chrome/browser/chromeos/input_method/input_method_util.h" | |
46 #include "chrome/browser/chromeos/login/existing_user_controller.h" | 42 #include "chrome/browser/chromeos/login/existing_user_controller.h" |
47 #include "chrome/browser/chromeos/login/screens/wizard_screen.h" | 43 #include "chrome/browser/chromeos/login/screens/wizard_screen.h" |
48 #include "chrome/browser/chromeos/login/ui/login_display_host.h" | 44 #include "chrome/browser/chromeos/login/ui/login_display_host.h" |
49 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" | 45 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" |
50 #include "chrome/browser/chromeos/login/ui/webui_login_view.h" | 46 #include "chrome/browser/chromeos/login/ui/webui_login_view.h" |
51 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager.h" | 47 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager.h" |
52 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h" | 48 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h" |
53 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_test_uti
l.h" | 49 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_test_uti
l.h" |
54 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" | 50 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h" |
55 #include "chrome/browser/chromeos/login/users/user_manager.h" | 51 #include "chrome/browser/chromeos/login/users/user_manager.h" |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 #include "components/policy/core/common/cloud/cloud_policy_store.h" | 92 #include "components/policy/core/common/cloud/cloud_policy_store.h" |
97 #include "components/policy/core/common/cloud/policy_builder.h" | 93 #include "components/policy/core/common/cloud/policy_builder.h" |
98 #include "components/policy/core/common/external_data_fetcher.h" | 94 #include "components/policy/core/common/external_data_fetcher.h" |
99 #include "components/policy/core/common/policy_map.h" | 95 #include "components/policy/core/common/policy_map.h" |
100 #include "components/policy/core/common/policy_namespace.h" | 96 #include "components/policy/core/common/policy_namespace.h" |
101 #include "components/policy/core/common/policy_service.h" | 97 #include "components/policy/core/common/policy_service.h" |
102 #include "components/policy/core/common/policy_switches.h" | 98 #include "components/policy/core/common/policy_switches.h" |
103 #include "components/signin/core/common/signin_pref_names.h" | 99 #include "components/signin/core/common/signin_pref_names.h" |
104 #include "components/user_manager/user.h" | 100 #include "components/user_manager/user.h" |
105 #include "components/user_manager/user_type.h" | 101 #include "components/user_manager/user_type.h" |
106 #include "content/public/browser/browser_thread.h" | |
107 #include "content/public/browser/notification_details.h" | 102 #include "content/public/browser/notification_details.h" |
108 #include "content/public/browser/notification_service.h" | 103 #include "content/public/browser/notification_service.h" |
109 #include "content/public/browser/notification_source.h" | 104 #include "content/public/browser/notification_source.h" |
110 #include "content/public/browser/web_contents.h" | 105 #include "content/public/browser/web_contents.h" |
111 #include "content/public/browser/web_ui.h" | 106 #include "content/public/browser/web_ui.h" |
112 #include "content/public/test/browser_test_utils.h" | 107 #include "content/public/test/browser_test_utils.h" |
113 #include "content/public/test/test_utils.h" | 108 #include "content/public/test/test_utils.h" |
114 #include "crypto/rsa_private_key.h" | 109 #include "crypto/rsa_private_key.h" |
115 #include "extensions/browser/extension_system.h" | 110 #include "extensions/browser/extension_system.h" |
116 #include "extensions/browser/management_policy.h" | 111 #include "extensions/browser/management_policy.h" |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
171 const char kHostedAppCRXPath[] = "extensions/hosted_app.crx"; | 166 const char kHostedAppCRXPath[] = "extensions/hosted_app.crx"; |
172 const char kHostedAppVersion[] = "1.0.0.0"; | 167 const char kHostedAppVersion[] = "1.0.0.0"; |
173 const char kGoodExtensionID[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; | 168 const char kGoodExtensionID[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; |
174 const char kGoodExtensionCRXPath[] = "extensions/good.crx"; | 169 const char kGoodExtensionCRXPath[] = "extensions/good.crx"; |
175 const char kGoodExtensionVersion[] = "1.0"; | 170 const char kGoodExtensionVersion[] = "1.0"; |
176 const char kPackagedAppCRXPath[] = "extensions/platform_apps/app_window_2.crx"; | 171 const char kPackagedAppCRXPath[] = "extensions/platform_apps/app_window_2.crx"; |
177 | 172 |
178 const char kExternalData[] = "External data"; | 173 const char kExternalData[] = "External data"; |
179 const char kExternalDataURL[] = "http://localhost/external_data"; | 174 const char kExternalDataURL[] = "http://localhost/external_data"; |
180 | 175 |
181 const char* kSingleRecommendedLocale[] = { | |
182 "el", | |
183 }; | |
184 const char* kRecommendedLocales1[] = { | |
185 "pl", | |
186 "et", | |
187 "en-US", | |
188 }; | |
189 const char* kRecommendedLocales2[] = { | |
190 "fr", | |
191 "nl", | |
192 }; | |
193 const char kPublicSessionLocale[] = "de"; | 176 const char kPublicSessionLocale[] = "de"; |
194 const char kPublicSessionInputMethodIDTemplate[] = "_comp_ime_%sxkb:de:neo:ger"; | 177 const char kPublicSessionInputMethodIDTemplate[] = "_comp_ime_%sxkb:de:neo:ger"; |
195 | 178 |
196 // The sequence token used by GetKeyboardLayoutsForLocale() for its background | |
197 // tasks. | |
198 const char kSequenceToken[] = "chromeos_login_l10n_util"; | |
199 | |
200 // Helper that serves extension update manifests to Chrome. | 179 // Helper that serves extension update manifests to Chrome. |
201 class TestingUpdateManifestProvider { | 180 class TestingUpdateManifestProvider { |
202 public: | 181 public: |
203 // Update manifests will be served at |relative_update_url|. | 182 // Update manifests will be served at |relative_update_url|. |
204 explicit TestingUpdateManifestProvider( | 183 explicit TestingUpdateManifestProvider( |
205 const std::string& relative_update_url); | 184 const std::string& relative_update_url); |
206 ~TestingUpdateManifestProvider(); | 185 ~TestingUpdateManifestProvider(); |
207 | 186 |
208 // When an update manifest is requested for the given extension |id|, indicate | 187 // When an update manifest is requested for the given extension |id|, indicate |
209 // that |version| of the extension can be downloaded at |crx_url|. | 188 // that |version| of the extension can be downloaded at |crx_url|. |
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 net::URLRequestStatus::Status status) { | 349 net::URLRequestStatus::Status status) { |
371 task_runner->PostTask(FROM_HERE, callback); | 350 task_runner->PostTask(FROM_HERE, callback); |
372 return make_scoped_ptr(new net::FakeURLFetcher( | 351 return make_scoped_ptr(new net::FakeURLFetcher( |
373 url, delegate, response_data, response_code, status)); | 352 url, delegate, response_data, response_code, status)); |
374 } | 353 } |
375 | 354 |
376 bool IsSessionStarted() { | 355 bool IsSessionStarted() { |
377 return chromeos::UserManager::Get()->IsSessionStarted(); | 356 return chromeos::UserManager::Get()->IsSessionStarted(); |
378 } | 357 } |
379 | 358 |
380 // GetKeyboardLayoutsForLocale() posts a task to a background task runner. This | |
381 // method flushes that task runner and the current thread's message loop to | |
382 // ensure that GetKeyboardLayoutsForLocale() is finished. | |
383 void WaitForGetKeyboardLayoutsForLocaleToFinish() { | |
384 base::SequencedWorkerPool* worker_pool = | |
385 content::BrowserThread::GetBlockingPool(); | |
386 scoped_refptr<base::SequencedTaskRunner> background_task_runner = | |
387 worker_pool->GetSequencedTaskRunner( | |
388 worker_pool->GetNamedSequenceToken(kSequenceToken)); | |
389 base::RunLoop run_loop; | |
390 background_task_runner->PostTaskAndReply(FROM_HERE, | |
391 base::Bind(&base::DoNothing), | |
392 run_loop.QuitClosure()); | |
393 run_loop.Run(); | |
394 base::RunLoop().RunUntilIdle(); | |
395 } | |
396 | |
397 } // namespace | 359 } // namespace |
398 | 360 |
399 class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, | 361 class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest, |
400 public chromeos::UserManager::Observer, | 362 public chromeos::UserManager::Observer, |
401 public chrome::BrowserListObserver, | 363 public chrome::BrowserListObserver, |
402 public apps::AppWindowRegistry::Observer { | 364 public apps::AppWindowRegistry::Observer { |
403 protected: | 365 protected: |
404 DeviceLocalAccountTest() | 366 DeviceLocalAccountTest() |
405 : user_id_1_(GenerateDeviceLocalAccountUserId( | 367 : user_id_1_(GenerateDeviceLocalAccountUserId( |
406 kAccountId1, DeviceLocalAccount::TYPE_PUBLIC_SESSION)), | 368 kAccountId1, DeviceLocalAccount::TYPE_PUBLIC_SESSION)), |
407 user_id_2_(GenerateDeviceLocalAccountUserId( | 369 user_id_2_(GenerateDeviceLocalAccountUserId( |
408 kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)), | 370 kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)), |
409 public_session_input_method_id_(base::StringPrintf( | 371 public_session_input_method_id_(base::StringPrintf( |
410 kPublicSessionInputMethodIDTemplate, | 372 kPublicSessionInputMethodIDTemplate, |
411 chromeos::extension_ime_util::kXkbExtensionId)), | 373 chromeos::extension_ime_util::kXkbExtensionId)) { |
412 contents_(NULL) { | |
413 set_exit_when_last_browser_closes(false); | 374 set_exit_when_last_browser_closes(false); |
414 } | 375 } |
415 | 376 |
416 virtual ~DeviceLocalAccountTest() {} | 377 virtual ~DeviceLocalAccountTest() {} |
417 | 378 |
418 virtual void SetUp() OVERRIDE { | 379 virtual void SetUp() OVERRIDE { |
419 // Configure and start the test server. | 380 // Configure and start the test server. |
420 scoped_ptr<crypto::RSAPrivateKey> signing_key( | 381 scoped_ptr<crypto::RSAPrivateKey> signing_key( |
421 PolicyBuilder::CreateTestSigningKey()); | 382 PolicyBuilder::CreateTestSigningKey()); |
422 ASSERT_TRUE(test_server_.SetSigningKeyAndSignature( | 383 ASSERT_TRUE(test_server_.SetSigningKeyAndSignature( |
(...skipping 27 matching lines...) Expand all Loading... |
450 argv.erase(argv.begin() + argv.size() - command_line->GetArgs().size(), | 411 argv.erase(argv.begin() + argv.size() - command_line->GetArgs().size(), |
451 argv.end()); | 412 argv.end()); |
452 command_line->InitFromArgv(argv); | 413 command_line->InitFromArgv(argv); |
453 | 414 |
454 InstallOwnerKey(); | 415 InstallOwnerKey(); |
455 MarkAsEnterpriseOwned(); | 416 MarkAsEnterpriseOwned(); |
456 | 417 |
457 InitializePolicy(); | 418 InitializePolicy(); |
458 } | 419 } |
459 | 420 |
460 virtual void SetUpOnMainThread() OVERRIDE { | |
461 DevicePolicyCrosBrowserTest::SetUpOnMainThread(); | |
462 | |
463 content::WindowedNotificationObserver( | |
464 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, | |
465 content::NotificationService::AllSources()).Wait(); | |
466 | |
467 chromeos::LoginDisplayHostImpl* host = | |
468 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( | |
469 chromeos::LoginDisplayHostImpl::default_host()); | |
470 ASSERT_TRUE(host); | |
471 chromeos::WebUILoginView* web_ui_login_view = host->GetWebUILoginView(); | |
472 ASSERT_TRUE(web_ui_login_view); | |
473 content::WebUI* web_ui = web_ui_login_view->GetWebUI(); | |
474 ASSERT_TRUE(web_ui); | |
475 contents_ = web_ui->GetWebContents(); | |
476 ASSERT_TRUE(contents_); | |
477 | |
478 // Wait for the login UI to be ready. | |
479 chromeos::OobeUI* oobe_ui = host->GetOobeUI(); | |
480 ASSERT_TRUE(oobe_ui); | |
481 base::RunLoop run_loop; | |
482 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); | |
483 if (!oobe_ui_ready) | |
484 run_loop.Run(); | |
485 | |
486 // The network selection screen changes the application locale on load and | |
487 // once again on blur. Wait for the screen to load and blur it so that any | |
488 // locale changes caused by this screen happen now and do not affect any | |
489 // subsequent parts of the test. | |
490 bool done = false; | |
491 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( | |
492 contents_, | |
493 "var languageSelect = document.getElementById('language-select');" | |
494 "var blurAndReportSuccess = function() {" | |
495 " languageSelect.blur();" | |
496 " domAutomationController.send(true);" | |
497 "};" | |
498 "var screenLoading = document.getElementById('outer-container')" | |
499 " .classList.contains('down');" | |
500 "if (document.activeElement == languageSelect || !screenLoading)" | |
501 " blurAndReportSuccess();" | |
502 "else" | |
503 " languageSelect.addEventListener('focus', blurAndReportSuccess);", | |
504 &done)); | |
505 | |
506 // Skip to the login screen. | |
507 chromeos::WizardController* wizard_controller = | |
508 chromeos::WizardController::default_controller(); | |
509 ASSERT_TRUE(wizard_controller); | |
510 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); | |
511 } | |
512 | |
513 virtual void TearDownOnMainThread() OVERRIDE { | 421 virtual void TearDownOnMainThread() OVERRIDE { |
514 BrowserList::RemoveObserver(this); | 422 BrowserList::RemoveObserver(this); |
515 | 423 |
516 // This shuts down the login UI. | 424 // This shuts down the login UI. |
517 base::MessageLoop::current()->PostTask(FROM_HERE, | 425 base::MessageLoop::current()->PostTask(FROM_HERE, |
518 base::Bind(&chrome::AttemptExit)); | 426 base::Bind(&chrome::AttemptExit)); |
519 base::RunLoop().RunUntilIdle(); | 427 base::RunLoop().RunUntilIdle(); |
520 } | 428 } |
521 | 429 |
522 virtual void LocalStateChanged(chromeos::UserManager* user_manager) OVERRIDE { | 430 virtual void LocalStateChanged(chromeos::UserManager* user_manager) OVERRIDE { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
565 dm_protocol::kChromePublicAccountPolicyType, kAccountId1, | 473 dm_protocol::kChromePublicAccountPolicyType, kAccountId1, |
566 device_local_account_policy_.payload().SerializeAsString()); | 474 device_local_account_policy_.payload().SerializeAsString()); |
567 } | 475 } |
568 | 476 |
569 void UploadAndInstallDeviceLocalAccountPolicy() { | 477 void UploadAndInstallDeviceLocalAccountPolicy() { |
570 UploadDeviceLocalAccountPolicy(); | 478 UploadDeviceLocalAccountPolicy(); |
571 session_manager_client()->set_device_local_account_policy( | 479 session_manager_client()->set_device_local_account_policy( |
572 kAccountId1, device_local_account_policy_.GetBlob()); | 480 kAccountId1, device_local_account_policy_.GetBlob()); |
573 } | 481 } |
574 | 482 |
575 void SetRecommendedLocales(const char* recommended_locales[], | |
576 size_t array_size) { | |
577 em::StringListPolicyProto* session_locales_proto = | |
578 device_local_account_policy_.payload().mutable_sessionlocales(); | |
579 session_locales_proto->mutable_policy_options()->set_mode( | |
580 em::PolicyOptions_PolicyMode_RECOMMENDED); | |
581 session_locales_proto->mutable_value()->Clear(); | |
582 for (size_t i = 0; i < array_size; ++i) { | |
583 session_locales_proto->mutable_value()->add_entries( | |
584 recommended_locales[i]); | |
585 } | |
586 } | |
587 | |
588 void AddPublicSessionToDevicePolicy(const std::string& username) { | 483 void AddPublicSessionToDevicePolicy(const std::string& username) { |
589 em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); | 484 em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); |
590 em::DeviceLocalAccountInfoProto* account = | 485 em::DeviceLocalAccountInfoProto* account = |
591 proto.mutable_device_local_accounts()->add_account(); | 486 proto.mutable_device_local_accounts()->add_account(); |
592 account->set_account_id(username); | 487 account->set_account_id(username); |
593 account->set_type( | 488 account->set_type( |
594 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); | 489 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION); |
595 RefreshDevicePolicy(); | 490 RefreshDevicePolicy(); |
596 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, | 491 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, |
597 std::string(), proto.SerializeAsString()); | 492 std::string(), proto.SerializeAsString()); |
598 } | 493 } |
599 | 494 |
600 void EnableAutoLogin() { | |
601 em::ChromeDeviceSettingsProto& proto(device_policy()->payload()); | |
602 em::DeviceLocalAccountsProto* device_local_accounts = | |
603 proto.mutable_device_local_accounts(); | |
604 device_local_accounts->set_auto_login_id(kAccountId1); | |
605 device_local_accounts->set_auto_login_delay(0); | |
606 RefreshDevicePolicy(); | |
607 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, | |
608 std::string(), proto.SerializeAsString()); | |
609 } | |
610 | |
611 void CheckPublicSessionPresent(const std::string& id) { | 495 void CheckPublicSessionPresent(const std::string& id) { |
612 const user_manager::User* user = chromeos::UserManager::Get()->FindUser(id); | 496 const user_manager::User* user = chromeos::UserManager::Get()->FindUser(id); |
613 ASSERT_TRUE(user); | 497 ASSERT_TRUE(user); |
614 EXPECT_EQ(id, user->email()); | 498 EXPECT_EQ(id, user->email()); |
615 EXPECT_EQ(user_manager::USER_TYPE_PUBLIC_ACCOUNT, user->GetType()); | 499 EXPECT_EQ(user_manager::USER_TYPE_PUBLIC_ACCOUNT, user->GetType()); |
616 } | 500 } |
617 | 501 |
618 base::FilePath GetExtensionCacheDirectoryForAccountID( | 502 base::FilePath GetExtensionCacheDirectoryForAccountID( |
619 const std::string& account_id) { | 503 const std::string& account_id) { |
620 base::FilePath extension_cache_root_dir; | 504 base::FilePath extension_cache_root_dir; |
(...skipping 25 matching lines...) Expand all Loading... |
646 expected_display_name).Wait(); | 530 expected_display_name).Wait(); |
647 } | 531 } |
648 | 532 |
649 void WaitForPolicy() { | 533 void WaitForPolicy() { |
650 // Wait for the display name becoming available as that indicates | 534 // Wait for the display name becoming available as that indicates |
651 // device-local account policy is fully loaded, which is a prerequisite for | 535 // device-local account policy is fully loaded, which is a prerequisite for |
652 // successful login. | 536 // successful login. |
653 WaitForDisplayName(user_id_1_, kDisplayName1); | 537 WaitForDisplayName(user_id_1_, kDisplayName1); |
654 } | 538 } |
655 | 539 |
| 540 void GetWebContents(content::WebContents** contents) { |
| 541 chromeos::LoginDisplayHostImpl* host = |
| 542 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( |
| 543 chromeos::LoginDisplayHostImpl::default_host()); |
| 544 ASSERT_TRUE(host); |
| 545 chromeos::WebUILoginView* web_ui_login_view = host->GetWebUILoginView(); |
| 546 ASSERT_TRUE(web_ui_login_view); |
| 547 content::WebUI* web_ui = web_ui_login_view->GetWebUI(); |
| 548 ASSERT_TRUE(web_ui); |
| 549 *contents = web_ui->GetWebContents(); |
| 550 ASSERT_TRUE(*contents); |
| 551 } |
| 552 |
| 553 void WaitForLoginUI() { |
| 554 // Wait for the login UI to be ready. |
| 555 chromeos::LoginDisplayHostImpl* host = |
| 556 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( |
| 557 chromeos::LoginDisplayHostImpl::default_host()); |
| 558 ASSERT_TRUE(host); |
| 559 chromeos::OobeUI* oobe_ui = host->GetOobeUI(); |
| 560 ASSERT_TRUE(oobe_ui); |
| 561 base::RunLoop run_loop; |
| 562 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure()); |
| 563 if (!oobe_ui_ready) |
| 564 run_loop.Run(); |
| 565 |
| 566 // The network selection screen changes the application locale on load and |
| 567 // once again on blur. Wait for the screen to load and blur it so that any |
| 568 // locale changes caused by this screen happen now and do not affect any |
| 569 // subsequent parts of the test. |
| 570 content::WebContents* contents = NULL; |
| 571 ASSERT_NO_FATAL_FAILURE(GetWebContents(&contents)); |
| 572 bool done = false; |
| 573 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
| 574 contents, |
| 575 "var languageSelect = document.getElementById('language-select');" |
| 576 "var blurAndReportSuccess = function() {" |
| 577 " languageSelect.blur();" |
| 578 " domAutomationController.send(true);" |
| 579 "};" |
| 580 "if (document.activeElement == languageSelect)" |
| 581 " blurAndReportSuccess();" |
| 582 "else" |
| 583 " languageSelect.addEventListener('focus', blurAndReportSuccess);", |
| 584 &done)); |
| 585 } |
| 586 |
656 void StartLogin(const std::string& locale, | 587 void StartLogin(const std::string& locale, |
657 const std::string& input_method) { | 588 const std::string& input_method) { |
658 // Start login into the device-local account. | 589 // Start login into the device-local account. |
659 chromeos::LoginDisplayHostImpl* host = | 590 chromeos::LoginDisplayHostImpl* host = |
660 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( | 591 reinterpret_cast<chromeos::LoginDisplayHostImpl*>( |
661 chromeos::LoginDisplayHostImpl::default_host()); | 592 chromeos::LoginDisplayHostImpl::default_host()); |
662 ASSERT_TRUE(host); | 593 ASSERT_TRUE(host); |
663 host->StartSignInScreen(LoginScreenContext()); | 594 host->StartSignInScreen(LoginScreenContext()); |
664 chromeos::ExistingUserController* controller = | 595 chromeos::ExistingUserController* controller = |
665 chromeos::ExistingUserController::current_controller(); | 596 chromeos::ExistingUserController::current_controller(); |
666 ASSERT_TRUE(controller); | 597 ASSERT_TRUE(controller); |
667 | 598 |
668 chromeos::UserContext user_context(user_manager::USER_TYPE_PUBLIC_ACCOUNT, | 599 chromeos::UserContext user_context(user_manager::USER_TYPE_PUBLIC_ACCOUNT, |
669 user_id_1_); | 600 user_id_1_); |
670 user_context.SetPublicSessionLocale(locale); | 601 user_context.SetPublicSessionLocale(locale); |
671 user_context.SetPublicSessionInputMethod(input_method); | 602 user_context.SetPublicSessionInputMethod(input_method); |
672 controller->LoginAsPublicSession(user_context); | 603 controller->LoginAsPublicSession(user_context); |
673 } | 604 } |
674 | 605 |
675 void WaitForSessionStart() { | 606 void WaitForSessionStart() { |
676 if (IsSessionStarted()) | 607 if (IsSessionStarted()) |
677 return; | 608 return; |
678 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED, | 609 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED, |
679 base::Bind(IsSessionStarted)).Wait(); | 610 base::Bind(IsSessionStarted)).Wait(); |
680 } | 611 } |
681 | 612 |
682 void VerifyKeyboardLayoutMatchesLocale() { | |
683 chromeos::input_method::InputMethodManager* input_method_manager = | |
684 chromeos::input_method::InputMethodManager::Get(); | |
685 std::vector<std::string> layouts_from_locale; | |
686 input_method_manager->GetInputMethodUtil()-> | |
687 GetInputMethodIdsFromLanguageCode( | |
688 g_browser_process->GetApplicationLocale(), | |
689 chromeos::input_method::kKeyboardLayoutsOnly, | |
690 &layouts_from_locale); | |
691 ASSERT_FALSE(layouts_from_locale.empty()); | |
692 EXPECT_EQ(layouts_from_locale.front(), | |
693 input_method_manager->GetCurrentInputMethod().id()); | |
694 } | |
695 | |
696 const std::string user_id_1_; | 613 const std::string user_id_1_; |
697 const std::string user_id_2_; | 614 const std::string user_id_2_; |
698 const std::string public_session_input_method_id_; | 615 const std::string public_session_input_method_id_; |
699 | 616 |
700 scoped_ptr<base::RunLoop> run_loop_; | 617 scoped_ptr<base::RunLoop> run_loop_; |
701 | 618 |
702 UserPolicyBuilder device_local_account_policy_; | 619 UserPolicyBuilder device_local_account_policy_; |
703 LocalPolicyTestServer test_server_; | 620 LocalPolicyTestServer test_server_; |
704 | 621 |
705 content::WebContents* contents_; | |
706 | |
707 private: | 622 private: |
708 DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountTest); | 623 DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountTest); |
709 }; | 624 }; |
710 | 625 |
711 static bool IsKnownUser(const std::string& account_id) { | 626 static bool IsKnownUser(const std::string& account_id) { |
712 return chromeos::UserManager::Get()->IsKnownUser(account_id); | 627 return chromeos::UserManager::Get()->IsKnownUser(account_id); |
713 } | 628 } |
714 | 629 |
715 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) { | 630 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) { |
716 AddPublicSessionToDevicePolicy(kAccountId1); | 631 AddPublicSessionToDevicePolicy(kAccountId1); |
717 AddPublicSessionToDevicePolicy(kAccountId2); | 632 AddPublicSessionToDevicePolicy(kAccountId2); |
718 | 633 |
719 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED, | 634 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED, |
720 base::Bind(&IsKnownUser, user_id_1_)) | 635 base::Bind(&IsKnownUser, user_id_1_)) |
721 .Wait(); | 636 .Wait(); |
722 EXPECT_TRUE(IsKnownUser(user_id_2_)); | 637 EXPECT_TRUE(IsKnownUser(user_id_2_)); |
723 | 638 |
724 CheckPublicSessionPresent(user_id_1_); | 639 CheckPublicSessionPresent(user_id_1_); |
725 CheckPublicSessionPresent(user_id_2_); | 640 CheckPublicSessionPresent(user_id_2_); |
726 } | 641 } |
727 | 642 |
728 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { | 643 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { |
729 UploadAndInstallDeviceLocalAccountPolicy(); | 644 UploadAndInstallDeviceLocalAccountPolicy(); |
730 AddPublicSessionToDevicePolicy(kAccountId1); | 645 AddPublicSessionToDevicePolicy(kAccountId1); |
731 | 646 |
732 WaitForPolicy(); | 647 WaitForPolicy(); |
733 | 648 |
| 649 // Skip to the login screen. |
| 650 chromeos::WizardController* wizard_controller = |
| 651 chromeos::WizardController::default_controller(); |
| 652 ASSERT_TRUE(wizard_controller); |
| 653 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); |
| 654 content::WindowedNotificationObserver( |
| 655 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, |
| 656 content::NotificationService::AllSources()).Wait(); |
| 657 |
734 // Verify that the display name is shown in the UI. | 658 // Verify that the display name is shown in the UI. |
| 659 content::WebContents* contents = NULL; |
| 660 ASSERT_NO_FATAL_FAILURE(GetWebContents(&contents)); |
735 const std::string get_compact_pod_display_name = base::StringPrintf( | 661 const std::string get_compact_pod_display_name = base::StringPrintf( |
736 "domAutomationController.send(document.getElementById('pod-row')" | 662 "domAutomationController.send(document.getElementById('pod-row')" |
737 " .getPodWithUsername_('%s').nameElement.textContent);", | 663 " .getPodWithUsername_('%s').nameElement.textContent);", |
738 user_id_1_.c_str()); | 664 user_id_1_.c_str()); |
739 std::string display_name; | 665 std::string display_name; |
740 ASSERT_TRUE(content::ExecuteScriptAndExtractString( | 666 ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
741 contents_, | 667 contents, |
742 get_compact_pod_display_name, | 668 get_compact_pod_display_name, |
743 &display_name)); | 669 &display_name)); |
744 EXPECT_EQ(kDisplayName1, display_name); | 670 EXPECT_EQ(kDisplayName1, display_name); |
745 const std::string get_expanded_pod_display_name = base::StringPrintf( | 671 const std::string get_expanded_pod_display_name = base::StringPrintf( |
746 "domAutomationController.send(document.getElementById('pod-row')" | 672 "domAutomationController.send(document.getElementById('pod-row')" |
747 " .getPodWithUsername_('%s').querySelector('.expanded-pane-name')" | 673 " .getPodWithUsername_('%s').querySelector('.expanded-pane-name')" |
748 " .textContent);", | 674 " .textContent);", |
749 user_id_1_.c_str()); | 675 user_id_1_.c_str()); |
750 display_name.clear(); | 676 display_name.clear(); |
751 ASSERT_TRUE(content::ExecuteScriptAndExtractString( | 677 ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
752 contents_, | 678 contents, |
753 get_expanded_pod_display_name, | 679 get_expanded_pod_display_name, |
754 &display_name)); | 680 &display_name)); |
755 EXPECT_EQ(kDisplayName1, display_name); | 681 EXPECT_EQ(kDisplayName1, display_name); |
756 | 682 |
757 // Click on the pod to expand it. | 683 // Click on the pod to expand it. |
758 ASSERT_TRUE(content::ExecuteScript( | 684 ASSERT_TRUE(content::ExecuteScript( |
759 contents_, | 685 contents, |
760 base::StringPrintf( | 686 base::StringPrintf( |
761 "document.getElementById('pod-row').getPodWithUsername_('%s')" | 687 "document.getElementById('pod-row').getPodWithUsername_('%s')" |
762 " .click();", | 688 " .click();", |
763 user_id_1_.c_str()))); | 689 user_id_1_.c_str()))); |
764 | 690 |
765 // Change the display name. | 691 // Change the display name. |
766 device_local_account_policy_.payload().mutable_userdisplayname()->set_value( | 692 device_local_account_policy_.payload().mutable_userdisplayname()->set_value( |
767 kDisplayName2); | 693 kDisplayName2); |
768 UploadAndInstallDeviceLocalAccountPolicy(); | 694 UploadAndInstallDeviceLocalAccountPolicy(); |
769 policy::BrowserPolicyConnectorChromeOS* connector = | 695 policy::BrowserPolicyConnectorChromeOS* connector = |
770 g_browser_process->platform_part()->browser_policy_connector_chromeos(); | 696 g_browser_process->platform_part()->browser_policy_connector_chromeos(); |
771 DeviceLocalAccountPolicyBroker* broker = | 697 DeviceLocalAccountPolicyBroker* broker = |
772 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser( | 698 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser( |
773 user_id_1_); | 699 user_id_1_); |
774 ASSERT_TRUE(broker); | 700 ASSERT_TRUE(broker); |
775 broker->core()->store()->Load(); | 701 broker->core()->store()->Load(); |
776 WaitForDisplayName(user_id_1_, kDisplayName2); | 702 WaitForDisplayName(user_id_1_, kDisplayName2); |
777 | 703 |
778 // Verify that the new display name is shown in the UI. | 704 // Verify that the new display name is shown in the UI. |
779 display_name.clear(); | 705 display_name.clear(); |
780 ASSERT_TRUE(content::ExecuteScriptAndExtractString( | 706 ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
781 contents_, | 707 contents, |
782 get_compact_pod_display_name, | 708 get_compact_pod_display_name, |
783 &display_name)); | 709 &display_name)); |
784 EXPECT_EQ(kDisplayName2, display_name); | 710 EXPECT_EQ(kDisplayName2, display_name); |
785 display_name.clear(); | 711 display_name.clear(); |
786 ASSERT_TRUE(content::ExecuteScriptAndExtractString( | 712 ASSERT_TRUE(content::ExecuteScriptAndExtractString( |
787 contents_, | 713 contents, |
788 get_expanded_pod_display_name, | 714 get_expanded_pod_display_name, |
789 &display_name)); | 715 &display_name)); |
790 EXPECT_EQ(kDisplayName2, display_name); | 716 EXPECT_EQ(kDisplayName2, display_name); |
791 | 717 |
792 // Verify that the pod is still expanded. This indicates that the UI updated | 718 // Verify that the pod is still expanded. This indicates that the UI updated |
793 // without reloading and losing state. | 719 // without reloading and losing state. |
794 bool expanded = false; | 720 bool expanded = false; |
795 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( | 721 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( |
796 contents_, | 722 contents, |
797 base::StringPrintf( | 723 base::StringPrintf( |
798 "domAutomationController.send(document.getElementById('pod-row')" | 724 "domAutomationController.send(document.getElementById('pod-row')" |
799 " .getPodWithUsername_('%s').expanded);", | 725 " .getPodWithUsername_('%s').expanded);", |
800 user_id_1_.c_str()), | 726 user_id_1_.c_str()), |
801 &expanded)); | 727 &expanded)); |
802 EXPECT_TRUE(expanded); | 728 EXPECT_TRUE(expanded); |
803 } | 729 } |
804 | 730 |
805 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, PolicyDownload) { | 731 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, PolicyDownload) { |
806 UploadDeviceLocalAccountPolicy(); | 732 UploadDeviceLocalAccountPolicy(); |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
854 device_local_account_policy_.payload().mutable_restoreonstartup()->set_value( | 780 device_local_account_policy_.payload().mutable_restoreonstartup()->set_value( |
855 SessionStartupPref::kPrefValueURLs); | 781 SessionStartupPref::kPrefValueURLs); |
856 em::StringListPolicyProto* startup_urls_proto = | 782 em::StringListPolicyProto* startup_urls_proto = |
857 device_local_account_policy_.payload().mutable_restoreonstartupurls(); | 783 device_local_account_policy_.payload().mutable_restoreonstartupurls(); |
858 for (size_t i = 0; i < arraysize(kStartupURLs); ++i) | 784 for (size_t i = 0; i < arraysize(kStartupURLs); ++i) |
859 startup_urls_proto->mutable_value()->add_entries(kStartupURLs[i]); | 785 startup_urls_proto->mutable_value()->add_entries(kStartupURLs[i]); |
860 UploadAndInstallDeviceLocalAccountPolicy(); | 786 UploadAndInstallDeviceLocalAccountPolicy(); |
861 AddPublicSessionToDevicePolicy(kAccountId1); | 787 AddPublicSessionToDevicePolicy(kAccountId1); |
862 | 788 |
863 WaitForPolicy(); | 789 WaitForPolicy(); |
864 | 790 ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
865 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); | 791 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
866 WaitForSessionStart(); | 792 WaitForSessionStart(); |
867 | 793 |
868 // Check that the startup pages specified in policy were opened. | 794 // Check that the startup pages specified in policy were opened. |
869 BrowserList* browser_list = | 795 BrowserList* browser_list = |
870 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); | 796 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); |
871 EXPECT_EQ(1U, browser_list->size()); | 797 EXPECT_EQ(1U, browser_list->size()); |
872 Browser* browser = browser_list->get(0); | 798 Browser* browser = browser_list->get(0); |
873 ASSERT_TRUE(browser); | 799 ASSERT_TRUE(browser); |
874 | 800 |
(...skipping 12 matching lines...) Expand all Loading... |
887 ASSERT_TRUE(profile); | 813 ASSERT_TRUE(profile); |
888 EXPECT_FALSE(profile->GetPrefs()->HasPrefPath( | 814 EXPECT_FALSE(profile->GetPrefs()->HasPrefPath( |
889 prefs::kGoogleServicesUsername)); | 815 prefs::kGoogleServicesUsername)); |
890 } | 816 } |
891 | 817 |
892 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, FullscreenDisallowed) { | 818 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, FullscreenDisallowed) { |
893 UploadAndInstallDeviceLocalAccountPolicy(); | 819 UploadAndInstallDeviceLocalAccountPolicy(); |
894 AddPublicSessionToDevicePolicy(kAccountId1); | 820 AddPublicSessionToDevicePolicy(kAccountId1); |
895 | 821 |
896 WaitForPolicy(); | 822 WaitForPolicy(); |
897 | 823 ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
898 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); | 824 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
899 WaitForSessionStart(); | 825 WaitForSessionStart(); |
900 | 826 |
901 BrowserList* browser_list = | 827 BrowserList* browser_list = |
902 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); | 828 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH); |
903 EXPECT_EQ(1U, browser_list->size()); | 829 EXPECT_EQ(1U, browser_list->size()); |
904 Browser* browser = browser_list->get(0); | 830 Browser* browser = browser_list->get(0); |
905 ASSERT_TRUE(browser); | 831 ASSERT_TRUE(browser); |
906 BrowserWindow* browser_window = browser->window(); | 832 BrowserWindow* browser_window = browser->window(); |
907 ASSERT_TRUE(browser_window); | 833 ASSERT_TRUE(browser_window); |
(...skipping 30 matching lines...) Expand all Loading... |
938 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); | 864 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); |
939 forcelist->add_entries(base::StringPrintf( | 865 forcelist->add_entries(base::StringPrintf( |
940 "%s;%s", | 866 "%s;%s", |
941 kGoodExtensionID, | 867 kGoodExtensionID, |
942 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); | 868 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); |
943 | 869 |
944 UploadAndInstallDeviceLocalAccountPolicy(); | 870 UploadAndInstallDeviceLocalAccountPolicy(); |
945 AddPublicSessionToDevicePolicy(kAccountId1); | 871 AddPublicSessionToDevicePolicy(kAccountId1); |
946 | 872 |
947 WaitForPolicy(); | 873 WaitForPolicy(); |
| 874 ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
948 | 875 |
949 // Start listening for app/extension installation results. | 876 // Start listening for app/extension installation results. |
950 content::WindowedNotificationObserver hosted_app_observer( | 877 content::WindowedNotificationObserver hosted_app_observer( |
951 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, | 878 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, |
952 base::Bind(DoesInstallSuccessReferToId, kHostedAppID)); | 879 base::Bind(DoesInstallSuccessReferToId, kHostedAppID)); |
953 content::WindowedNotificationObserver extension_observer( | 880 content::WindowedNotificationObserver extension_observer( |
954 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, | 881 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, |
955 base::Bind(DoesInstallFailureReferToId, kGoodExtensionID)); | 882 base::Bind(DoesInstallFailureReferToId, kGoodExtensionID)); |
956 | 883 |
957 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); | 884 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1017 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); | 944 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); |
1018 forcelist->add_entries(base::StringPrintf( | 945 forcelist->add_entries(base::StringPrintf( |
1019 "%s;%s", | 946 "%s;%s", |
1020 kGoodExtensionID, | 947 kGoodExtensionID, |
1021 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); | 948 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str())); |
1022 | 949 |
1023 UploadAndInstallDeviceLocalAccountPolicy(); | 950 UploadAndInstallDeviceLocalAccountPolicy(); |
1024 AddPublicSessionToDevicePolicy(kAccountId1); | 951 AddPublicSessionToDevicePolicy(kAccountId1); |
1025 | 952 |
1026 WaitForPolicy(); | 953 WaitForPolicy(); |
| 954 ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
1027 | 955 |
1028 // Start listening for app/extension installation results. | 956 // Start listening for app/extension installation results. |
1029 content::WindowedNotificationObserver hosted_app_observer( | 957 content::WindowedNotificationObserver hosted_app_observer( |
1030 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, | 958 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, |
1031 base::Bind(DoesInstallSuccessReferToId, kHostedAppID)); | 959 base::Bind(DoesInstallSuccessReferToId, kHostedAppID)); |
1032 content::WindowedNotificationObserver extension_observer( | 960 content::WindowedNotificationObserver extension_observer( |
1033 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, | 961 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR, |
1034 base::Bind(DoesInstallFailureReferToId, kGoodExtensionID)); | 962 base::Bind(DoesInstallFailureReferToId, kGoodExtensionID)); |
1035 | 963 |
1036 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); | 964 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1126 scoped_ptr<std::string> fetched_external_data; | 1054 scoped_ptr<std::string> fetched_external_data; |
1127 policy_entry->external_data_fetcher->Fetch(base::Bind( | 1055 policy_entry->external_data_fetcher->Fetch(base::Bind( |
1128 &test::ExternalDataFetchCallback, | 1056 &test::ExternalDataFetchCallback, |
1129 &fetched_external_data, | 1057 &fetched_external_data, |
1130 run_loop->QuitClosure())); | 1058 run_loop->QuitClosure())); |
1131 run_loop->Run(); | 1059 run_loop->Run(); |
1132 | 1060 |
1133 ASSERT_TRUE(fetched_external_data); | 1061 ASSERT_TRUE(fetched_external_data); |
1134 EXPECT_EQ(kExternalData, *fetched_external_data); | 1062 EXPECT_EQ(kExternalData, *fetched_external_data); |
1135 | 1063 |
| 1064 ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
1136 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); | 1065 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
1137 WaitForSessionStart(); | 1066 WaitForSessionStart(); |
1138 | 1067 |
1139 // Verify that the external data reference has propagated to the device-local | 1068 // Verify that the external data reference has propagated to the device-local |
1140 // account's ProfilePolicyConnector. | 1069 // account's ProfilePolicyConnector. |
1141 ProfilePolicyConnector* policy_connector = | 1070 ProfilePolicyConnector* policy_connector = |
1142 ProfilePolicyConnectorFactory::GetForProfile(GetProfileForTest()); | 1071 ProfilePolicyConnectorFactory::GetForProfile(GetProfileForTest()); |
1143 ASSERT_TRUE(policy_connector); | 1072 ASSERT_TRUE(policy_connector); |
1144 const PolicyMap& policies = policy_connector->policy_service()->GetPolicies( | 1073 const PolicyMap& policies = policy_connector->policy_service()->GetPolicies( |
1145 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); | 1074 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string())); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1236 // Check image dimensions. Images can't be compared since JPEG is lossy. | 1165 // Check image dimensions. Images can't be compared since JPEG is lossy. |
1237 EXPECT_EQ(policy_image->width(), saved_image->width()); | 1166 EXPECT_EQ(policy_image->width(), saved_image->width()); |
1238 EXPECT_EQ(policy_image->height(), saved_image->height()); | 1167 EXPECT_EQ(policy_image->height(), saved_image->height()); |
1239 } | 1168 } |
1240 | 1169 |
1241 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LastWindowClosedLogoutReminder) { | 1170 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LastWindowClosedLogoutReminder) { |
1242 UploadAndInstallDeviceLocalAccountPolicy(); | 1171 UploadAndInstallDeviceLocalAccountPolicy(); |
1243 AddPublicSessionToDevicePolicy(kAccountId1); | 1172 AddPublicSessionToDevicePolicy(kAccountId1); |
1244 | 1173 |
1245 WaitForPolicy(); | 1174 WaitForPolicy(); |
1246 | 1175 ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
1247 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); | 1176 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
1248 WaitForSessionStart(); | 1177 WaitForSessionStart(); |
1249 | 1178 |
1250 Profile* profile = GetProfileForTest(); | 1179 Profile* profile = GetProfileForTest(); |
1251 ASSERT_TRUE(profile); | 1180 ASSERT_TRUE(profile); |
1252 apps::AppWindowRegistry* app_window_registry = | 1181 apps::AppWindowRegistry* app_window_registry = |
1253 apps::AppWindowRegistry::Get(profile); | 1182 apps::AppWindowRegistry::Get(profile); |
1254 app_window_registry->AddObserver(this); | 1183 app_window_registry->AddObserver(this); |
1255 | 1184 |
1256 // Verify that the logout confirmation dialog is not showing. | 1185 // Verify that the logout confirmation dialog is not showing. |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1385 ASSERT_TRUE(dialog); | 1314 ASSERT_TRUE(dialog); |
1386 | 1315 |
1387 // Deny the logout. | 1316 // Deny the logout. |
1388 dialog->GetWidget()->Close(); | 1317 dialog->GetWidget()->Close(); |
1389 dialog = NULL; | 1318 dialog = NULL; |
1390 base::RunLoop().RunUntilIdle(); | 1319 base::RunLoop().RunUntilIdle(); |
1391 | 1320 |
1392 app_window_registry->RemoveObserver(this); | 1321 app_window_registry->RemoveObserver(this); |
1393 }; | 1322 }; |
1394 | 1323 |
1395 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, NoRecommendedLocaleNoSwitch) { | 1324 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DoNotSelectLanguageAndKeyboard) { |
| 1325 chromeos::input_method::InputMethodManager* input_method_manager = |
| 1326 chromeos::input_method::InputMethodManager::Get(); |
1396 const std::string initial_locale = g_browser_process->GetApplicationLocale(); | 1327 const std::string initial_locale = g_browser_process->GetApplicationLocale(); |
| 1328 const std::string initial_input_method = |
| 1329 input_method_manager->GetCurrentInputMethod().id(); |
1397 | 1330 |
1398 UploadAndInstallDeviceLocalAccountPolicy(); | 1331 UploadAndInstallDeviceLocalAccountPolicy(); |
1399 AddPublicSessionToDevicePolicy(kAccountId1); | 1332 AddPublicSessionToDevicePolicy(kAccountId1); |
1400 | 1333 |
1401 WaitForPolicy(); | 1334 WaitForPolicy(); |
1402 | 1335 ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
1403 // Click on the pod to expand it. Verify that the pod expands to its basic | 1336 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
1404 // form as there are no recommended locales. | |
1405 bool advanced = false; | |
1406 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( | |
1407 contents_, | |
1408 base::StringPrintf( | |
1409 "var pod =" | |
1410 " document.getElementById('pod-row').getPodWithUsername_('%s');" | |
1411 "pod.click();" | |
1412 "domAutomationController.send(pod.classList.contains('advanced'));", | |
1413 user_id_1_.c_str()), | |
1414 &advanced)); | |
1415 EXPECT_FALSE(advanced); | |
1416 | |
1417 // Click the enter button to start the session. | |
1418 ASSERT_TRUE(content::ExecuteScript( | |
1419 contents_, | |
1420 base::StringPrintf( | |
1421 "document.getElementById('pod-row').getPodWithUsername_('%s')" | |
1422 " .querySelector('.enter-button').click();", | |
1423 user_id_1_.c_str()))); | |
1424 | |
1425 WaitForSessionStart(); | 1337 WaitForSessionStart(); |
1426 | 1338 |
1427 // Verify that the locale has not changed and the first keyboard layout | |
1428 // applicable to the locale was chosen. | |
1429 EXPECT_EQ(initial_locale, g_browser_process->GetApplicationLocale()); | 1339 EXPECT_EQ(initial_locale, g_browser_process->GetApplicationLocale()); |
1430 VerifyKeyboardLayoutMatchesLocale(); | 1340 EXPECT_EQ(initial_input_method, |
| 1341 input_method_manager->GetCurrentInputMethod().id()); |
1431 } | 1342 } |
1432 | 1343 |
1433 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, NoRecommendedLocaleSwitch) { | 1344 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, SelectLanguageAndKeyboard) { |
| 1345 // Specify startup pages. |
| 1346 device_local_account_policy_.payload().mutable_restoreonstartup()->set_value( |
| 1347 SessionStartupPref::kPrefValueURLs); |
| 1348 em::StringListPolicyProto* startup_urls_proto = |
| 1349 device_local_account_policy_.payload().mutable_restoreonstartupurls(); |
| 1350 for (size_t i = 0; i < arraysize(kStartupURLs); ++i) |
| 1351 startup_urls_proto->mutable_value()->add_entries(kStartupURLs[i]); |
1434 UploadAndInstallDeviceLocalAccountPolicy(); | 1352 UploadAndInstallDeviceLocalAccountPolicy(); |
1435 AddPublicSessionToDevicePolicy(kAccountId1); | 1353 AddPublicSessionToDevicePolicy(kAccountId1); |
1436 | 1354 |
| 1355 // Log in to the device-local account with a specific locale and keyboard |
| 1356 // layout. |
1437 WaitForPolicy(); | 1357 WaitForPolicy(); |
1438 | 1358 ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
1439 // Click on the pod to expand it. Verify that the pod expands to its basic | 1359 ASSERT_NO_FATAL_FAILURE( |
1440 // form as there are no recommended locales. | 1360 StartLogin(kPublicSessionLocale, public_session_input_method_id_)); |
1441 bool advanced = false; | |
1442 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( | |
1443 contents_, | |
1444 base::StringPrintf( | |
1445 "var pod =" | |
1446 " document.getElementById('pod-row').getPodWithUsername_('%s');" | |
1447 "pod.click();" | |
1448 "domAutomationController.send(pod.classList.contains('advanced'));", | |
1449 user_id_1_.c_str()), | |
1450 &advanced)); | |
1451 EXPECT_FALSE(advanced); | |
1452 | |
1453 // Click the link that switches the pod to its advanced form. Verify that the | |
1454 // pod switches from basic to advanced. | |
1455 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( | |
1456 contents_, | |
1457 base::StringPrintf( | |
1458 "var pod =" | |
1459 " document.getElementById('pod-row').getPodWithUsername_('%s');" | |
1460 "pod.querySelector('.language-and-input').click();" | |
1461 "domAutomationController.send(pod.classList.contains('advanced'));", | |
1462 user_id_1_.c_str()), | |
1463 &advanced)); | |
1464 EXPECT_FALSE(advanced); | |
1465 | |
1466 // Manually select a different locale. | |
1467 ASSERT_TRUE(content::ExecuteScript( | |
1468 contents_, | |
1469 base::StringPrintf( | |
1470 "var languageSelect = document.getElementById('pod-row')" | |
1471 " .getPodWithUsername_('%s').querySelector('.language-select');" | |
1472 "languageSelect.value = '%s';" | |
1473 "var event = document.createEvent('HTMLEvents');" | |
1474 "event.initEvent('change', false, true);" | |
1475 "languageSelect.dispatchEvent(event);", | |
1476 user_id_1_.c_str(), | |
1477 kPublicSessionLocale))); | |
1478 | |
1479 // The UI will have requested an updated list of keyboard layouts at this | |
1480 // point. Wait for the constructions of this list to finish. | |
1481 WaitForGetKeyboardLayoutsForLocaleToFinish(); | |
1482 | |
1483 // Manually select a different keyboard layout and click the enter button to | |
1484 // start the session. | |
1485 ASSERT_TRUE(content::ExecuteScript( | |
1486 contents_, | |
1487 base::StringPrintf( | |
1488 "var pod =" | |
1489 " document.getElementById('pod-row').getPodWithUsername_('%s');" | |
1490 "pod.querySelector('.keyboard-select').value = '%s';" | |
1491 "pod.querySelector('.enter-button').click();", | |
1492 user_id_1_.c_str(), | |
1493 public_session_input_method_id_.c_str()))); | |
1494 | |
1495 WaitForSessionStart(); | 1361 WaitForSessionStart(); |
1496 | 1362 |
1497 // Verify that the locale and keyboard layout have been applied. | 1363 // Verify that the locale and keyboard layout have been applied. |
1498 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale()); | 1364 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale()); |
1499 EXPECT_EQ(public_session_input_method_id_, | 1365 EXPECT_EQ(public_session_input_method_id_, |
1500 chromeos::input_method::InputMethodManager::Get()-> | 1366 chromeos::input_method::InputMethodManager::Get()-> |
1501 GetCurrentInputMethod().id()); | 1367 GetCurrentInputMethod().id()); |
1502 } | 1368 } |
1503 | 1369 |
1504 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, OneRecommendedLocale) { | |
1505 // Specify a recommended locale. | |
1506 SetRecommendedLocales(kSingleRecommendedLocale, | |
1507 arraysize(kSingleRecommendedLocale)); | |
1508 UploadAndInstallDeviceLocalAccountPolicy(); | |
1509 AddPublicSessionToDevicePolicy(kAccountId1); | |
1510 | |
1511 WaitForPolicy(); | |
1512 | |
1513 // Click on the pod to expand it. Verify that the pod expands to its basic | |
1514 // form as there is only one recommended locale. | |
1515 bool advanced = false; | |
1516 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( | |
1517 contents_, | |
1518 base::StringPrintf( | |
1519 "var pod =" | |
1520 " document.getElementById('pod-row').getPodWithUsername_('%s');" | |
1521 "pod.click();" | |
1522 "domAutomationController.send(pod.classList.contains('advanced'));", | |
1523 user_id_1_.c_str()), | |
1524 &advanced)); | |
1525 EXPECT_FALSE(advanced); | |
1526 | |
1527 // Click the enter button to start the session. | |
1528 ASSERT_TRUE(content::ExecuteScript( | |
1529 contents_, | |
1530 base::StringPrintf( | |
1531 "document.getElementById('pod-row').getPodWithUsername_('%s')" | |
1532 " .querySelector('.enter-button').click();", | |
1533 user_id_1_.c_str()))); | |
1534 | |
1535 WaitForSessionStart(); | |
1536 | |
1537 // Verify that the recommended locale has been applied and the first keyboard | |
1538 // layout applicable to the locale was chosen. | |
1539 EXPECT_EQ(kSingleRecommendedLocale[0], | |
1540 g_browser_process->GetApplicationLocale()); | |
1541 VerifyKeyboardLayoutMatchesLocale(); | |
1542 } | |
1543 | |
1544 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, MultipleRecommendedLocales) { | |
1545 // Specify recommended locales. | |
1546 SetRecommendedLocales(kRecommendedLocales1, arraysize(kRecommendedLocales1)); | |
1547 UploadAndInstallDeviceLocalAccountPolicy(); | |
1548 AddPublicSessionToDevicePolicy(kAccountId1); | |
1549 AddPublicSessionToDevicePolicy(kAccountId2); | |
1550 | |
1551 WaitForPolicy(); | |
1552 | |
1553 // Click on the pod to expand it. Verify that the pod expands to its advanced | |
1554 // form directly as there are two or more recommended locales. | |
1555 bool advanced = false; | |
1556 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( | |
1557 contents_, | |
1558 base::StringPrintf( | |
1559 "var pod =" | |
1560 " document.getElementById('pod-row').getPodWithUsername_('%s');" | |
1561 "pod.click();" | |
1562 "domAutomationController.send(pod.classList.contains('advanced'));", | |
1563 user_id_1_.c_str()), | |
1564 &advanced)); | |
1565 EXPECT_TRUE(advanced); | |
1566 | |
1567 // Verify that the pod shows a list of locales beginning with the recommended | |
1568 // ones, followed by others. | |
1569 const std::string get_locale_list = base::StringPrintf( | |
1570 "var languageSelect = document.getElementById('pod-row')" | |
1571 " .getPodWithUsername_('%s').querySelector('.language-select');" | |
1572 "var locales = [];" | |
1573 "for (var i = 0; i < languageSelect.length; ++i)" | |
1574 " locales.push(languageSelect.options[i].value);" | |
1575 "domAutomationController.send(JSON.stringify(locales));", | |
1576 user_id_1_.c_str()); | |
1577 std::string json; | |
1578 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, | |
1579 get_locale_list, | |
1580 &json)); | |
1581 scoped_ptr<base::Value> value_ptr(base::JSONReader::Read(json)); | |
1582 const base::ListValue* locales = NULL; | |
1583 ASSERT_TRUE(value_ptr); | |
1584 ASSERT_TRUE(value_ptr->GetAsList(&locales)); | |
1585 EXPECT_LT(arraysize(kRecommendedLocales1), locales->GetSize()); | |
1586 | |
1587 // Verify that the list starts with the recommended locales, in correct order. | |
1588 for (size_t i = 0; i < arraysize(kRecommendedLocales1); ++i) { | |
1589 std::string locale; | |
1590 EXPECT_TRUE(locales->GetString(i, &locale)); | |
1591 EXPECT_EQ(kRecommendedLocales1[i], locale); | |
1592 } | |
1593 | |
1594 // Verify that the recommended locales do not appear again in the remainder of | |
1595 // the list. | |
1596 std::set<std::string> recommended_locales; | |
1597 for (size_t i = 0; i < arraysize(kRecommendedLocales1); ++i) | |
1598 recommended_locales.insert(kRecommendedLocales1[i]); | |
1599 for (size_t i = arraysize(kRecommendedLocales1); i < locales->GetSize(); | |
1600 ++i) { | |
1601 std::string locale; | |
1602 EXPECT_TRUE(locales->GetString(i, &locale)); | |
1603 EXPECT_EQ(recommended_locales.end(), recommended_locales.find(locale)); | |
1604 } | |
1605 | |
1606 // Verify that the first recommended locale is selected. | |
1607 const std::string get_selected_locale = | |
1608 base::StringPrintf( | |
1609 "domAutomationController.send(document.getElementById('pod-row')" | |
1610 " .getPodWithUsername_('%s').querySelector('.language-select')" | |
1611 " .value);", | |
1612 user_id_1_.c_str()); | |
1613 std::string selected_locale; | |
1614 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, | |
1615 get_selected_locale, | |
1616 &selected_locale)); | |
1617 EXPECT_EQ(kRecommendedLocales1[0], selected_locale); | |
1618 | |
1619 // Change the list of recommended locales. | |
1620 SetRecommendedLocales(kRecommendedLocales2, arraysize(kRecommendedLocales2)); | |
1621 | |
1622 // Also change the display name as it is easy to ensure that policy has been | |
1623 // updated by waiting for a display name change. | |
1624 device_local_account_policy_.payload().mutable_userdisplayname()->set_value( | |
1625 kDisplayName2); | |
1626 UploadAndInstallDeviceLocalAccountPolicy(); | |
1627 policy::BrowserPolicyConnectorChromeOS* connector = | |
1628 g_browser_process->platform_part()->browser_policy_connector_chromeos(); | |
1629 DeviceLocalAccountPolicyBroker* broker = | |
1630 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser( | |
1631 user_id_1_); | |
1632 ASSERT_TRUE(broker); | |
1633 broker->core()->store()->Load(); | |
1634 WaitForDisplayName(user_id_1_, kDisplayName2); | |
1635 | |
1636 // Verify that the new list of locales is shown in the UI. | |
1637 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, | |
1638 get_locale_list, | |
1639 &json)); | |
1640 value_ptr.reset(base::JSONReader::Read(json)); | |
1641 locales = NULL; | |
1642 ASSERT_TRUE(value_ptr); | |
1643 ASSERT_TRUE(value_ptr->GetAsList(&locales)); | |
1644 EXPECT_LT(arraysize(kRecommendedLocales2), locales->GetSize()); | |
1645 for (size_t i = 0; i < arraysize(kRecommendedLocales2); ++i) { | |
1646 std::string locale; | |
1647 EXPECT_TRUE(locales->GetString(i, &locale)); | |
1648 EXPECT_EQ(kRecommendedLocales2[i], locale); | |
1649 } | |
1650 | |
1651 // Verify that the first new recommended locale is selected. | |
1652 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, | |
1653 get_selected_locale, | |
1654 &selected_locale)); | |
1655 EXPECT_EQ(kRecommendedLocales2[0], selected_locale); | |
1656 | |
1657 // Manually select a different locale. | |
1658 ASSERT_TRUE(content::ExecuteScript( | |
1659 contents_, | |
1660 base::StringPrintf( | |
1661 "var languageSelect = document.getElementById('pod-row')" | |
1662 " .getPodWithUsername_('%s').querySelector('.language-select');" | |
1663 "languageSelect.value = '%s';" | |
1664 "var event = document.createEvent('HTMLEvents');" | |
1665 "event.initEvent('change', false, true);" | |
1666 "languageSelect.dispatchEvent(event);", | |
1667 user_id_1_.c_str(), | |
1668 kPublicSessionLocale))); | |
1669 | |
1670 // Change the list of recommended locales. | |
1671 SetRecommendedLocales(kRecommendedLocales2, arraysize(kRecommendedLocales1)); | |
1672 device_local_account_policy_.payload().mutable_userdisplayname()->set_value( | |
1673 kDisplayName1); | |
1674 UploadAndInstallDeviceLocalAccountPolicy(); | |
1675 broker->core()->store()->Load(); | |
1676 WaitForDisplayName(user_id_1_, kDisplayName1); | |
1677 | |
1678 // Verify that the manually selected locale is still selected. | |
1679 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, | |
1680 get_selected_locale, | |
1681 &selected_locale)); | |
1682 EXPECT_EQ(kPublicSessionLocale, selected_locale); | |
1683 | |
1684 // The UI will request an updated list of keyboard layouts at this point. Wait | |
1685 // for the constructions of this list to finish. | |
1686 WaitForGetKeyboardLayoutsForLocaleToFinish(); | |
1687 | |
1688 // Manually select a different keyboard layout. | |
1689 ASSERT_TRUE(content::ExecuteScript( | |
1690 contents_, | |
1691 base::StringPrintf( | |
1692 "document.getElementById('pod-row').getPodWithUsername_('%s')" | |
1693 " .querySelector('.keyboard-select').value = '%s';", | |
1694 user_id_1_.c_str(), | |
1695 public_session_input_method_id_.c_str()))); | |
1696 | |
1697 // Click on a different pod, causing focus to shift away and the pod to | |
1698 // contract. | |
1699 ASSERT_TRUE(content::ExecuteScript( | |
1700 contents_, | |
1701 base::StringPrintf( | |
1702 "document.getElementById('pod-row').getPodWithUsername_('%s')" | |
1703 " .click();", | |
1704 user_id_2_.c_str()))); | |
1705 | |
1706 // Click on the pod again, causing it to expand again. Verify that the pod has | |
1707 // kept all its state (the advanced form is being shown, the manually selected | |
1708 // locale and keyboard layout are selected). | |
1709 ASSERT_TRUE(content::ExecuteScriptAndExtractString( | |
1710 contents_, | |
1711 base::StringPrintf( | |
1712 "var pod =" | |
1713 " document.getElementById('pod-row').getPodWithUsername_('%s');" | |
1714 "pod.click();" | |
1715 "var state = {};" | |
1716 "state.advanced = pod.classList.contains('advanced');" | |
1717 "state.locale = pod.querySelector('.language-select').value;" | |
1718 "state.keyboardLayout = pod.querySelector('.keyboard-select').value;" | |
1719 "console.log(JSON.stringify(state));" | |
1720 "domAutomationController.send(JSON.stringify(state));", | |
1721 user_id_1_.c_str()), | |
1722 &json)); | |
1723 LOG(ERROR) << json; | |
1724 value_ptr.reset(base::JSONReader::Read(json)); | |
1725 const base::DictionaryValue* state = NULL; | |
1726 ASSERT_TRUE(value_ptr); | |
1727 ASSERT_TRUE(value_ptr->GetAsDictionary(&state)); | |
1728 EXPECT_TRUE(state->GetBoolean("advanced", &advanced)); | |
1729 EXPECT_TRUE(advanced); | |
1730 EXPECT_TRUE(state->GetString("locale", &selected_locale)); | |
1731 EXPECT_EQ(kPublicSessionLocale, selected_locale); | |
1732 std::string selected_keyboard_layout; | |
1733 EXPECT_TRUE(state->GetString("keyboardLayout", &selected_keyboard_layout)); | |
1734 EXPECT_EQ(public_session_input_method_id_, selected_keyboard_layout); | |
1735 | |
1736 // Click the enter button to start the session. | |
1737 ASSERT_TRUE(content::ExecuteScript( | |
1738 contents_, | |
1739 base::StringPrintf( | |
1740 "document.getElementById('pod-row').getPodWithUsername_('%s')" | |
1741 " .querySelector('.enter-button').click();", | |
1742 user_id_1_.c_str()))); | |
1743 | |
1744 WaitForSessionStart(); | |
1745 | |
1746 // Verify that the locale and keyboard layout have been applied. | |
1747 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale()); | |
1748 EXPECT_EQ(public_session_input_method_id_, | |
1749 chromeos::input_method::InputMethodManager::Get()-> | |
1750 GetCurrentInputMethod().id()); | |
1751 } | |
1752 | |
1753 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, | 1370 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, |
1754 AutoLoginWithoutRecommendedLocales) { | 1371 SelectLanguageAndKeyboardWithTermsOfService) { |
1755 const std::string initial_locale = g_browser_process->GetApplicationLocale(); | |
1756 | |
1757 UploadAndInstallDeviceLocalAccountPolicy(); | |
1758 AddPublicSessionToDevicePolicy(kAccountId1); | |
1759 EnableAutoLogin(); | |
1760 | |
1761 WaitForPolicy(); | |
1762 | |
1763 WaitForSessionStart(); | |
1764 | |
1765 // Verify that the locale has not changed and the first keyboard layout | |
1766 // applicable to the locale was chosen. | |
1767 EXPECT_EQ(initial_locale, g_browser_process->GetApplicationLocale()); | |
1768 VerifyKeyboardLayoutMatchesLocale(); | |
1769 } | |
1770 | |
1771 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, | |
1772 AutoLoginWithRecommendedLocales) { | |
1773 // Specify recommended locales. | |
1774 SetRecommendedLocales(kRecommendedLocales1, arraysize(kRecommendedLocales1)); | |
1775 UploadAndInstallDeviceLocalAccountPolicy(); | |
1776 AddPublicSessionToDevicePolicy(kAccountId1); | |
1777 EnableAutoLogin(); | |
1778 | |
1779 WaitForPolicy(); | |
1780 | |
1781 WaitForSessionStart(); | |
1782 | |
1783 // Verify that the first recommended locale has been applied and the first | |
1784 // keyboard layout applicable to the locale was chosen. | |
1785 EXPECT_EQ(kRecommendedLocales1[0], g_browser_process->GetApplicationLocale()); | |
1786 VerifyKeyboardLayoutMatchesLocale(); | |
1787 } | |
1788 | |
1789 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, TermsOfServiceWithLocaleSwitch) { | |
1790 // Specify Terms of Service URL. | 1372 // Specify Terms of Service URL. |
1791 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | 1373 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
1792 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( | 1374 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( |
1793 embedded_test_server()->GetURL( | 1375 embedded_test_server()->GetURL( |
1794 std::string("/") + kExistentTermsOfServicePath).spec()); | 1376 std::string("/") + kExistentTermsOfServicePath).spec()); |
1795 UploadAndInstallDeviceLocalAccountPolicy(); | 1377 UploadAndInstallDeviceLocalAccountPolicy(); |
1796 AddPublicSessionToDevicePolicy(kAccountId1); | 1378 AddPublicSessionToDevicePolicy(kAccountId1); |
1797 | 1379 |
| 1380 // Log in to the device-local account with a specific locale and keyboard |
| 1381 // layout. |
1798 WaitForPolicy(); | 1382 WaitForPolicy(); |
1799 | 1383 ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
1800 // Select a different locale. | 1384 ASSERT_NO_FATAL_FAILURE( |
1801 ASSERT_TRUE(content::ExecuteScript( | 1385 StartLogin(kPublicSessionLocale, public_session_input_method_id_)); |
1802 contents_, | |
1803 base::StringPrintf( | |
1804 "var languageSelect = document.getElementById('pod-row')" | |
1805 " .getPodWithUsername_('%s').querySelector('.language-select');" | |
1806 "languageSelect.value = '%s';" | |
1807 "var event = document.createEvent('HTMLEvents');" | |
1808 "event.initEvent('change', false, true);" | |
1809 "languageSelect.dispatchEvent(event);", | |
1810 user_id_1_.c_str(), | |
1811 kPublicSessionLocale))); | |
1812 | |
1813 // The UI will have requested an updated list of keyboard layouts at this | |
1814 // point. Wait for the constructions of this list to finish. | |
1815 WaitForGetKeyboardLayoutsForLocaleToFinish(); | |
1816 | 1386 |
1817 // Set up an observer that will quit the message loop when login has succeeded | 1387 // Set up an observer that will quit the message loop when login has succeeded |
1818 // and the first wizard screen, if any, is being shown. | 1388 // and the first wizard screen, if any, is being shown. |
1819 base::RunLoop login_wait_run_loop; | 1389 base::RunLoop login_wait_run_loop; |
1820 chromeos::MockAuthStatusConsumer login_status_consumer; | 1390 chromeos::MockAuthStatusConsumer login_status_consumer; |
1821 EXPECT_CALL(login_status_consumer, OnAuthSuccess(_)).Times(1).WillOnce( | 1391 EXPECT_CALL(login_status_consumer, OnAuthSuccess(_)).Times(1).WillOnce( |
1822 InvokeWithoutArgs(&login_wait_run_loop, &base::RunLoop::Quit)); | 1392 InvokeWithoutArgs(&login_wait_run_loop, &base::RunLoop::Quit)); |
| 1393 |
| 1394 // Spin the loop until the observer fires. Then, unregister the observer. |
1823 chromeos::ExistingUserController* controller = | 1395 chromeos::ExistingUserController* controller = |
1824 chromeos::ExistingUserController::current_controller(); | 1396 chromeos::ExistingUserController::current_controller(); |
1825 ASSERT_TRUE(controller); | 1397 ASSERT_TRUE(controller); |
1826 controller->set_login_status_consumer(&login_status_consumer); | 1398 controller->set_login_status_consumer(&login_status_consumer); |
1827 | |
1828 // Manually select a different keyboard layout and click the enter button to | |
1829 // start the session. | |
1830 ASSERT_TRUE(content::ExecuteScript( | |
1831 contents_, | |
1832 base::StringPrintf( | |
1833 "var pod =" | |
1834 " document.getElementById('pod-row').getPodWithUsername_('%s');" | |
1835 "pod.querySelector('.keyboard-select').value = '%s';" | |
1836 "pod.querySelector('.enter-button').click();", | |
1837 user_id_1_.c_str(), | |
1838 public_session_input_method_id_.c_str()))); | |
1839 | |
1840 // Spin the loop until the login observer fires. Then, unregister the | |
1841 // observer. | |
1842 login_wait_run_loop.Run(); | 1399 login_wait_run_loop.Run(); |
1843 controller->set_login_status_consumer(NULL); | 1400 controller->set_login_status_consumer(NULL); |
1844 | 1401 |
1845 // Verify that the Terms of Service screen is being shown. | 1402 // Verify that the Terms of Service screen is being shown. |
1846 chromeos::WizardController* wizard_controller = | 1403 chromeos::WizardController* wizard_controller = |
1847 chromeos::WizardController::default_controller(); | 1404 chromeos::WizardController::default_controller(); |
1848 ASSERT_TRUE(wizard_controller); | 1405 ASSERT_TRUE(wizard_controller); |
1849 ASSERT_TRUE(wizard_controller->current_screen()); | 1406 ASSERT_TRUE(wizard_controller->current_screen()); |
1850 EXPECT_EQ(chromeos::WizardController::kTermsOfServiceScreenName, | 1407 EXPECT_EQ(chromeos::WizardController::kTermsOfServiceScreenName, |
1851 wizard_controller->current_screen()->GetName()); | 1408 wizard_controller->current_screen()->GetName()); |
1852 | 1409 |
1853 // Wait for the Terms of Service to finish downloading. | 1410 // Wait for the Terms of Service to finish downloading. |
| 1411 content::WebContents* contents = NULL; |
| 1412 ASSERT_NO_FATAL_FAILURE(GetWebContents(&contents)); |
1854 bool done = false; | 1413 bool done = false; |
1855 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(contents_, | 1414 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(contents, |
1856 "var screenElement = document.getElementById('terms-of-service');" | 1415 "var screenElement = document.getElementById('terms-of-service');" |
1857 "function SendReplyIfDownloadDone() {" | 1416 "function SendReplyIfDownloadDone() {" |
1858 " if (screenElement.classList.contains('tos-loading'))" | 1417 " if (screenElement.classList.contains('tos-loading'))" |
1859 " return false;" | 1418 " return false;" |
1860 " domAutomationController.send(true);" | 1419 " domAutomationController.send(true);" |
1861 " observer.disconnect();" | 1420 " observer.disconnect();" |
1862 " return true;" | 1421 " return true;" |
1863 "}" | 1422 "}" |
1864 "var observer = new MutationObserver(SendReplyIfDownloadDone);" | 1423 "var observer = new MutationObserver(SendReplyIfDownloadDone);" |
1865 "if (!SendReplyIfDownloadDone()) {" | 1424 "if (!SendReplyIfDownloadDone()) {" |
1866 " var options = { attributes: true, attributeFilter: [ 'class' ] };" | 1425 " var options = { attributes: true, attributeFilter: [ 'class' ] };" |
1867 " observer.observe(screenElement, options);" | 1426 " observer.observe(screenElement, options);" |
1868 "}", | 1427 "}", |
1869 &done)); | 1428 &done)); |
1870 | 1429 |
1871 // Verify that the locale and keyboard layout have been applied. | 1430 // Verify that the locale and keyboard layout have been applied. |
1872 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale()); | 1431 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale()); |
1873 EXPECT_EQ(public_session_input_method_id_, | 1432 EXPECT_EQ(public_session_input_method_id_, |
1874 chromeos::input_method::InputMethodManager::Get()-> | 1433 chromeos::input_method::InputMethodManager::Get()-> |
1875 GetCurrentInputMethod().id()); | 1434 GetCurrentInputMethod().id()); |
1876 | 1435 |
1877 // Click the accept button. | 1436 // Click the accept button. |
1878 ASSERT_TRUE(content::ExecuteScript(contents_, | 1437 ASSERT_TRUE(content::ExecuteScript(contents, |
1879 "$('tos-accept-button').click();")); | 1438 "$('tos-accept-button').click();")); |
1880 | 1439 |
1881 WaitForSessionStart(); | 1440 WaitForSessionStart(); |
1882 | 1441 |
1883 // Verify that the locale and keyboard layout are still in force. | 1442 // Verify that the locale and keyboard layout are still in force. |
1884 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale()); | 1443 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale()); |
1885 EXPECT_EQ(public_session_input_method_id_, | 1444 EXPECT_EQ(public_session_input_method_id_, |
1886 chromeos::input_method::InputMethodManager::Get()-> | 1445 chromeos::input_method::InputMethodManager::Get()-> |
1887 GetCurrentInputMethod().id()); | 1446 GetCurrentInputMethod().id()); |
1888 } | 1447 } |
1889 | 1448 |
1890 class TermsOfServiceDownloadTest : public DeviceLocalAccountTest, | 1449 class TermsOfServiceDownloadTest : public DeviceLocalAccountTest, |
1891 public testing::WithParamInterface<bool> { | 1450 public testing::WithParamInterface<bool> { |
1892 }; | 1451 }; |
1893 | 1452 |
1894 IN_PROC_BROWSER_TEST_P(TermsOfServiceDownloadTest, TermsOfServiceScreen) { | 1453 IN_PROC_BROWSER_TEST_P(TermsOfServiceDownloadTest, TermsOfServiceScreen) { |
1895 // Specify Terms of Service URL. | 1454 // Specify Terms of Service URL. |
1896 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | 1455 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
1897 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( | 1456 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value( |
1898 embedded_test_server()->GetURL( | 1457 embedded_test_server()->GetURL( |
1899 std::string("/") + | 1458 std::string("/") + |
1900 (GetParam() ? kExistentTermsOfServicePath | 1459 (GetParam() ? kExistentTermsOfServicePath |
1901 : kNonexistentTermsOfServicePath)).spec()); | 1460 : kNonexistentTermsOfServicePath)).spec()); |
1902 UploadAndInstallDeviceLocalAccountPolicy(); | 1461 UploadAndInstallDeviceLocalAccountPolicy(); |
1903 AddPublicSessionToDevicePolicy(kAccountId1); | 1462 AddPublicSessionToDevicePolicy(kAccountId1); |
1904 | 1463 |
1905 WaitForPolicy(); | 1464 WaitForPolicy(); |
1906 | 1465 ASSERT_NO_FATAL_FAILURE(WaitForLoginUI()); |
1907 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); | 1466 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string())); |
1908 | 1467 |
1909 // Set up an observer that will quit the message loop when login has succeeded | 1468 // Set up an observer that will quit the message loop when login has succeeded |
1910 // and the first wizard screen, if any, is being shown. | 1469 // and the first wizard screen, if any, is being shown. |
1911 base::RunLoop login_wait_run_loop; | 1470 base::RunLoop login_wait_run_loop; |
1912 chromeos::MockAuthStatusConsumer login_status_consumer; | 1471 chromeos::MockAuthStatusConsumer login_status_consumer; |
1913 EXPECT_CALL(login_status_consumer, OnAuthSuccess(_)).Times(1).WillOnce( | 1472 EXPECT_CALL(login_status_consumer, OnAuthSuccess(_)).Times(1).WillOnce( |
1914 InvokeWithoutArgs(&login_wait_run_loop, &base::RunLoop::Quit)); | 1473 InvokeWithoutArgs(&login_wait_run_loop, &base::RunLoop::Quit)); |
1915 | 1474 |
1916 // Spin the loop until the observer fires. Then, unregister the observer. | 1475 // Spin the loop until the observer fires. Then, unregister the observer. |
1917 chromeos::ExistingUserController* controller = | 1476 chromeos::ExistingUserController* controller = |
1918 chromeos::ExistingUserController::current_controller(); | 1477 chromeos::ExistingUserController::current_controller(); |
1919 ASSERT_TRUE(controller); | 1478 ASSERT_TRUE(controller); |
1920 controller->set_login_status_consumer(&login_status_consumer); | 1479 controller->set_login_status_consumer(&login_status_consumer); |
1921 login_wait_run_loop.Run(); | 1480 login_wait_run_loop.Run(); |
1922 controller->set_login_status_consumer(NULL); | 1481 controller->set_login_status_consumer(NULL); |
1923 | 1482 |
1924 // Verify that the Terms of Service screen is being shown. | 1483 // Verify that the Terms of Service screen is being shown. |
1925 chromeos::WizardController* wizard_controller = | 1484 chromeos::WizardController* wizard_controller = |
1926 chromeos::WizardController::default_controller(); | 1485 chromeos::WizardController::default_controller(); |
1927 ASSERT_TRUE(wizard_controller); | 1486 ASSERT_TRUE(wizard_controller); |
1928 ASSERT_TRUE(wizard_controller->current_screen()); | 1487 ASSERT_TRUE(wizard_controller->current_screen()); |
1929 EXPECT_EQ(chromeos::WizardController::kTermsOfServiceScreenName, | 1488 EXPECT_EQ(chromeos::WizardController::kTermsOfServiceScreenName, |
1930 wizard_controller->current_screen()->GetName()); | 1489 wizard_controller->current_screen()->GetName()); |
1931 | 1490 |
1932 // Wait for the Terms of Service to finish downloading, then get the status of | 1491 // Wait for the Terms of Service to finish downloading, then get the status of |
1933 // the screen's UI elements. | 1492 // the screen's UI elements. |
| 1493 content::WebContents* contents = NULL; |
| 1494 ASSERT_NO_FATAL_FAILURE(GetWebContents(&contents)); |
1934 std::string json; | 1495 std::string json; |
1935 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_, | 1496 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents, |
1936 "var screenElement = document.getElementById('terms-of-service');" | 1497 "var screenElement = document.getElementById('terms-of-service');" |
1937 "function SendReplyIfDownloadDone() {" | 1498 "function SendReplyIfDownloadDone() {" |
1938 " if (screenElement.classList.contains('tos-loading'))" | 1499 " if (screenElement.classList.contains('tos-loading'))" |
1939 " return false;" | 1500 " return false;" |
1940 " var status = {};" | 1501 " var status = {};" |
1941 " status.heading = document.getElementById('tos-heading').textContent;" | 1502 " status.heading = document.getElementById('tos-heading').textContent;" |
1942 " status.subheading =" | 1503 " status.subheading =" |
1943 " document.getElementById('tos-subheading').textContent;" | 1504 " document.getElementById('tos-subheading').textContent;" |
1944 " status.contentHeading =" | 1505 " status.contentHeading =" |
1945 " document.getElementById('tos-content-heading').textContent;" | 1506 " document.getElementById('tos-content-heading').textContent;" |
1946 " status.content =" | 1507 " status.content =" |
1947 " document.getElementById('tos-content-main').textContent;" | 1508 " document.getElementById('tos-content-main').textContent;" |
1948 " status.error = screenElement.classList.contains('error');" | 1509 " status.error = screenElement.classList.contains('error');" |
1949 " status.acceptEnabled =" | 1510 " status.acceptEnabled =" |
1950 " !document.getElementById('tos-accept-button').disabled;" | 1511 " !document.getElementById('tos-accept-button').disabled;" |
1951 " domAutomationController.send(JSON.stringify(status));" | 1512 " domAutomationController.send(JSON.stringify(status));" |
1952 " observer.disconnect();" | 1513 " observer.disconnect();" |
1953 " return true;" | 1514 " return true;" |
1954 "}" | 1515 "}" |
1955 "var observer = new MutationObserver(SendReplyIfDownloadDone);" | 1516 "var observer = new MutationObserver(SendReplyIfDownloadDone);" |
1956 "if (!SendReplyIfDownloadDone()) {" | 1517 "if (!SendReplyIfDownloadDone()) {" |
1957 " var options = { attributes: true, attributeFilter: [ 'class' ] };" | 1518 " var options = { attributes: true, attributeFilter: [ 'class' ] };" |
1958 " observer.observe(screenElement, options);" | 1519 " observer.observe(screenElement, options);" |
1959 "}", | 1520 "}", |
1960 &json)); | 1521 &json)); |
1961 scoped_ptr<base::Value> value_ptr(base::JSONReader::Read(json)); | 1522 scoped_ptr<base::Value> value_ptr(base::JSONReader::Read(json)); |
1962 const base::DictionaryValue* status = NULL; | 1523 const base::DictionaryValue* status = NULL; |
1963 ASSERT_TRUE(value_ptr); | 1524 ASSERT_TRUE(value_ptr.get()); |
1964 ASSERT_TRUE(value_ptr->GetAsDictionary(&status)); | 1525 ASSERT_TRUE(value_ptr->GetAsDictionary(&status)); |
1965 std::string heading; | 1526 std::string heading; |
1966 EXPECT_TRUE(status->GetString("heading", &heading)); | 1527 EXPECT_TRUE(status->GetString("heading", &heading)); |
1967 std::string subheading; | 1528 std::string subheading; |
1968 EXPECT_TRUE(status->GetString("subheading", &subheading)); | 1529 EXPECT_TRUE(status->GetString("subheading", &subheading)); |
1969 std::string content_heading; | 1530 std::string content_heading; |
1970 EXPECT_TRUE(status->GetString("contentHeading", &content_heading)); | 1531 EXPECT_TRUE(status->GetString("contentHeading", &content_heading)); |
1971 std::string content; | 1532 std::string content; |
1972 EXPECT_TRUE(status->GetString("content", &content)); | 1533 EXPECT_TRUE(status->GetString("content", &content)); |
1973 bool error; | 1534 bool error; |
(...skipping 28 matching lines...) Expand all Loading... |
2002 base::FilePath test_dir; | 1563 base::FilePath test_dir; |
2003 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); | 1564 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); |
2004 std::string terms_of_service; | 1565 std::string terms_of_service; |
2005 ASSERT_TRUE(base::ReadFileToString( | 1566 ASSERT_TRUE(base::ReadFileToString( |
2006 test_dir.Append(kExistentTermsOfServicePath), &terms_of_service)); | 1567 test_dir.Append(kExistentTermsOfServicePath), &terms_of_service)); |
2007 EXPECT_EQ(terms_of_service, content); | 1568 EXPECT_EQ(terms_of_service, content); |
2008 EXPECT_FALSE(error); | 1569 EXPECT_FALSE(error); |
2009 EXPECT_TRUE(accept_enabled); | 1570 EXPECT_TRUE(accept_enabled); |
2010 | 1571 |
2011 // Click the accept button. | 1572 // Click the accept button. |
2012 ASSERT_TRUE(content::ExecuteScript(contents_, | 1573 ASSERT_TRUE(content::ExecuteScript(contents, |
2013 "$('tos-accept-button').click();")); | 1574 "$('tos-accept-button').click();")); |
2014 | 1575 |
2015 WaitForSessionStart(); | 1576 WaitForSessionStart(); |
2016 } | 1577 } |
2017 | 1578 |
2018 INSTANTIATE_TEST_CASE_P(TermsOfServiceDownloadTestInstance, | 1579 INSTANTIATE_TEST_CASE_P(TermsOfServiceDownloadTestInstance, |
2019 TermsOfServiceDownloadTest, testing::Bool()); | 1580 TermsOfServiceDownloadTest, testing::Bool()); |
2020 | 1581 |
2021 } // namespace policy | 1582 } // namespace policy |
OLD | NEW |