Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / chromeos / policy / device_local_account_browsertest.cc
blob739e4283ba61527a223ccc7f2a4e02353a3b9aa9
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
3 // found in the LICENSE file.
5 #include <map>
6 #include <set>
7 #include <string>
8 #include <vector>
10 #include "ash/shell.h"
11 #include "ash/system/chromeos/session/logout_confirmation_controller.h"
12 #include "ash/system/chromeos/session/logout_confirmation_dialog.h"
13 #include "base/basictypes.h"
14 #include "base/bind.h"
15 #include "base/bind_helpers.h"
16 #include "base/callback.h"
17 #include "base/command_line.h"
18 #include "base/files/file_path.h"
19 #include "base/files/file_util.h"
20 #include "base/json/json_reader.h"
21 #include "base/json/json_writer.h"
22 #include "base/location.h"
23 #include "base/macros.h"
24 #include "base/memory/ref_counted.h"
25 #include "base/memory/scoped_ptr.h"
26 #include "base/message_loop/message_loop.h"
27 #include "base/message_loop/message_loop_proxy.h"
28 #include "base/path_service.h"
29 #include "base/prefs/pref_change_registrar.h"
30 #include "base/prefs/pref_service.h"
31 #include "base/run_loop.h"
32 #include "base/sequenced_task_runner.h"
33 #include "base/strings/string_number_conversions.h"
34 #include "base/strings/string_util.h"
35 #include "base/strings/stringprintf.h"
36 #include "base/strings/utf_string_conversions.h"
37 #include "base/threading/sequenced_worker_pool.h"
38 #include "base/values.h"
39 #include "chrome/browser/browser_process.h"
40 #include "chrome/browser/chrome_notification_types.h"
41 #include "chrome/browser/chromeos/extensions/device_local_account_external_policy_loader.h"
42 #include "chrome/browser/chromeos/extensions/external_cache.h"
43 #include "chrome/browser/chromeos/input_method/input_method_util.h"
44 #include "chrome/browser/chromeos/login/existing_user_controller.h"
45 #include "chrome/browser/chromeos/login/screens/base_screen.h"
46 #include "chrome/browser/chromeos/login/signin_specifics.h"
47 #include "chrome/browser/chromeos/login/ui/login_display_host.h"
48 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
49 #include "chrome/browser/chromeos/login/ui/webui_login_view.h"
50 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager.h"
51 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_impl.h"
52 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager_test_util.h"
53 #include "chrome/browser/chromeos/login/users/chrome_user_manager_impl.h"
54 #include "chrome/browser/chromeos/login/wizard_controller.h"
55 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
56 #include "chrome/browser/chromeos/policy/cloud_external_data_manager_base_test_util.h"
57 #include "chrome/browser/chromeos/policy/device_local_account.h"
58 #include "chrome/browser/chromeos/policy/device_local_account_policy_service.h"
59 #include "chrome/browser/chromeos/policy/device_policy_builder.h"
60 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
61 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
62 #include "chrome/browser/extensions/crx_installer.h"
63 #include "chrome/browser/extensions/extension_service.h"
64 #include "chrome/browser/extensions/updater/chromeos_extension_cache_delegate.h"
65 #include "chrome/browser/extensions/updater/extension_cache_impl.h"
66 #include "chrome/browser/extensions/updater/local_extension_cache.h"
67 #include "chrome/browser/lifetime/application_lifetime.h"
68 #include "chrome/browser/policy/profile_policy_connector.h"
69 #include "chrome/browser/policy/profile_policy_connector_factory.h"
70 #include "chrome/browser/policy/test/local_policy_test_server.h"
71 #include "chrome/browser/prefs/session_startup_pref.h"
72 #include "chrome/browser/profiles/profile.h"
73 #include "chrome/browser/profiles/profile_manager.h"
74 #include "chrome/browser/signin/signin_manager_factory.h"
75 #include "chrome/browser/ui/browser.h"
76 #include "chrome/browser/ui/browser_commands.h"
77 #include "chrome/browser/ui/browser_finder.h"
78 #include "chrome/browser/ui/browser_list.h"
79 #include "chrome/browser/ui/browser_list_observer.h"
80 #include "chrome/browser/ui/browser_window.h"
81 #include "chrome/browser/ui/extensions/app_launch_params.h"
82 #include "chrome/browser/ui/extensions/application_launch.h"
83 #include "chrome/browser/ui/host_desktop.h"
84 #include "chrome/browser/ui/tabs/tab_strip_model.h"
85 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
86 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
87 #include "chrome/common/chrome_paths.h"
88 #include "chrome/common/extensions/extension_constants.h"
89 #include "chrome/grit/chromium_strings.h"
90 #include "chrome/grit/generated_resources.h"
91 #include "chromeos/chromeos_paths.h"
92 #include "chromeos/chromeos_switches.h"
93 #include "chromeos/dbus/fake_session_manager_client.h"
94 #include "chromeos/login/auth/mock_auth_status_consumer.h"
95 #include "chromeos/login/auth/user_context.h"
96 #include "components/policy/core/common/cloud/cloud_policy_constants.h"
97 #include "components/policy/core/common/cloud/cloud_policy_core.h"
98 #include "components/policy/core/common/cloud/cloud_policy_store.h"
99 #include "components/policy/core/common/cloud/policy_builder.h"
100 #include "components/policy/core/common/external_data_fetcher.h"
101 #include "components/policy/core/common/policy_map.h"
102 #include "components/policy/core/common/policy_namespace.h"
103 #include "components/policy/core/common/policy_service.h"
104 #include "components/policy/core/common/policy_switches.h"
105 #include "components/signin/core/browser/signin_manager.h"
106 #include "components/user_manager/user.h"
107 #include "components/user_manager/user_manager.h"
108 #include "components/user_manager/user_type.h"
109 #include "content/public/browser/browser_thread.h"
110 #include "content/public/browser/notification_details.h"
111 #include "content/public/browser/notification_service.h"
112 #include "content/public/browser/notification_source.h"
113 #include "content/public/browser/web_contents.h"
114 #include "content/public/browser/web_ui.h"
115 #include "content/public/test/browser_test_utils.h"
116 #include "content/public/test/test_utils.h"
117 #include "crypto/rsa_private_key.h"
118 #include "extensions/browser/app_window/app_window.h"
119 #include "extensions/browser/app_window/app_window_registry.h"
120 #include "extensions/browser/app_window/native_app_window.h"
121 #include "extensions/browser/extension_system.h"
122 #include "extensions/browser/install/crx_install_error.h"
123 #include "extensions/browser/management_policy.h"
124 #include "extensions/browser/notification_types.h"
125 #include "extensions/common/constants.h"
126 #include "extensions/common/extension.h"
127 #include "net/base/url_util.h"
128 #include "net/http/http_status_code.h"
129 #include "net/test/embedded_test_server/embedded_test_server.h"
130 #include "net/test/embedded_test_server/http_request.h"
131 #include "net/test/embedded_test_server/http_response.h"
132 #include "net/url_request/test_url_fetcher_factory.h"
133 #include "net/url_request/url_fetcher_delegate.h"
134 #include "net/url_request/url_request_status.h"
135 #include "policy/policy_constants.h"
136 #include "testing/gmock/include/gmock/gmock.h"
137 #include "third_party/icu/source/common/unicode/locid.h"
138 #include "ui/base/ime/chromeos/extension_ime_util.h"
139 #include "ui/base/ime/chromeos/input_method_descriptor.h"
140 #include "ui/base/ime/chromeos/input_method_manager.h"
141 #include "ui/base/l10n/l10n_util.h"
142 #include "ui/base/window_open_disposition.h"
143 #include "ui/gfx/image/image_skia.h"
144 #include "ui/views/widget/widget.h"
145 #include "url/gurl.h"
147 namespace em = enterprise_management;
149 using chromeos::LoginScreenContext;
150 using testing::InvokeWithoutArgs;
151 using testing::Return;
152 using testing::_;
154 namespace policy {
156 namespace {
158 const char kDomain[] = "example.com";
159 const char kAccountId1[] = "dla1@example.com";
160 const char kAccountId2[] = "dla2@example.com";
161 const char kDisplayName1[] = "display name 1";
162 const char kDisplayName2[] = "display name 2";
163 const char* const kStartupURLs[] = {
164 "chrome://policy",
165 "chrome://about",
167 const char kExistentTermsOfServicePath[] = "chromeos/enterprise/tos.txt";
168 const char kNonexistentTermsOfServicePath[] = "chromeos/enterprise/tos404.txt";
169 const char kRelativeUpdateURL[] = "/service/update2/crx";
170 const char kUpdateManifestHeader[] =
171 "<?xml version='1.0' encoding='UTF-8'?>\n"
172 "<gupdate xmlns='http://www.google.com/update2/response' protocol='2.0'>\n";
173 const char kUpdateManifestTemplate[] =
174 " <app appid='%s'>\n"
175 " <updatecheck codebase='%s' version='%s' />\n"
176 " </app>\n";
177 const char kUpdateManifestFooter[] =
178 "</gupdate>\n";
179 const char kHostedAppID[] = "kbmnembihfiondgfjekmnmcbddelicoi";
180 const char kHostedAppCRXPath[] = "extensions/hosted_app.crx";
181 const char kHostedAppVersion[] = "1.0.0.0";
182 const char kGoodExtensionID[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
183 const char kGoodExtensionCRXPath[] = "extensions/good.crx";
184 const char kGoodExtensionVersion[] = "1.0";
185 const char kPackagedAppCRXPath[] = "extensions/platform_apps/app_window_2.crx";
186 const char kShowManagedStorageID[] = "ongnjlefhnoajpbodoldndkbkdgfomlp";
187 const char kShowManagedStorageCRXPath[] = "extensions/show_managed_storage.crx";
188 const char kShowManagedStorageVersion[] = "1.0";
190 const char kExternalData[] = "External data";
191 const char kExternalDataURL[] = "http://localhost/external_data";
193 const char* const kSingleRecommendedLocale[] = {
194 "el",
196 const char* const kRecommendedLocales1[] = {
197 "pl",
198 "et",
199 "en-US",
201 const char* const kRecommendedLocales2[] = {
202 "fr",
203 "nl",
205 const char* const kInvalidRecommendedLocale[] = {
206 "xx",
208 const char kPublicSessionLocale[] = "de";
209 const char kPublicSessionInputMethodIDTemplate[] = "_comp_ime_%sxkb:de:neo:ger";
211 // The sequence token used by GetKeyboardLayoutsForLocale() for its background
212 // tasks.
213 const char kSequenceToken[] = "chromeos_login_l10n_util";
215 // Helper that serves extension update manifests to Chrome.
216 class TestingUpdateManifestProvider {
217 public:
218 // Update manifests will be served at |relative_update_url|.
219 explicit TestingUpdateManifestProvider(
220 const std::string& relative_update_url);
221 ~TestingUpdateManifestProvider();
223 // When an update manifest is requested for the given extension |id|, indicate
224 // that |version| of the extension can be downloaded at |crx_url|.
225 void AddUpdate(const std::string& id,
226 const std::string& version,
227 const GURL& crx_url);
229 // This method must be registered with the test's EmbeddedTestServer to start
230 // serving update manifests.
231 scoped_ptr<net::test_server::HttpResponse> HandleRequest(
232 const net::test_server::HttpRequest& request);
234 private:
235 struct Update {
236 public:
237 Update(const std::string& version, const GURL& crx_url);
238 Update();
240 std::string version;
241 GURL crx_url;
243 typedef std::map<std::string, Update> UpdateMap;
244 UpdateMap updates_;
246 const std::string relative_update_url_;
248 DISALLOW_COPY_AND_ASSIGN(TestingUpdateManifestProvider);
251 // Helper that observes the dictionary |pref| in local state and waits until the
252 // value stored for |key| matches |expected_value|.
253 class DictionaryPrefValueWaiter {
254 public:
255 DictionaryPrefValueWaiter(const std::string& pref,
256 const std::string& key,
257 const std::string& expected_value);
258 ~DictionaryPrefValueWaiter();
260 void Wait();
262 private:
263 void QuitLoopIfExpectedValueFound();
265 const std::string pref_;
266 const std::string key_;
267 const std::string expected_value_;
269 base::RunLoop run_loop_;
270 PrefChangeRegistrar pref_change_registrar_;
272 DISALLOW_COPY_AND_ASSIGN(DictionaryPrefValueWaiter);
275 TestingUpdateManifestProvider::Update::Update(const std::string& version,
276 const GURL& crx_url)
277 : version(version),
278 crx_url(crx_url) {
281 TestingUpdateManifestProvider::Update::Update() {
284 TestingUpdateManifestProvider::TestingUpdateManifestProvider(
285 const std::string& relative_update_url)
286 : relative_update_url_(relative_update_url) {
289 TestingUpdateManifestProvider::~TestingUpdateManifestProvider() {
292 void TestingUpdateManifestProvider::AddUpdate(const std::string& id,
293 const std::string& version,
294 const GURL& crx_url) {
295 updates_[id] = Update(version, crx_url);
298 scoped_ptr<net::test_server::HttpResponse>
299 TestingUpdateManifestProvider::HandleRequest(
300 const net::test_server::HttpRequest& request) {
301 const GURL url("http://localhost" + request.relative_url);
302 if (url.path() != relative_update_url_)
303 return scoped_ptr<net::test_server::HttpResponse>();
305 std::string content = kUpdateManifestHeader;
306 for (net::QueryIterator it(url); !it.IsAtEnd(); it.Advance()) {
307 if (it.GetKey() != "x")
308 continue;
309 // Extract the extension id from the subquery. Since GetValueForKeyInQuery()
310 // expects a complete URL, dummy scheme and host must be prepended.
311 std::string id;
312 net::GetValueForKeyInQuery(GURL("http://dummy?" + it.GetUnescapedValue()),
313 "id", &id);
314 UpdateMap::const_iterator entry = updates_.find(id);
315 if (entry != updates_.end()) {
316 content += base::StringPrintf(kUpdateManifestTemplate,
317 id.c_str(),
318 entry->second.crx_url.spec().c_str(),
319 entry->second.version.c_str());
322 content += kUpdateManifestFooter;
323 scoped_ptr<net::test_server::BasicHttpResponse>
324 http_response(new net::test_server::BasicHttpResponse);
325 http_response->set_code(net::HTTP_OK);
326 http_response->set_content(content);
327 http_response->set_content_type("text/xml");
328 return http_response.Pass();
331 DictionaryPrefValueWaiter::DictionaryPrefValueWaiter(
332 const std::string& pref,
333 const std::string& key,
334 const std::string& expected_value)
335 : pref_(pref),
336 key_(key),
337 expected_value_(expected_value) {
338 pref_change_registrar_.Init(g_browser_process->local_state());
341 DictionaryPrefValueWaiter::~DictionaryPrefValueWaiter() {
344 void DictionaryPrefValueWaiter::Wait() {
345 pref_change_registrar_.Add(
346 pref_.c_str(),
347 base::Bind(&DictionaryPrefValueWaiter::QuitLoopIfExpectedValueFound,
348 base::Unretained(this)));
349 QuitLoopIfExpectedValueFound();
350 run_loop_.Run();
353 void DictionaryPrefValueWaiter::QuitLoopIfExpectedValueFound() {
354 const base::DictionaryValue* pref =
355 pref_change_registrar_.prefs()->GetDictionary(pref_.c_str());
356 ASSERT_TRUE(pref);
357 std::string actual_value;
358 if (pref->GetStringWithoutPathExpansion(key_, &actual_value) &&
359 actual_value == expected_value_) {
360 run_loop_.Quit();
364 bool DoesInstallSuccessReferToId(const std::string& id,
365 const content::NotificationSource& source,
366 const content::NotificationDetails& details) {
367 return content::Details<const extensions::InstalledExtensionInfo>(details)->
368 extension->id() == id;
371 bool DoesInstallFailureReferToId(const std::string& id,
372 const content::NotificationSource& source,
373 const content::NotificationDetails& details) {
374 return content::Details<const extensions::CrxInstallError>(details)
375 ->message()
376 .find(base::UTF8ToUTF16(id)) != base::string16::npos;
379 scoped_ptr<net::FakeURLFetcher> RunCallbackAndReturnFakeURLFetcher(
380 scoped_refptr<base::SequencedTaskRunner> task_runner,
381 const base::Closure& callback,
382 const GURL& url,
383 net::URLFetcherDelegate* delegate,
384 const std::string& response_data,
385 net::HttpStatusCode response_code,
386 net::URLRequestStatus::Status status) {
387 task_runner->PostTask(FROM_HERE, callback);
388 return make_scoped_ptr(new net::FakeURLFetcher(
389 url, delegate, response_data, response_code, status));
392 bool IsSessionStarted() {
393 return user_manager::UserManager::Get()->IsSessionStarted();
396 void PolicyChangedCallback(const base::Closure& callback,
397 const base::Value* old_value,
398 const base::Value* new_value) {
399 callback.Run();
402 } // namespace
404 class DeviceLocalAccountTest : public DevicePolicyCrosBrowserTest,
405 public user_manager::UserManager::Observer,
406 public chrome::BrowserListObserver,
407 public extensions::AppWindowRegistry::Observer {
408 protected:
409 DeviceLocalAccountTest()
410 : user_id_1_(GenerateDeviceLocalAccountUserId(
411 kAccountId1, DeviceLocalAccount::TYPE_PUBLIC_SESSION)),
412 user_id_2_(GenerateDeviceLocalAccountUserId(
413 kAccountId2, DeviceLocalAccount::TYPE_PUBLIC_SESSION)),
414 public_session_input_method_id_(base::StringPrintf(
415 kPublicSessionInputMethodIDTemplate,
416 chromeos::extension_ime_util::kXkbExtensionId)),
417 contents_(NULL) {
418 set_exit_when_last_browser_closes(false);
421 ~DeviceLocalAccountTest() override {}
423 void SetUp() override {
424 // Configure and start the test server.
425 scoped_ptr<crypto::RSAPrivateKey> signing_key(
426 PolicyBuilder::CreateTestSigningKey());
427 ASSERT_TRUE(test_server_.SetSigningKeyAndSignature(
428 signing_key.get(), PolicyBuilder::GetTestSigningKeySignature()));
429 signing_key.reset();
430 test_server_.RegisterClient(PolicyBuilder::kFakeToken,
431 PolicyBuilder::kFakeDeviceId);
432 ASSERT_TRUE(test_server_.Start());
434 BrowserList::AddObserver(this);
436 DevicePolicyCrosBrowserTest::SetUp();
439 void SetUpCommandLine(base::CommandLine* command_line) override {
440 DevicePolicyCrosBrowserTest::SetUpCommandLine(command_line);
441 command_line->AppendSwitch(chromeos::switches::kLoginManager);
442 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests);
443 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user");
444 command_line->AppendSwitchASCII(policy::switches::kDeviceManagementUrl,
445 test_server_.GetServiceURL().spec());
448 void SetUpInProcessBrowserTestFixture() override {
449 DevicePolicyCrosBrowserTest::SetUpInProcessBrowserTestFixture();
451 // Clear command-line arguments (but keep command-line switches) so the
452 // startup pages policy takes effect.
453 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
454 base::CommandLine::StringVector argv(command_line->argv());
455 argv.erase(argv.begin() + argv.size() - command_line->GetArgs().size(),
456 argv.end());
457 command_line->InitFromArgv(argv);
459 InstallOwnerKey();
460 MarkAsEnterpriseOwned();
462 InitializePolicy();
465 void SetUpOnMainThread() override {
466 DevicePolicyCrosBrowserTest::SetUpOnMainThread();
468 initial_locale_ = g_browser_process->GetApplicationLocale();
469 initial_language_ = l10n_util::GetLanguage(initial_locale_);
471 content::WindowedNotificationObserver(
472 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
473 content::NotificationService::AllSources()).Wait();
475 chromeos::LoginDisplayHostImpl* host =
476 reinterpret_cast<chromeos::LoginDisplayHostImpl*>(
477 chromeos::LoginDisplayHostImpl::default_host());
478 ASSERT_TRUE(host);
479 chromeos::WebUILoginView* web_ui_login_view = host->GetWebUILoginView();
480 ASSERT_TRUE(web_ui_login_view);
481 content::WebUI* web_ui = web_ui_login_view->GetWebUI();
482 ASSERT_TRUE(web_ui);
483 contents_ = web_ui->GetWebContents();
484 ASSERT_TRUE(contents_);
486 // Wait for the login UI to be ready.
487 chromeos::OobeUI* oobe_ui = host->GetOobeUI();
488 ASSERT_TRUE(oobe_ui);
489 base::RunLoop run_loop;
490 const bool oobe_ui_ready = oobe_ui->IsJSReady(run_loop.QuitClosure());
491 if (!oobe_ui_ready)
492 run_loop.Run();
494 // The network selection screen changes the application locale on load and
495 // once again on blur. Wait for the screen to load and blur it so that any
496 // locale changes caused by this screen happen now and do not affect any
497 // subsequent parts of the test.
498 bool done = false;
499 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
500 contents_,
501 "var languageSelect = document.getElementById('language-select');"
502 "var blurAndReportSuccess = function() {"
503 " languageSelect.blur();"
504 " domAutomationController.send(true);"
505 "};"
506 "var screenLoading = document.getElementById('outer-container')"
507 " .classList.contains('down');"
508 "if (document.activeElement == languageSelect || !screenLoading)"
509 " blurAndReportSuccess();"
510 "else"
511 " languageSelect.addEventListener('focus', blurAndReportSuccess);",
512 &done));
514 // Skip to the login screen.
515 chromeos::WizardController* wizard_controller =
516 chromeos::WizardController::default_controller();
517 ASSERT_TRUE(wizard_controller);
518 wizard_controller->SkipToLoginForTesting(LoginScreenContext());
521 void TearDownOnMainThread() override {
522 BrowserList::RemoveObserver(this);
524 // This shuts down the login UI.
525 base::MessageLoop::current()->PostTask(FROM_HERE,
526 base::Bind(&chrome::AttemptExit));
527 base::RunLoop().RunUntilIdle();
530 void LocalStateChanged(user_manager::UserManager* user_manager) override {
531 if (run_loop_)
532 run_loop_->Quit();
535 void OnBrowserRemoved(Browser* browser) override {
536 if (run_loop_)
537 run_loop_->Quit();
540 void OnAppWindowAdded(extensions::AppWindow* app_window) override {
541 if (run_loop_)
542 run_loop_->Quit();
545 void OnAppWindowRemoved(extensions::AppWindow* app_window) override {
546 if (run_loop_)
547 run_loop_->Quit();
550 void InitializePolicy() {
551 device_policy()->policy_data().set_public_key_version(1);
552 em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
553 proto.mutable_show_user_names()->set_show_user_names(true);
555 device_local_account_policy_.policy_data().set_policy_type(
556 dm_protocol::kChromePublicAccountPolicyType);
557 device_local_account_policy_.policy_data().set_username(kAccountId1);
558 device_local_account_policy_.policy_data().set_settings_entity_id(
559 kAccountId1);
560 device_local_account_policy_.policy_data().set_public_key_version(1);
561 device_local_account_policy_.payload().mutable_userdisplayname()->set_value(
562 kDisplayName1);
565 void BuildDeviceLocalAccountPolicy() {
566 device_local_account_policy_.SetDefaultSigningKey();
567 device_local_account_policy_.Build();
570 void UploadDeviceLocalAccountPolicy() {
571 BuildDeviceLocalAccountPolicy();
572 ASSERT_TRUE(test_server_.UpdatePolicy(
573 dm_protocol::kChromePublicAccountPolicyType, kAccountId1,
574 device_local_account_policy_.payload().SerializeAsString()));
577 void UploadAndInstallDeviceLocalAccountPolicy() {
578 UploadDeviceLocalAccountPolicy();
579 session_manager_client()->set_device_local_account_policy(
580 kAccountId1, device_local_account_policy_.GetBlob());
583 void SetRecommendedLocales(const char* const recommended_locales[],
584 size_t array_size) {
585 em::StringListPolicyProto* session_locales_proto =
586 device_local_account_policy_.payload().mutable_sessionlocales();
587 session_locales_proto->mutable_policy_options()->set_mode(
588 em::PolicyOptions_PolicyMode_RECOMMENDED);
589 session_locales_proto->mutable_value()->Clear();
590 for (size_t i = 0; i < array_size; ++i) {
591 session_locales_proto->mutable_value()->add_entries(
592 recommended_locales[i]);
596 void AddPublicSessionToDevicePolicy(const std::string& username) {
597 em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
598 em::DeviceLocalAccountInfoProto* account =
599 proto.mutable_device_local_accounts()->add_account();
600 account->set_account_id(username);
601 account->set_type(
602 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION);
603 RefreshDevicePolicy();
604 ASSERT_TRUE(test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType,
605 std::string(),
606 proto.SerializeAsString()));
609 void EnableAutoLogin() {
610 em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
611 em::DeviceLocalAccountsProto* device_local_accounts =
612 proto.mutable_device_local_accounts();
613 device_local_accounts->set_auto_login_id(kAccountId1);
614 device_local_accounts->set_auto_login_delay(0);
615 RefreshDevicePolicy();
616 ASSERT_TRUE(test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType,
617 std::string(),
618 proto.SerializeAsString()));
621 void CheckPublicSessionPresent(const std::string& id) {
622 const user_manager::User* user =
623 user_manager::UserManager::Get()->FindUser(id);
624 ASSERT_TRUE(user);
625 EXPECT_EQ(id, user->email());
626 EXPECT_EQ(user_manager::USER_TYPE_PUBLIC_ACCOUNT, user->GetType());
629 base::FilePath GetExtensionCacheDirectoryForAccountID(
630 const std::string& account_id) {
631 base::FilePath extension_cache_root_dir;
632 if (!PathService::Get(chromeos::DIR_DEVICE_LOCAL_ACCOUNT_EXTENSIONS,
633 &extension_cache_root_dir)) {
634 ADD_FAILURE();
636 return extension_cache_root_dir.Append(
637 base::HexEncode(account_id.c_str(), account_id.size()));
640 base::FilePath GetCacheCRXFilePath(const std::string& id,
641 const std::string& version,
642 const base::FilePath& path) {
643 return path.Append(
644 extensions::LocalExtensionCache::ExtensionFileName(id, version, ""));
647 base::FilePath GetCacheCRXFile(const std::string& account_id,
648 const std::string& id,
649 const std::string& version) {
650 return GetCacheCRXFilePath(
651 id, version, GetExtensionCacheDirectoryForAccountID(account_id));
654 // Returns a profile which can be used for testing.
655 Profile* GetProfileForTest() {
656 // Any profile can be used here since this test does not test multi profile.
657 return ProfileManager::GetActiveUserProfile();
660 void WaitForDisplayName(const std::string& user_id,
661 const std::string& expected_display_name) {
662 DictionaryPrefValueWaiter("UserDisplayName",
663 user_id,
664 expected_display_name).Wait();
667 void WaitForPolicy() {
668 // Wait for the display name becoming available as that indicates
669 // device-local account policy is fully loaded, which is a prerequisite for
670 // successful login.
671 WaitForDisplayName(user_id_1_, kDisplayName1);
674 void ExpandPublicSessionPod(bool expect_advanced) {
675 bool advanced = false;
676 // Click on the pod to expand it.
677 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
678 contents_,
679 base::StringPrintf(
680 "var pod ="
681 " document.getElementById('pod-row').getPodWithUsername_('%s');"
682 "pod.click();"
683 "domAutomationController.send(pod.classList.contains('advanced'));",
684 user_id_1_.c_str()),
685 &advanced));
686 // Verify that the pod expanded to its basic/advanced form, as expected.
687 EXPECT_EQ(expect_advanced, advanced);
689 // Verify that the construction of the pod's language list did not affect
690 // the current ICU locale.
691 EXPECT_EQ(initial_language_, icu::Locale::getDefault().getLanguage());
694 // GetKeyboardLayoutsForLocale() posts a task to a background task runner.
695 // This method flushes that task runner and the current thread's message loop
696 // to ensure that GetKeyboardLayoutsForLocale() is finished.
697 void WaitForGetKeyboardLayoutsForLocaleToFinish() {
698 base::SequencedWorkerPool* worker_pool =
699 content::BrowserThread::GetBlockingPool();
700 scoped_refptr<base::SequencedTaskRunner> background_task_runner =
701 worker_pool->GetSequencedTaskRunner(
702 worker_pool->GetNamedSequenceToken(kSequenceToken));
703 base::RunLoop run_loop;
704 background_task_runner->PostTaskAndReply(FROM_HERE,
705 base::Bind(&base::DoNothing),
706 run_loop.QuitClosure());
707 run_loop.Run();
708 base::RunLoop().RunUntilIdle();
710 // Verify that the construction of the keyboard layout list did not affect
711 // the current ICU locale.
712 EXPECT_EQ(initial_language_, icu::Locale::getDefault().getLanguage());
715 void StartLogin(const std::string& locale,
716 const std::string& input_method) {
717 // Start login into the device-local account.
718 chromeos::LoginDisplayHostImpl* host =
719 reinterpret_cast<chromeos::LoginDisplayHostImpl*>(
720 chromeos::LoginDisplayHostImpl::default_host());
721 ASSERT_TRUE(host);
722 host->StartSignInScreen(LoginScreenContext());
723 chromeos::ExistingUserController* controller =
724 chromeos::ExistingUserController::current_controller();
725 ASSERT_TRUE(controller);
727 chromeos::UserContext user_context(user_manager::USER_TYPE_PUBLIC_ACCOUNT,
728 user_id_1_);
729 user_context.SetPublicSessionLocale(locale);
730 user_context.SetPublicSessionInputMethod(input_method);
731 controller->Login(user_context, chromeos::SigninSpecifics());
734 void WaitForSessionStart() {
735 if (IsSessionStarted())
736 return;
737 content::WindowedNotificationObserver(chrome::NOTIFICATION_SESSION_STARTED,
738 base::Bind(IsSessionStarted)).Wait();
741 void VerifyKeyboardLayoutMatchesLocale() {
742 chromeos::input_method::InputMethodManager* input_method_manager =
743 chromeos::input_method::InputMethodManager::Get();
744 std::vector<std::string> layouts_from_locale;
745 input_method_manager->GetInputMethodUtil()->
746 GetInputMethodIdsFromLanguageCode(
747 g_browser_process->GetApplicationLocale(),
748 chromeos::input_method::kKeyboardLayoutsOnly,
749 &layouts_from_locale);
750 ASSERT_FALSE(layouts_from_locale.empty());
751 EXPECT_EQ(layouts_from_locale.front(),
752 input_method_manager->GetActiveIMEState()
753 ->GetCurrentInputMethod()
754 .id());
757 const std::string user_id_1_;
758 const std::string user_id_2_;
759 const std::string public_session_input_method_id_;
761 std::string initial_locale_;
762 std::string initial_language_;
764 scoped_ptr<base::RunLoop> run_loop_;
766 UserPolicyBuilder device_local_account_policy_;
767 LocalPolicyTestServer test_server_;
769 content::WebContents* contents_;
771 private:
772 DISALLOW_COPY_AND_ASSIGN(DeviceLocalAccountTest);
775 static bool IsKnownUser(const std::string& account_id) {
776 return user_manager::UserManager::Get()->IsKnownUser(account_id);
779 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) {
780 AddPublicSessionToDevicePolicy(kAccountId1);
781 AddPublicSessionToDevicePolicy(kAccountId2);
783 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED,
784 base::Bind(&IsKnownUser, user_id_1_))
785 .Wait();
786 EXPECT_TRUE(IsKnownUser(user_id_2_));
788 CheckPublicSessionPresent(user_id_1_);
789 CheckPublicSessionPresent(user_id_2_);
792 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) {
793 UploadAndInstallDeviceLocalAccountPolicy();
794 AddPublicSessionToDevicePolicy(kAccountId1);
796 WaitForPolicy();
798 // Verify that the display name is shown in the UI.
799 const std::string get_compact_pod_display_name = base::StringPrintf(
800 "domAutomationController.send(document.getElementById('pod-row')"
801 " .getPodWithUsername_('%s').nameElement.textContent);",
802 user_id_1_.c_str());
803 std::string display_name;
804 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
805 contents_,
806 get_compact_pod_display_name,
807 &display_name));
808 EXPECT_EQ(kDisplayName1, display_name);
809 const std::string get_expanded_pod_display_name = base::StringPrintf(
810 "domAutomationController.send(document.getElementById('pod-row')"
811 " .getPodWithUsername_('%s').querySelector('.expanded-pane-name')"
812 " .textContent);",
813 user_id_1_.c_str());
814 display_name.clear();
815 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
816 contents_,
817 get_expanded_pod_display_name,
818 &display_name));
819 EXPECT_EQ(kDisplayName1, display_name);
821 // Click on the pod to expand it.
822 ASSERT_TRUE(content::ExecuteScript(
823 contents_,
824 base::StringPrintf(
825 "document.getElementById('pod-row').getPodWithUsername_('%s')"
826 " .click();",
827 user_id_1_.c_str())));
829 // Change the display name.
830 device_local_account_policy_.payload().mutable_userdisplayname()->set_value(
831 kDisplayName2);
832 UploadAndInstallDeviceLocalAccountPolicy();
833 policy::BrowserPolicyConnectorChromeOS* connector =
834 g_browser_process->platform_part()->browser_policy_connector_chromeos();
835 DeviceLocalAccountPolicyBroker* broker =
836 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
837 user_id_1_);
838 ASSERT_TRUE(broker);
839 broker->core()->store()->Load();
840 WaitForDisplayName(user_id_1_, kDisplayName2);
842 // Verify that the new display name is shown in the UI.
843 display_name.clear();
844 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
845 contents_,
846 get_compact_pod_display_name,
847 &display_name));
848 EXPECT_EQ(kDisplayName2, display_name);
849 display_name.clear();
850 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
851 contents_,
852 get_expanded_pod_display_name,
853 &display_name));
854 EXPECT_EQ(kDisplayName2, display_name);
856 // Verify that the pod is still expanded. This indicates that the UI updated
857 // without reloading and losing state.
858 bool expanded = false;
859 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
860 contents_,
861 base::StringPrintf(
862 "domAutomationController.send(document.getElementById('pod-row')"
863 " .getPodWithUsername_('%s').expanded);",
864 user_id_1_.c_str()),
865 &expanded));
866 EXPECT_TRUE(expanded);
869 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, PolicyDownload) {
870 UploadDeviceLocalAccountPolicy();
871 AddPublicSessionToDevicePolicy(kAccountId1);
873 WaitForPolicy();
875 // Sanity check: The policy should be present now.
876 ASSERT_FALSE(session_manager_client()->device_local_account_policy(
877 kAccountId1).empty());
880 static bool IsNotKnownUser(const std::string& account_id) {
881 return !IsKnownUser(account_id);
884 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, AccountListChange) {
885 AddPublicSessionToDevicePolicy(kAccountId1);
886 AddPublicSessionToDevicePolicy(kAccountId2);
888 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED,
889 base::Bind(&IsKnownUser, user_id_1_))
890 .Wait();
891 EXPECT_TRUE(IsKnownUser(user_id_2_));
893 // Update policy to remove kAccountId2.
894 em::ChromeDeviceSettingsProto& proto(device_policy()->payload());
895 proto.mutable_device_local_accounts()->clear_account();
896 AddPublicSessionToDevicePolicy(kAccountId1);
898 em::ChromeDeviceSettingsProto policy;
899 policy.mutable_show_user_names()->set_show_user_names(true);
900 em::DeviceLocalAccountInfoProto* account1 =
901 policy.mutable_device_local_accounts()->add_account();
902 account1->set_account_id(kAccountId1);
903 account1->set_type(
904 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_PUBLIC_SESSION);
906 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, std::string(),
907 policy.SerializeAsString());
908 g_browser_process->policy_service()->RefreshPolicies(base::Closure());
910 // Make sure the second device-local account disappears.
911 content::WindowedNotificationObserver(chrome::NOTIFICATION_USER_LIST_CHANGED,
912 base::Bind(&IsNotKnownUser, user_id_2_))
913 .Wait();
916 // Test fails under MSan, http://crbug.com/446950
917 #if defined(MEMORY_SANITIZER)
918 #define MAYBE_StartSession DISABLED_StartSession
919 #else
920 #define MAYBE_StartSession StartSession
921 #endif
923 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, MAYBE_StartSession) {
924 // Specify startup pages.
925 device_local_account_policy_.payload().mutable_restoreonstartup()->set_value(
926 SessionStartupPref::kPrefValueURLs);
927 em::StringListPolicyProto* startup_urls_proto =
928 device_local_account_policy_.payload().mutable_restoreonstartupurls();
929 for (size_t i = 0; i < arraysize(kStartupURLs); ++i)
930 startup_urls_proto->mutable_value()->add_entries(kStartupURLs[i]);
931 UploadAndInstallDeviceLocalAccountPolicy();
932 AddPublicSessionToDevicePolicy(kAccountId1);
934 WaitForPolicy();
936 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
937 WaitForSessionStart();
939 // Check that the startup pages specified in policy were opened.
940 BrowserList* browser_list =
941 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
942 EXPECT_EQ(1U, browser_list->size());
943 Browser* browser = browser_list->get(0);
944 ASSERT_TRUE(browser);
946 TabStripModel* tabs = browser->tab_strip_model();
947 ASSERT_TRUE(tabs);
948 int expected_tab_count = static_cast<int>(arraysize(kStartupURLs));
949 EXPECT_EQ(expected_tab_count, tabs->count());
950 for (int i = 0; i < expected_tab_count && i < tabs->count(); ++i) {
951 EXPECT_EQ(GURL(kStartupURLs[i]),
952 tabs->GetWebContentsAt(i)->GetVisibleURL());
955 // Verify that the session is not considered to be logged in with a GAIA
956 // account.
957 Profile* profile = GetProfileForTest();
958 ASSERT_TRUE(profile);
959 EXPECT_FALSE(
960 SigninManagerFactory::GetForProfile(profile)->IsAuthenticated());
963 // Test fails under MSan, http://crbug.com/446950
964 #if defined(MEMORY_SANITIZER)
965 #define MAYBE_FullscreenDisallowed DISABLED_FullscreenDisallowed
966 #else
967 #define MAYBE_FullscreenDisallowed FullscreenDisallowed
968 #endif
970 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, MAYBE_FullscreenDisallowed) {
971 UploadAndInstallDeviceLocalAccountPolicy();
972 AddPublicSessionToDevicePolicy(kAccountId1);
974 WaitForPolicy();
976 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
977 WaitForSessionStart();
979 BrowserList* browser_list =
980 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
981 EXPECT_EQ(1U, browser_list->size());
982 Browser* browser = browser_list->get(0);
983 ASSERT_TRUE(browser);
984 BrowserWindow* browser_window = browser->window();
985 ASSERT_TRUE(browser_window);
987 // Verify that an attempt to enter fullscreen mode is denied.
988 EXPECT_FALSE(browser_window->IsFullscreen());
989 chrome::ToggleFullscreenMode(browser);
990 EXPECT_FALSE(browser_window->IsFullscreen());
993 // Test fails under MSan, http://crbug.com/446950
994 #if defined(MEMORY_SANITIZER)
995 #define MAYBE_ExtensionsUncached DISABLED_ExtensionsUncached
996 #else
997 #define MAYBE_ExtensionsUncached ExtensionsUncached
998 #endif
1000 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, MAYBE_ExtensionsUncached) {
1001 // Make it possible to force-install a hosted app and an extension.
1002 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
1003 TestingUpdateManifestProvider testing_update_manifest_provider(
1004 kRelativeUpdateURL);
1005 testing_update_manifest_provider.AddUpdate(
1006 kHostedAppID,
1007 kHostedAppVersion,
1008 embedded_test_server()->GetURL(std::string("/") + kHostedAppCRXPath));
1009 testing_update_manifest_provider.AddUpdate(
1010 kGoodExtensionID,
1011 kGoodExtensionVersion,
1012 embedded_test_server()->GetURL(std::string("/") + kGoodExtensionCRXPath));
1013 embedded_test_server()->RegisterRequestHandler(
1014 base::Bind(&TestingUpdateManifestProvider::HandleRequest,
1015 base::Unretained(&testing_update_manifest_provider)));
1017 // Specify policy to force-install the hosted app and the extension.
1018 em::StringList* forcelist = device_local_account_policy_.payload()
1019 .mutable_extensioninstallforcelist()->mutable_value();
1020 forcelist->add_entries(base::StringPrintf(
1021 "%s;%s",
1022 kHostedAppID,
1023 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str()));
1024 forcelist->add_entries(base::StringPrintf(
1025 "%s;%s",
1026 kGoodExtensionID,
1027 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str()));
1029 UploadAndInstallDeviceLocalAccountPolicy();
1030 AddPublicSessionToDevicePolicy(kAccountId1);
1032 WaitForPolicy();
1034 // Start listening for app/extension installation results.
1035 content::WindowedNotificationObserver hosted_app_observer(
1036 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
1037 base::Bind(DoesInstallSuccessReferToId, kHostedAppID));
1038 content::WindowedNotificationObserver extension_observer(
1039 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR,
1040 base::Bind(DoesInstallFailureReferToId, kGoodExtensionID));
1042 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
1044 // Wait for the hosted app installation to succeed and the extension
1045 // installation to fail (because hosted apps are whitelisted for use in
1046 // device-local accounts and extensions are not).
1047 hosted_app_observer.Wait();
1048 extension_observer.Wait();
1050 // Verify that the hosted app was installed.
1051 Profile* profile = GetProfileForTest();
1052 ASSERT_TRUE(profile);
1053 ExtensionService* extension_service =
1054 extensions::ExtensionSystem::Get(profile)->extension_service();
1055 EXPECT_TRUE(extension_service->GetExtensionById(kHostedAppID, true));
1057 // Verify that the extension was not installed.
1058 EXPECT_FALSE(extension_service->GetExtensionById(kGoodExtensionID, true));
1060 // Verify that the app was downloaded to the account's extension cache.
1061 base::FilePath test_dir;
1062 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
1063 EXPECT_TRUE(ContentsEqual(
1064 GetCacheCRXFile(kAccountId1, kHostedAppID, kHostedAppVersion),
1065 test_dir.Append(kHostedAppCRXPath)));
1067 // Verify that the extension was removed from the account's extension cache
1068 // after the installation failure.
1069 DeviceLocalAccountPolicyBroker* broker =
1070 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
1071 GetDeviceLocalAccountPolicyService()->GetBrokerForUser(user_id_1_);
1072 ASSERT_TRUE(broker);
1073 chromeos::ExternalCache* cache =
1074 broker->extension_loader()->GetExternalCacheForTesting();
1075 ASSERT_TRUE(cache);
1076 EXPECT_FALSE(cache->GetExtension(kGoodExtensionID, NULL, NULL));
1079 // Test fails under MSan, http://crbug.com/446950
1080 #if defined(MEMORY_SANITIZER)
1081 #define MAYBE_ExtensionsCached DISABLED_ExtensionsCached
1082 #else
1083 #define MAYBE_ExtensionsCached ExtensionsCached
1084 #endif
1086 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, MAYBE_ExtensionsCached) {
1087 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
1089 // Pre-populate the device local account's extension cache with a hosted app
1090 // and an extension.
1091 EXPECT_TRUE(base::CreateDirectory(
1092 GetExtensionCacheDirectoryForAccountID(kAccountId1)));
1093 base::FilePath test_dir;
1094 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
1095 const base::FilePath cached_hosted_app =
1096 GetCacheCRXFile(kAccountId1, kHostedAppID, kHostedAppVersion);
1097 EXPECT_TRUE(CopyFile(test_dir.Append(kHostedAppCRXPath),
1098 cached_hosted_app));
1099 EXPECT_TRUE(CopyFile(
1100 test_dir.Append(kGoodExtensionCRXPath),
1101 GetCacheCRXFile(kAccountId1, kGoodExtensionID, kGoodExtensionVersion)));
1103 // Specify policy to force-install the hosted app.
1104 em::StringList* forcelist = device_local_account_policy_.payload()
1105 .mutable_extensioninstallforcelist()->mutable_value();
1106 forcelist->add_entries(base::StringPrintf(
1107 "%s;%s",
1108 kHostedAppID,
1109 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str()));
1110 forcelist->add_entries(base::StringPrintf(
1111 "%s;%s",
1112 kGoodExtensionID,
1113 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str()));
1115 UploadAndInstallDeviceLocalAccountPolicy();
1116 AddPublicSessionToDevicePolicy(kAccountId1);
1118 WaitForPolicy();
1120 // Start listening for app/extension installation results.
1121 content::WindowedNotificationObserver hosted_app_observer(
1122 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
1123 base::Bind(DoesInstallSuccessReferToId, kHostedAppID));
1124 content::WindowedNotificationObserver extension_observer(
1125 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR,
1126 base::Bind(DoesInstallFailureReferToId, kGoodExtensionID));
1128 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
1130 // Wait for the hosted app installation to succeed and the extension
1131 // installation to fail.
1132 hosted_app_observer.Wait();
1133 extension_observer.Wait();
1135 // Verify that the hosted app was installed.
1136 Profile* profile = GetProfileForTest();
1137 ASSERT_TRUE(profile);
1138 ExtensionService* extension_service =
1139 extensions::ExtensionSystem::Get(profile)->extension_service();
1140 EXPECT_TRUE(extension_service->GetExtensionById(kHostedAppID, true));
1142 // Verify that the extension was not installed.
1143 EXPECT_FALSE(extension_service->GetExtensionById(kGoodExtensionID, true));
1145 // Verify that the app is still in the account's extension cache.
1146 EXPECT_TRUE(PathExists(cached_hosted_app));
1148 // Verify that the extension was removed from the account's extension cache.
1149 DeviceLocalAccountPolicyBroker* broker =
1150 g_browser_process->platform_part()->browser_policy_connector_chromeos()->
1151 GetDeviceLocalAccountPolicyService()->GetBrokerForUser(user_id_1_);
1152 ASSERT_TRUE(broker);
1153 chromeos::ExternalCache* cache =
1154 broker->extension_loader()->GetExternalCacheForTesting();
1155 ASSERT_TRUE(cache);
1156 EXPECT_FALSE(cache->GetExtension(kGoodExtensionID, NULL, NULL));
1159 static void OnPutExtension(scoped_ptr<base::RunLoop>* run_loop,
1160 const base::FilePath& file_path,
1161 bool file_ownership_passed) {
1162 ASSERT_TRUE(*run_loop);
1163 (*run_loop)->Quit();
1166 static void OnExtensionCacheImplInitialized(
1167 scoped_ptr<base::RunLoop>* run_loop) {
1168 ASSERT_TRUE(*run_loop);
1169 (*run_loop)->Quit();
1172 static void CreateFile(const base::FilePath& file,
1173 size_t size,
1174 const base::Time& timestamp) {
1175 std::string data(size, 0);
1176 EXPECT_EQ(base::WriteFile(file, data.data(), data.size()), int(size));
1177 EXPECT_TRUE(base::TouchFile(file, timestamp, timestamp));
1180 // Test fails under MSan, http://crbug.com/446950
1181 #if defined(MEMORY_SANITIZER)
1182 #define MAYBE_ExtensionCacheImplTest DISABLED_ExtensionCacheImplTest
1183 #else
1184 #define MAYBE_ExtensionCacheImplTest ExtensionCacheImplTest
1185 #endif
1187 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, MAYBE_ExtensionCacheImplTest) {
1188 // Make it possible to force-install a hosted app and an extension.
1189 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
1190 TestingUpdateManifestProvider testing_update_manifest_provider(
1191 kRelativeUpdateURL);
1192 testing_update_manifest_provider.AddUpdate(
1193 kHostedAppID,
1194 kHostedAppVersion,
1195 embedded_test_server()->GetURL(std::string("/") + kHostedAppCRXPath));
1196 testing_update_manifest_provider.AddUpdate(
1197 kGoodExtensionID,
1198 kGoodExtensionVersion,
1199 embedded_test_server()->GetURL(std::string("/") + kGoodExtensionCRXPath));
1200 embedded_test_server()->RegisterRequestHandler(
1201 base::Bind(&TestingUpdateManifestProvider::HandleRequest,
1202 base::Unretained(&testing_update_manifest_provider)));
1204 // Create and initialize local cache.
1205 base::ScopedTempDir cache_dir;
1206 EXPECT_TRUE(cache_dir.CreateUniqueTempDir());
1207 const base::FilePath impl_path = cache_dir.path();
1208 EXPECT_TRUE(base::CreateDirectory(impl_path));
1209 CreateFile(impl_path.Append(
1210 extensions::LocalExtensionCache::kCacheReadyFlagFileName),
1211 0, base::Time::Now());
1212 extensions::ExtensionCacheImpl cache_impl(make_scoped_ptr(
1213 new extensions::ChromeOSExtensionCacheDelegate(impl_path)));
1214 scoped_ptr<base::RunLoop> run_loop;
1215 run_loop.reset(new base::RunLoop);
1216 cache_impl.Start(base::Bind(&OnExtensionCacheImplInitialized, &run_loop));
1217 run_loop->Run();
1219 // Put extension in the local cache.
1220 base::ScopedTempDir temp_dir;
1221 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
1222 const base::FilePath temp_path = temp_dir.path();
1223 EXPECT_TRUE(base::CreateDirectory(temp_path));
1224 const base::FilePath temp_file =
1225 GetCacheCRXFilePath(kGoodExtensionID, kGoodExtensionVersion, temp_path);
1226 base::FilePath test_dir;
1227 std::string hash;
1228 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
1229 EXPECT_TRUE(CopyFile(test_dir.Append(kGoodExtensionCRXPath), temp_file));
1230 cache_impl.AllowCaching(kGoodExtensionID);
1231 run_loop.reset(new base::RunLoop);
1232 cache_impl.PutExtension(kGoodExtensionID, hash, temp_file,
1233 kGoodExtensionVersion,
1234 base::Bind(&OnPutExtension, &run_loop));
1235 run_loop->Run();
1237 // Verify that the extension file was added to the local cache.
1238 const base::FilePath local_file =
1239 GetCacheCRXFilePath(kGoodExtensionID, kGoodExtensionVersion, impl_path);
1240 EXPECT_TRUE(PathExists(local_file));
1242 // Specify policy to force-install the hosted app and the extension.
1243 em::StringList* forcelist = device_local_account_policy_.payload()
1244 .mutable_extensioninstallforcelist()->mutable_value();
1245 forcelist->add_entries(base::StringPrintf(
1246 "%s;%s",
1247 kHostedAppID,
1248 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str()));
1249 forcelist->add_entries(base::StringPrintf(
1250 "%s;%s",
1251 kGoodExtensionID,
1252 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str()));
1254 UploadAndInstallDeviceLocalAccountPolicy();
1255 AddPublicSessionToDevicePolicy(kAccountId1);
1257 WaitForPolicy();
1259 // Start listening for app/extension installation results.
1260 content::WindowedNotificationObserver hosted_app_observer(
1261 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
1262 base::Bind(DoesInstallSuccessReferToId, kHostedAppID));
1263 content::WindowedNotificationObserver extension_observer(
1264 extensions::NOTIFICATION_EXTENSION_INSTALL_ERROR,
1265 base::Bind(DoesInstallFailureReferToId, kGoodExtensionID));
1267 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
1269 // Wait for the hosted app installation to succeed and the extension
1270 // installation to fail (because hosted apps are whitelisted for use in
1271 // device-local accounts and extensions are not).
1272 hosted_app_observer.Wait();
1273 extension_observer.Wait();
1275 // Verify that the extension was kept in the local cache.
1276 EXPECT_TRUE(cache_impl.GetExtension(kGoodExtensionID, hash, NULL, NULL));
1278 // Verify that the extension file was kept in the local cache.
1279 EXPECT_TRUE(PathExists(local_file));
1282 // Test fails under MSan, http://crbug.com/446950
1283 #if defined(MEMORY_SANITIZER)
1284 #define MAYBE_ExternalData DISABLED_ExternalData
1285 #else
1286 #define MAYBE_ExternalData ExternalData
1287 #endif
1289 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, MAYBE_ExternalData) {
1290 // user_manager::UserManager requests an external data fetch whenever
1291 // the key::kUserAvatarImage policy is set. Since this test wants to
1292 // verify that the underlying policy subsystem will start a fetch
1293 // without this request as well, the user_manager::UserManager must be
1294 // prevented from seeing the policy change.
1295 reinterpret_cast<chromeos::ChromeUserManagerImpl*>(
1296 user_manager::UserManager::Get())->StopPolicyObserverForTesting();
1298 UploadDeviceLocalAccountPolicy();
1299 AddPublicSessionToDevicePolicy(kAccountId1);
1301 WaitForPolicy();
1303 // Start serving external data at |kExternalDataURL|.
1304 scoped_ptr<base::RunLoop> run_loop(new base::RunLoop);
1305 scoped_ptr<net::FakeURLFetcherFactory> fetcher_factory(
1306 new net::FakeURLFetcherFactory(
1307 NULL,
1308 base::Bind(&RunCallbackAndReturnFakeURLFetcher,
1309 base::MessageLoopProxy::current(),
1310 run_loop->QuitClosure())));
1311 fetcher_factory->SetFakeResponse(GURL(kExternalDataURL),
1312 kExternalData,
1313 net::HTTP_OK,
1314 net::URLRequestStatus::SUCCESS);
1316 // Specify an external data reference for the key::kUserAvatarImage policy.
1317 scoped_ptr<base::DictionaryValue> metadata =
1318 test::ConstructExternalDataReference(kExternalDataURL, kExternalData);
1319 std::string policy;
1320 base::JSONWriter::Write(metadata.get(), &policy);
1321 device_local_account_policy_.payload().mutable_useravatarimage()->set_value(
1322 policy);
1323 UploadAndInstallDeviceLocalAccountPolicy();
1324 policy::BrowserPolicyConnectorChromeOS* connector =
1325 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1326 DeviceLocalAccountPolicyBroker* broker =
1327 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
1328 user_id_1_);
1329 ASSERT_TRUE(broker);
1330 broker->core()->store()->Load();
1332 // The external data should be fetched and cached automatically. Wait for this
1333 // fetch.
1334 run_loop->Run();
1336 // Stop serving external data at |kExternalDataURL|.
1337 fetcher_factory.reset();
1339 const PolicyMap::Entry* policy_entry =
1340 broker->core()->store()->policy_map().Get(key::kUserAvatarImage);
1341 ASSERT_TRUE(policy_entry);
1342 ASSERT_TRUE(policy_entry->external_data_fetcher);
1344 // Retrieve the external data. Although the data is no longer being served at
1345 // |kExternalDataURL|, the retrieval should succeed because the data has been
1346 // cached.
1347 run_loop.reset(new base::RunLoop);
1348 scoped_ptr<std::string> fetched_external_data;
1349 policy_entry->external_data_fetcher->Fetch(base::Bind(
1350 &test::ExternalDataFetchCallback,
1351 &fetched_external_data,
1352 run_loop->QuitClosure()));
1353 run_loop->Run();
1355 ASSERT_TRUE(fetched_external_data);
1356 EXPECT_EQ(kExternalData, *fetched_external_data);
1358 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
1359 WaitForSessionStart();
1361 // Verify that the external data reference has propagated to the device-local
1362 // account's ProfilePolicyConnector.
1363 ProfilePolicyConnector* policy_connector =
1364 ProfilePolicyConnectorFactory::GetForBrowserContext(GetProfileForTest());
1365 ASSERT_TRUE(policy_connector);
1366 const PolicyMap& policies = policy_connector->policy_service()->GetPolicies(
1367 PolicyNamespace(POLICY_DOMAIN_CHROME, std::string()));
1368 policy_entry = policies.Get(key::kUserAvatarImage);
1369 ASSERT_TRUE(policy_entry);
1370 EXPECT_TRUE(base::Value::Equals(metadata.get(), policy_entry->value));
1371 ASSERT_TRUE(policy_entry->external_data_fetcher);
1373 // Retrieve the external data via the ProfilePolicyConnector. The retrieval
1374 // should succeed because the data has been cached.
1375 run_loop.reset(new base::RunLoop);
1376 fetched_external_data.reset();
1377 policy_entry->external_data_fetcher->Fetch(base::Bind(
1378 &test::ExternalDataFetchCallback,
1379 &fetched_external_data,
1380 run_loop->QuitClosure()));
1381 run_loop->Run();
1383 ASSERT_TRUE(fetched_external_data);
1384 EXPECT_EQ(kExternalData, *fetched_external_data);
1387 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, UserAvatarImage) {
1388 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
1390 UploadDeviceLocalAccountPolicy();
1391 AddPublicSessionToDevicePolicy(kAccountId1);
1393 WaitForPolicy();
1395 base::FilePath test_dir;
1396 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
1397 std::string image_data;
1398 ASSERT_TRUE(base::ReadFileToString(
1399 test_dir.Append(chromeos::test::kUserAvatarImage1RelativePath),
1400 &image_data));
1402 std::string policy;
1403 base::JSONWriter::Write(test::ConstructExternalDataReference(
1404 embedded_test_server()->GetURL(std::string("/") +
1405 chromeos::test::kUserAvatarImage1RelativePath).spec(),
1406 image_data).get(),
1407 &policy);
1408 device_local_account_policy_.payload().mutable_useravatarimage()->set_value(
1409 policy);
1410 UploadAndInstallDeviceLocalAccountPolicy();
1411 policy::BrowserPolicyConnectorChromeOS* connector =
1412 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1413 DeviceLocalAccountPolicyBroker* broker =
1414 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
1415 user_id_1_);
1416 ASSERT_TRUE(broker);
1418 run_loop_.reset(new base::RunLoop);
1419 user_manager::UserManager::Get()->AddObserver(this);
1420 broker->core()->store()->Load();
1421 run_loop_->Run();
1422 user_manager::UserManager::Get()->RemoveObserver(this);
1424 scoped_ptr<gfx::ImageSkia> policy_image = chromeos::test::ImageLoader(
1425 test_dir.Append(chromeos::test::kUserAvatarImage1RelativePath)).Load();
1426 ASSERT_TRUE(policy_image);
1428 const user_manager::User* user =
1429 user_manager::UserManager::Get()->FindUser(user_id_1_);
1430 ASSERT_TRUE(user);
1432 base::FilePath user_data_dir;
1433 ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &user_data_dir));
1434 const base::FilePath saved_image_path =
1435 user_data_dir.Append(user_id_1_).AddExtension("jpg");
1437 EXPECT_FALSE(user->HasDefaultImage());
1438 EXPECT_EQ(user_manager::User::USER_IMAGE_EXTERNAL, user->image_index());
1439 EXPECT_TRUE(chromeos::test::AreImagesEqual(*policy_image, user->GetImage()));
1440 const base::DictionaryValue* images_pref =
1441 g_browser_process->local_state()->GetDictionary("user_image_info");
1442 ASSERT_TRUE(images_pref);
1443 const base::DictionaryValue* image_properties;
1444 ASSERT_TRUE(images_pref->GetDictionaryWithoutPathExpansion(
1445 user_id_1_,
1446 &image_properties));
1447 int image_index;
1448 std::string image_path;
1449 ASSERT_TRUE(image_properties->GetInteger("index", &image_index));
1450 ASSERT_TRUE(image_properties->GetString("path", &image_path));
1451 EXPECT_EQ(user_manager::User::USER_IMAGE_EXTERNAL, image_index);
1452 EXPECT_EQ(saved_image_path.value(), image_path);
1454 scoped_ptr<gfx::ImageSkia> saved_image =
1455 chromeos::test::ImageLoader(saved_image_path).Load();
1456 ASSERT_TRUE(saved_image);
1458 // Check image dimensions. Images can't be compared since JPEG is lossy.
1459 EXPECT_EQ(policy_image->width(), saved_image->width());
1460 EXPECT_EQ(policy_image->height(), saved_image->height());
1463 // Test fails under MSan, http://crbug.com/446950
1464 #if defined(MEMORY_SANITIZER)
1465 #define MAYBE_LastWindowClosedLogoutReminder \
1466 DISABLED_LastWindowClosedLogoutReminder
1467 #else
1468 #define MAYBE_LastWindowClosedLogoutReminder LastWindowClosedLogoutReminder
1469 #endif
1471 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest,
1472 MAYBE_LastWindowClosedLogoutReminder) {
1473 UploadAndInstallDeviceLocalAccountPolicy();
1474 AddPublicSessionToDevicePolicy(kAccountId1);
1476 WaitForPolicy();
1478 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
1479 WaitForSessionStart();
1481 Profile* profile = GetProfileForTest();
1482 ASSERT_TRUE(profile);
1483 extensions::AppWindowRegistry* app_window_registry =
1484 extensions::AppWindowRegistry::Get(profile);
1485 app_window_registry->AddObserver(this);
1487 // Verify that the logout confirmation dialog is not showing.
1488 ash::LogoutConfirmationController* logout_confirmation_controller =
1489 ash::Shell::GetInstance()->logout_confirmation_controller();
1490 ASSERT_TRUE(logout_confirmation_controller);
1491 EXPECT_FALSE(logout_confirmation_controller->dialog_for_testing());
1493 // Remove policy that allows only explicitly whitelisted apps to be installed
1494 // in a public session.
1495 extensions::ExtensionSystem* extension_system =
1496 extensions::ExtensionSystem::Get(profile);
1497 ASSERT_TRUE(extension_system);
1498 extension_system->management_policy()->UnregisterAllProviders();
1500 // Install and a platform app.
1501 scoped_refptr<extensions::CrxInstaller> installer =
1502 extensions::CrxInstaller::CreateSilent(
1503 extension_system->extension_service());
1504 installer->set_allow_silent_install(true);
1505 installer->set_install_cause(extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);
1506 installer->set_creation_flags(extensions::Extension::FROM_WEBSTORE);
1507 content::WindowedNotificationObserver app_install_observer(
1508 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1509 content::NotificationService::AllSources());
1510 base::FilePath test_dir;
1511 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
1512 installer->InstallCrx(test_dir.Append(kPackagedAppCRXPath));
1513 app_install_observer.Wait();
1514 const extensions::Extension* app =
1515 content::Details<const extensions::Extension>(
1516 app_install_observer.details()).ptr();
1518 // Start the platform app, causing it to open a window.
1519 run_loop_.reset(new base::RunLoop);
1520 OpenApplication(AppLaunchParams(profile, app,
1521 extensions::LAUNCH_CONTAINER_NONE, NEW_WINDOW,
1522 extensions::SOURCE_TEST));
1523 run_loop_->Run();
1524 EXPECT_EQ(1U, app_window_registry->app_windows().size());
1526 // Close the only open browser window.
1527 BrowserList* browser_list =
1528 BrowserList::GetInstance(chrome::HOST_DESKTOP_TYPE_ASH);
1529 EXPECT_EQ(1U, browser_list->size());
1530 Browser* browser = browser_list->get(0);
1531 ASSERT_TRUE(browser);
1532 BrowserWindow* browser_window = browser->window();
1533 ASSERT_TRUE(browser_window);
1534 run_loop_.reset(new base::RunLoop);
1535 browser_window->Close();
1536 browser_window = NULL;
1537 run_loop_->Run();
1538 browser = NULL;
1539 EXPECT_TRUE(browser_list->empty());
1541 // Verify that the logout confirmation dialog is not showing because an app
1542 // window is still open.
1543 EXPECT_FALSE(logout_confirmation_controller->dialog_for_testing());
1545 // Open a browser window.
1546 Browser* first_browser = CreateBrowser(profile);
1547 EXPECT_EQ(1U, browser_list->size());
1549 // Close the app window.
1550 run_loop_.reset(new base::RunLoop);
1551 ASSERT_EQ(1U, app_window_registry->app_windows().size());
1552 app_window_registry->app_windows().front()->GetBaseWindow()->Close();
1553 run_loop_->Run();
1554 EXPECT_TRUE(app_window_registry->app_windows().empty());
1556 // Verify that the logout confirmation dialog is not showing because a browser
1557 // window is still open.
1558 EXPECT_FALSE(logout_confirmation_controller->dialog_for_testing());
1560 // Open a second browser window.
1561 Browser* second_browser = CreateBrowser(profile);
1562 EXPECT_EQ(2U, browser_list->size());
1564 // Close the first browser window.
1565 browser_window = first_browser->window();
1566 ASSERT_TRUE(browser_window);
1567 run_loop_.reset(new base::RunLoop);
1568 browser_window->Close();
1569 browser_window = NULL;
1570 run_loop_->Run();
1571 first_browser = NULL;
1572 EXPECT_EQ(1U, browser_list->size());
1574 // Verify that the logout confirmation dialog is not showing because a browser
1575 // window is still open.
1576 EXPECT_FALSE(logout_confirmation_controller->dialog_for_testing());
1578 // Close the second browser window.
1579 browser_window = second_browser->window();
1580 ASSERT_TRUE(browser_window);
1581 run_loop_.reset(new base::RunLoop);
1582 browser_window->Close();
1583 browser_window = NULL;
1584 run_loop_->Run();
1585 second_browser = NULL;
1586 EXPECT_TRUE(browser_list->empty());
1588 // Verify that the logout confirmation dialog is showing.
1589 ash::LogoutConfirmationDialog* dialog =
1590 logout_confirmation_controller->dialog_for_testing();
1591 ASSERT_TRUE(dialog);
1593 // Deny the logout.
1594 dialog->GetWidget()->Close();
1595 dialog = NULL;
1596 base::RunLoop().RunUntilIdle();
1598 // Verify that the logout confirmation dialog is no longer showing.
1599 EXPECT_FALSE(logout_confirmation_controller->dialog_for_testing());
1601 // Open a browser window.
1602 browser = CreateBrowser(profile);
1603 EXPECT_EQ(1U, browser_list->size());
1605 // Close the browser window.
1606 browser_window = browser->window();
1607 ASSERT_TRUE(browser_window);
1608 run_loop_.reset(new base::RunLoop);
1609 browser_window->Close();
1610 browser_window = NULL;
1611 run_loop_->Run();
1612 browser = NULL;
1613 EXPECT_TRUE(browser_list->empty());
1615 // Verify that the logout confirmation dialog is showing again.
1616 dialog = logout_confirmation_controller->dialog_for_testing();
1617 ASSERT_TRUE(dialog);
1619 // Deny the logout.
1620 dialog->GetWidget()->Close();
1621 dialog = NULL;
1622 base::RunLoop().RunUntilIdle();
1624 app_window_registry->RemoveObserver(this);
1627 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, NoRecommendedLocaleNoSwitch) {
1628 UploadAndInstallDeviceLocalAccountPolicy();
1629 AddPublicSessionToDevicePolicy(kAccountId1);
1631 WaitForPolicy();
1633 ExpandPublicSessionPod(false);
1635 // Click the enter button to start the session.
1636 ASSERT_TRUE(content::ExecuteScript(
1637 contents_,
1638 base::StringPrintf(
1639 "document.getElementById('pod-row').getPodWithUsername_('%s')"
1640 " .querySelector('.enter-button').click();",
1641 user_id_1_.c_str())));
1643 WaitForSessionStart();
1645 // Verify that the locale has not changed and the first keyboard layout
1646 // applicable to the locale was chosen.
1647 EXPECT_EQ(initial_locale_, g_browser_process->GetApplicationLocale());
1648 EXPECT_EQ(initial_language_, icu::Locale::getDefault().getLanguage());
1649 VerifyKeyboardLayoutMatchesLocale();
1652 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, NoRecommendedLocaleSwitch) {
1653 UploadAndInstallDeviceLocalAccountPolicy();
1654 AddPublicSessionToDevicePolicy(kAccountId1);
1656 WaitForPolicy();
1658 ExpandPublicSessionPod(false);
1660 // Click the link that switches the pod to its advanced form. Verify that the
1661 // pod switches from basic to advanced.
1662 bool advanced = false;
1663 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1664 contents_,
1665 base::StringPrintf(
1666 "var pod ="
1667 " document.getElementById('pod-row').getPodWithUsername_('%s');"
1668 "pod.querySelector('.language-and-input').click();"
1669 "domAutomationController.send(pod.classList.contains('advanced'));",
1670 user_id_1_.c_str()),
1671 &advanced));
1672 EXPECT_FALSE(advanced);
1674 // Manually select a different locale.
1675 ASSERT_TRUE(content::ExecuteScript(
1676 contents_,
1677 base::StringPrintf(
1678 "var languageSelect = document.getElementById('pod-row')"
1679 " .getPodWithUsername_('%s').querySelector('.language-select');"
1680 "languageSelect.value = '%s';"
1681 "var event = document.createEvent('HTMLEvents');"
1682 "event.initEvent('change', false, true);"
1683 "languageSelect.dispatchEvent(event);",
1684 user_id_1_.c_str(),
1685 kPublicSessionLocale)));
1687 // The UI will have requested an updated list of keyboard layouts at this
1688 // point. Wait for the constructions of this list to finish.
1689 WaitForGetKeyboardLayoutsForLocaleToFinish();
1691 // Manually select a different keyboard layout and click the enter button to
1692 // start the session.
1693 ASSERT_TRUE(content::ExecuteScript(
1694 contents_,
1695 base::StringPrintf(
1696 "var pod ="
1697 " document.getElementById('pod-row').getPodWithUsername_('%s');"
1698 "pod.querySelector('.keyboard-select').value = '%s';"
1699 "pod.querySelector('.enter-button').click();",
1700 user_id_1_.c_str(),
1701 public_session_input_method_id_.c_str())));
1703 WaitForSessionStart();
1705 // Verify that the locale and keyboard layout have been applied.
1706 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale());
1707 EXPECT_EQ(l10n_util::GetLanguage(kPublicSessionLocale),
1708 icu::Locale::getDefault().getLanguage());
1709 EXPECT_EQ(public_session_input_method_id_,
1710 chromeos::input_method::InputMethodManager::Get()
1711 ->GetActiveIMEState()
1712 ->GetCurrentInputMethod()
1713 .id());
1716 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, OneRecommendedLocale) {
1717 // Specify a recommended locale.
1718 SetRecommendedLocales(kSingleRecommendedLocale,
1719 arraysize(kSingleRecommendedLocale));
1720 UploadAndInstallDeviceLocalAccountPolicy();
1721 AddPublicSessionToDevicePolicy(kAccountId1);
1723 WaitForPolicy();
1725 ExpandPublicSessionPod(false);
1727 // Click the enter button to start the session.
1728 ASSERT_TRUE(content::ExecuteScript(
1729 contents_,
1730 base::StringPrintf(
1731 "document.getElementById('pod-row').getPodWithUsername_('%s')"
1732 " .querySelector('.enter-button').click();",
1733 user_id_1_.c_str())));
1735 WaitForSessionStart();
1737 // Verify that the recommended locale has been applied and the first keyboard
1738 // layout applicable to the locale was chosen.
1739 EXPECT_EQ(kSingleRecommendedLocale[0],
1740 g_browser_process->GetApplicationLocale());
1741 EXPECT_EQ(l10n_util::GetLanguage(kSingleRecommendedLocale[0]),
1742 icu::Locale::getDefault().getLanguage());
1743 VerifyKeyboardLayoutMatchesLocale();
1746 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, MultipleRecommendedLocales) {
1747 // Specify recommended locales.
1748 SetRecommendedLocales(kRecommendedLocales1, arraysize(kRecommendedLocales1));
1749 UploadAndInstallDeviceLocalAccountPolicy();
1750 AddPublicSessionToDevicePolicy(kAccountId1);
1751 AddPublicSessionToDevicePolicy(kAccountId2);
1753 WaitForPolicy();
1755 ExpandPublicSessionPod(true);
1757 // Verify that the pod shows a list of locales beginning with the recommended
1758 // ones, followed by others.
1759 const std::string get_locale_list = base::StringPrintf(
1760 "var languageSelect = document.getElementById('pod-row')"
1761 " .getPodWithUsername_('%s').querySelector('.language-select');"
1762 "var locales = [];"
1763 "for (var i = 0; i < languageSelect.length; ++i)"
1764 " locales.push(languageSelect.options[i].value);"
1765 "domAutomationController.send(JSON.stringify(locales));",
1766 user_id_1_.c_str());
1767 std::string json;
1768 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_,
1769 get_locale_list,
1770 &json));
1771 scoped_ptr<base::Value> value_ptr(base::JSONReader::Read(json));
1772 const base::ListValue* locales = NULL;
1773 ASSERT_TRUE(value_ptr);
1774 ASSERT_TRUE(value_ptr->GetAsList(&locales));
1775 EXPECT_LT(arraysize(kRecommendedLocales1), locales->GetSize());
1777 // Verify that the list starts with the recommended locales, in correct order.
1778 for (size_t i = 0; i < arraysize(kRecommendedLocales1); ++i) {
1779 std::string locale;
1780 EXPECT_TRUE(locales->GetString(i, &locale));
1781 EXPECT_EQ(kRecommendedLocales1[i], locale);
1784 // Verify that the recommended locales do not appear again in the remainder of
1785 // the list.
1786 std::set<std::string> recommended_locales;
1787 for (size_t i = 0; i < arraysize(kRecommendedLocales1); ++i)
1788 recommended_locales.insert(kRecommendedLocales1[i]);
1789 for (size_t i = arraysize(kRecommendedLocales1); i < locales->GetSize();
1790 ++i) {
1791 std::string locale;
1792 EXPECT_TRUE(locales->GetString(i, &locale));
1793 EXPECT_EQ(recommended_locales.end(), recommended_locales.find(locale));
1796 // Verify that the first recommended locale is selected.
1797 const std::string get_selected_locale =
1798 base::StringPrintf(
1799 "domAutomationController.send(document.getElementById('pod-row')"
1800 " .getPodWithUsername_('%s').querySelector('.language-select')"
1801 " .value);",
1802 user_id_1_.c_str());
1803 std::string selected_locale;
1804 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_,
1805 get_selected_locale,
1806 &selected_locale));
1807 EXPECT_EQ(kRecommendedLocales1[0], selected_locale);
1809 // Change the list of recommended locales.
1810 SetRecommendedLocales(kRecommendedLocales2, arraysize(kRecommendedLocales2));
1812 // Also change the display name as it is easy to ensure that policy has been
1813 // updated by waiting for a display name change.
1814 device_local_account_policy_.payload().mutable_userdisplayname()->set_value(
1815 kDisplayName2);
1816 UploadAndInstallDeviceLocalAccountPolicy();
1817 policy::BrowserPolicyConnectorChromeOS* connector =
1818 g_browser_process->platform_part()->browser_policy_connector_chromeos();
1819 DeviceLocalAccountPolicyBroker* broker =
1820 connector->GetDeviceLocalAccountPolicyService()->GetBrokerForUser(
1821 user_id_1_);
1822 ASSERT_TRUE(broker);
1823 broker->core()->store()->Load();
1824 WaitForDisplayName(user_id_1_, kDisplayName2);
1826 // Verify that the new list of locales is shown in the UI.
1827 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_,
1828 get_locale_list,
1829 &json));
1830 value_ptr.reset(base::JSONReader::Read(json));
1831 locales = NULL;
1832 ASSERT_TRUE(value_ptr);
1833 ASSERT_TRUE(value_ptr->GetAsList(&locales));
1834 EXPECT_LT(arraysize(kRecommendedLocales2), locales->GetSize());
1835 for (size_t i = 0; i < arraysize(kRecommendedLocales2); ++i) {
1836 std::string locale;
1837 EXPECT_TRUE(locales->GetString(i, &locale));
1838 EXPECT_EQ(kRecommendedLocales2[i], locale);
1841 // Verify that the first new recommended locale is selected.
1842 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_,
1843 get_selected_locale,
1844 &selected_locale));
1845 EXPECT_EQ(kRecommendedLocales2[0], selected_locale);
1847 // Manually select a different locale.
1848 ASSERT_TRUE(content::ExecuteScript(
1849 contents_,
1850 base::StringPrintf(
1851 "var languageSelect = document.getElementById('pod-row')"
1852 " .getPodWithUsername_('%s').querySelector('.language-select');"
1853 "languageSelect.value = '%s';"
1854 "var event = document.createEvent('HTMLEvents');"
1855 "event.initEvent('change', false, true);"
1856 "languageSelect.dispatchEvent(event);",
1857 user_id_1_.c_str(),
1858 kPublicSessionLocale)));
1860 // Change the list of recommended locales.
1861 SetRecommendedLocales(kRecommendedLocales2, arraysize(kRecommendedLocales2));
1862 device_local_account_policy_.payload().mutable_userdisplayname()->set_value(
1863 kDisplayName1);
1864 UploadAndInstallDeviceLocalAccountPolicy();
1865 broker->core()->store()->Load();
1866 WaitForDisplayName(user_id_1_, kDisplayName1);
1868 // Verify that the manually selected locale is still selected.
1869 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_,
1870 get_selected_locale,
1871 &selected_locale));
1872 EXPECT_EQ(kPublicSessionLocale, selected_locale);
1874 // The UI will request an updated list of keyboard layouts at this point. Wait
1875 // for the constructions of this list to finish.
1876 WaitForGetKeyboardLayoutsForLocaleToFinish();
1878 // Manually select a different keyboard layout.
1879 ASSERT_TRUE(content::ExecuteScript(
1880 contents_,
1881 base::StringPrintf(
1882 "document.getElementById('pod-row').getPodWithUsername_('%s')"
1883 " .querySelector('.keyboard-select').value = '%s';",
1884 user_id_1_.c_str(),
1885 public_session_input_method_id_.c_str())));
1887 // Click on a different pod, causing focus to shift away and the pod to
1888 // contract.
1889 ASSERT_TRUE(content::ExecuteScript(
1890 contents_,
1891 base::StringPrintf(
1892 "document.getElementById('pod-row').getPodWithUsername_('%s')"
1893 " .click();",
1894 user_id_2_.c_str())));
1896 // Click on the pod again, causing it to expand again. Verify that the pod has
1897 // kept all its state (the advanced form is being shown, the manually selected
1898 // locale and keyboard layout are selected).
1899 ASSERT_TRUE(content::ExecuteScriptAndExtractString(
1900 contents_,
1901 base::StringPrintf(
1902 "var pod ="
1903 " document.getElementById('pod-row').getPodWithUsername_('%s');"
1904 "pod.click();"
1905 "var state = {};"
1906 "state.advanced = pod.classList.contains('advanced');"
1907 "state.locale = pod.querySelector('.language-select').value;"
1908 "state.keyboardLayout = pod.querySelector('.keyboard-select').value;"
1909 "console.log(JSON.stringify(state));"
1910 "domAutomationController.send(JSON.stringify(state));",
1911 user_id_1_.c_str()),
1912 &json));
1913 LOG(ERROR) << json;
1914 value_ptr.reset(base::JSONReader::Read(json));
1915 const base::DictionaryValue* state = NULL;
1916 ASSERT_TRUE(value_ptr);
1917 ASSERT_TRUE(value_ptr->GetAsDictionary(&state));
1918 bool advanced = false;
1919 EXPECT_TRUE(state->GetBoolean("advanced", &advanced));
1920 EXPECT_TRUE(advanced);
1921 EXPECT_TRUE(state->GetString("locale", &selected_locale));
1922 EXPECT_EQ(kPublicSessionLocale, selected_locale);
1923 std::string selected_keyboard_layout;
1924 EXPECT_TRUE(state->GetString("keyboardLayout", &selected_keyboard_layout));
1925 EXPECT_EQ(public_session_input_method_id_, selected_keyboard_layout);
1927 // Click the enter button to start the session.
1928 ASSERT_TRUE(content::ExecuteScript(
1929 contents_,
1930 base::StringPrintf(
1931 "document.getElementById('pod-row').getPodWithUsername_('%s')"
1932 " .querySelector('.enter-button').click();",
1933 user_id_1_.c_str())));
1935 WaitForSessionStart();
1937 // Verify that the locale and keyboard layout have been applied.
1938 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale());
1939 EXPECT_EQ(l10n_util::GetLanguage(kPublicSessionLocale),
1940 icu::Locale::getDefault().getLanguage());
1941 EXPECT_EQ(public_session_input_method_id_,
1942 chromeos::input_method::InputMethodManager::Get()
1943 ->GetActiveIMEState()
1944 ->GetCurrentInputMethod()
1945 .id());
1948 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, InvalidRecommendedLocale) {
1949 // Specify an invalid recommended locale.
1950 SetRecommendedLocales(kInvalidRecommendedLocale,
1951 arraysize(kInvalidRecommendedLocale));
1952 UploadAndInstallDeviceLocalAccountPolicy();
1953 AddPublicSessionToDevicePolicy(kAccountId1);
1955 WaitForPolicy();
1957 // Click on the pod to expand it. Verify that the pod expands to its basic
1958 // form as there is only one recommended locale.
1959 bool advanced = false;
1960 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
1961 contents_,
1962 base::StringPrintf(
1963 "var pod ="
1964 " document.getElementById('pod-row').getPodWithUsername_('%s');"
1965 "pod.click();"
1966 "domAutomationController.send(pod.classList.contains('advanced'));",
1967 user_id_1_.c_str()),
1968 &advanced));
1969 EXPECT_FALSE(advanced);
1970 EXPECT_EQ(l10n_util::GetLanguage(initial_locale_),
1971 icu::Locale::getDefault().getLanguage());
1973 // Click the enter button to start the session.
1974 ASSERT_TRUE(content::ExecuteScript(
1975 contents_,
1976 base::StringPrintf(
1977 "document.getElementById('pod-row').getPodWithUsername_('%s')"
1978 " .querySelector('.enter-button').click();",
1979 user_id_1_.c_str())));
1981 WaitForSessionStart();
1983 // Verify that since the recommended locale was invalid, the locale has not
1984 // changed and the first keyboard layout applicable to the locale was chosen.
1985 EXPECT_EQ(initial_locale_, g_browser_process->GetApplicationLocale());
1986 EXPECT_EQ(l10n_util::GetLanguage(initial_locale_),
1987 icu::Locale::getDefault().getLanguage());
1988 VerifyKeyboardLayoutMatchesLocale();
1991 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest,
1992 AutoLoginWithoutRecommendedLocales) {
1993 UploadAndInstallDeviceLocalAccountPolicy();
1994 AddPublicSessionToDevicePolicy(kAccountId1);
1995 EnableAutoLogin();
1997 WaitForPolicy();
1999 WaitForSessionStart();
2001 // Verify that the locale has not changed and the first keyboard layout
2002 // applicable to the locale was chosen.
2003 EXPECT_EQ(initial_locale_, g_browser_process->GetApplicationLocale());
2004 EXPECT_EQ(initial_language_, icu::Locale::getDefault().getLanguage());
2005 VerifyKeyboardLayoutMatchesLocale();
2008 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest,
2009 AutoLoginWithRecommendedLocales) {
2010 // Specify recommended locales.
2011 SetRecommendedLocales(kRecommendedLocales1, arraysize(kRecommendedLocales1));
2012 UploadAndInstallDeviceLocalAccountPolicy();
2013 AddPublicSessionToDevicePolicy(kAccountId1);
2014 EnableAutoLogin();
2016 WaitForPolicy();
2018 WaitForSessionStart();
2020 // Verify that the first recommended locale has been applied and the first
2021 // keyboard layout applicable to the locale was chosen.
2022 EXPECT_EQ(kRecommendedLocales1[0], g_browser_process->GetApplicationLocale());
2023 EXPECT_EQ(l10n_util::GetLanguage(kRecommendedLocales1[0]),
2024 icu::Locale::getDefault().getLanguage());
2025 VerifyKeyboardLayoutMatchesLocale();
2028 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, TermsOfServiceWithLocaleSwitch) {
2029 // Specify Terms of Service URL.
2030 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
2031 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value(
2032 embedded_test_server()->GetURL(
2033 std::string("/") + kExistentTermsOfServicePath).spec());
2034 UploadAndInstallDeviceLocalAccountPolicy();
2035 AddPublicSessionToDevicePolicy(kAccountId1);
2037 WaitForPolicy();
2039 // Select a different locale.
2040 ASSERT_TRUE(content::ExecuteScript(
2041 contents_,
2042 base::StringPrintf(
2043 "var languageSelect = document.getElementById('pod-row')"
2044 " .getPodWithUsername_('%s').querySelector('.language-select');"
2045 "languageSelect.value = '%s';"
2046 "var event = document.createEvent('HTMLEvents');"
2047 "event.initEvent('change', false, true);"
2048 "languageSelect.dispatchEvent(event);",
2049 user_id_1_.c_str(),
2050 kPublicSessionLocale)));
2052 // The UI will have requested an updated list of keyboard layouts at this
2053 // point. Wait for the constructions of this list to finish.
2054 WaitForGetKeyboardLayoutsForLocaleToFinish();
2056 // Set up an observer that will quit the message loop when login has succeeded
2057 // and the first wizard screen, if any, is being shown.
2058 base::RunLoop login_wait_run_loop;
2059 chromeos::MockAuthStatusConsumer login_status_consumer;
2060 EXPECT_CALL(login_status_consumer, OnAuthSuccess(_)).Times(1).WillOnce(
2061 InvokeWithoutArgs(&login_wait_run_loop, &base::RunLoop::Quit));
2062 chromeos::ExistingUserController* controller =
2063 chromeos::ExistingUserController::current_controller();
2064 ASSERT_TRUE(controller);
2065 controller->set_login_status_consumer(&login_status_consumer);
2067 // Manually select a different keyboard layout and click the enter button to
2068 // start the session.
2069 ASSERT_TRUE(content::ExecuteScript(
2070 contents_,
2071 base::StringPrintf(
2072 "var pod ="
2073 " document.getElementById('pod-row').getPodWithUsername_('%s');"
2074 "pod.querySelector('.keyboard-select').value = '%s';"
2075 "pod.querySelector('.enter-button').click();",
2076 user_id_1_.c_str(),
2077 public_session_input_method_id_.c_str())));
2079 // Spin the loop until the login observer fires. Then, unregister the
2080 // observer.
2081 login_wait_run_loop.Run();
2082 controller->set_login_status_consumer(NULL);
2084 // Verify that the Terms of Service screen is being shown.
2085 chromeos::WizardController* wizard_controller =
2086 chromeos::WizardController::default_controller();
2087 ASSERT_TRUE(wizard_controller);
2088 ASSERT_TRUE(wizard_controller->current_screen());
2089 EXPECT_EQ(chromeos::WizardController::kTermsOfServiceScreenName,
2090 wizard_controller->current_screen()->GetName());
2092 // Wait for the Terms of Service to finish downloading.
2093 bool done = false;
2094 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(contents_,
2095 "var screenElement = document.getElementById('terms-of-service');"
2096 "function SendReplyIfDownloadDone() {"
2097 " if (screenElement.classList.contains('tos-loading'))"
2098 " return false;"
2099 " domAutomationController.send(true);"
2100 " observer.disconnect();"
2101 " return true;"
2103 "var observer = new MutationObserver(SendReplyIfDownloadDone);"
2104 "if (!SendReplyIfDownloadDone()) {"
2105 " var options = { attributes: true, attributeFilter: [ 'class' ] };"
2106 " observer.observe(screenElement, options);"
2107 "}",
2108 &done));
2110 // Verify that the locale and keyboard layout have been applied.
2111 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale());
2112 EXPECT_EQ(l10n_util::GetLanguage(kPublicSessionLocale),
2113 icu::Locale::getDefault().getLanguage());
2114 EXPECT_EQ(public_session_input_method_id_,
2115 chromeos::input_method::InputMethodManager::Get()
2116 ->GetActiveIMEState()
2117 ->GetCurrentInputMethod()
2118 .id());
2120 // Wait for 'tos-accept-button' to become enabled.
2121 done = false;
2122 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
2123 contents_,
2124 "var screenElement = document.getElementById('tos-accept-button');"
2125 "function SendReplyIfAcceptEnabled() {"
2126 " if ($('tos-accept-button').disabled)"
2127 " return false;"
2128 " domAutomationController.send(true);"
2129 " observer.disconnect();"
2130 " return true;"
2132 "var observer = new MutationObserver(SendReplyIfAcceptEnabled);"
2133 "if (!SendReplyIfAcceptEnabled()) {"
2134 " var options = { attributes: true };"
2135 " observer.observe(screenElement, options);"
2136 "}",
2137 &done));
2139 // Click the accept button.
2140 ASSERT_TRUE(content::ExecuteScript(contents_,
2141 "$('tos-accept-button').click();"));
2143 WaitForSessionStart();
2145 // Verify that the locale and keyboard layout are still in force.
2146 EXPECT_EQ(kPublicSessionLocale, g_browser_process->GetApplicationLocale());
2147 EXPECT_EQ(l10n_util::GetLanguage(kPublicSessionLocale),
2148 icu::Locale::getDefault().getLanguage());
2149 EXPECT_EQ(public_session_input_method_id_,
2150 chromeos::input_method::InputMethodManager::Get()
2151 ->GetActiveIMEState()
2152 ->GetCurrentInputMethod()
2153 .id());
2156 // Test fails under MSan and is flaky on regular bots: http://crbug.com/446950
2157 IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DISABLED_PolicyForExtensions) {
2158 // Set up a test update server for the Show Managed Storage app.
2159 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
2160 TestingUpdateManifestProvider testing_update_manifest_provider(
2161 kRelativeUpdateURL);
2162 testing_update_manifest_provider.AddUpdate(
2163 kShowManagedStorageID,
2164 kShowManagedStorageVersion,
2165 embedded_test_server()->GetURL(std::string("/") +
2166 kShowManagedStorageCRXPath));
2167 embedded_test_server()->RegisterRequestHandler(
2168 base::Bind(&TestingUpdateManifestProvider::HandleRequest,
2169 base::Unretained(&testing_update_manifest_provider)));
2171 // Force-install the Show Managed Storage app. This app can be installed in
2172 // public sessions because it's whitelisted for testing purposes.
2173 em::StringList* forcelist = device_local_account_policy_.payload()
2174 .mutable_extensioninstallforcelist()->mutable_value();
2175 forcelist->add_entries(base::StringPrintf(
2176 "%s;%s",
2177 kShowManagedStorageID,
2178 embedded_test_server()->GetURL(kRelativeUpdateURL).spec().c_str()));
2180 // Set a policy for the app at the policy testserver.
2181 // Note that the policy for the device-local account will be fetched before
2182 // the session is started, so the policy for the app must be installed before
2183 // the first device policy fetch.
2184 ASSERT_TRUE(test_server_.UpdatePolicyData(
2185 dm_protocol::kChromeExtensionPolicyType, kShowManagedStorageID,
2187 " \"string\": {"
2188 " \"Value\": \"policy test value one\""
2189 " }"
2190 "}"));
2192 // Install and refresh the device policy now. This will also fetch the initial
2193 // user policy for the device-local account now.
2194 UploadAndInstallDeviceLocalAccountPolicy();
2195 AddPublicSessionToDevicePolicy(kAccountId1);
2196 WaitForPolicy();
2198 // Observe the app installation after login.
2199 content::WindowedNotificationObserver extension_observer(
2200 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
2201 base::Bind(DoesInstallSuccessReferToId, kShowManagedStorageID));
2202 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
2203 WaitForSessionStart();
2204 extension_observer.Wait();
2206 // Verify that the app was installed.
2207 Profile* profile = GetProfileForTest();
2208 ASSERT_TRUE(profile);
2209 ExtensionService* extension_service =
2210 extensions::ExtensionSystem::Get(profile)->extension_service();
2211 EXPECT_TRUE(extension_service->GetExtensionById(kShowManagedStorageID, true));
2213 // Wait for the app policy if it hasn't been fetched yet.
2214 ProfilePolicyConnector* connector =
2215 ProfilePolicyConnectorFactory::GetForBrowserContext(profile);
2216 ASSERT_TRUE(connector);
2217 PolicyService* policy_service = connector->policy_service();
2218 ASSERT_TRUE(policy_service);
2219 const PolicyNamespace ns(POLICY_DOMAIN_EXTENSIONS, kShowManagedStorageID);
2220 if (policy_service->GetPolicies(ns).empty()) {
2221 PolicyChangeRegistrar policy_registrar(policy_service, ns);
2222 base::RunLoop run_loop;
2223 policy_registrar.Observe(
2224 "string", base::Bind(&PolicyChangedCallback, run_loop.QuitClosure()));
2225 run_loop.Run();
2228 // Verify that the app policy was set.
2229 base::StringValue expected_value("policy test value one");
2230 EXPECT_TRUE(base::Value::Equals(
2231 &expected_value,
2232 policy_service->GetPolicies(ns).GetValue("string")));
2234 // Now update the policy at the server.
2235 ASSERT_TRUE(test_server_.UpdatePolicyData(
2236 dm_protocol::kChromeExtensionPolicyType, kShowManagedStorageID,
2238 " \"string\": {"
2239 " \"Value\": \"policy test value two\""
2240 " }"
2241 "}"));
2243 // And issue a policy refresh.
2245 PolicyChangeRegistrar policy_registrar(policy_service, ns);
2246 base::RunLoop run_loop;
2247 policy_registrar.Observe(
2248 "string", base::Bind(&PolicyChangedCallback, run_loop.QuitClosure()));
2249 policy_service->RefreshPolicies(base::Closure());
2250 run_loop.Run();
2253 // Verify that the app policy was updated.
2254 base::StringValue expected_new_value("policy test value two");
2255 EXPECT_TRUE(base::Value::Equals(
2256 &expected_new_value,
2257 policy_service->GetPolicies(ns).GetValue("string")));
2260 class TermsOfServiceDownloadTest : public DeviceLocalAccountTest,
2261 public testing::WithParamInterface<bool> {
2264 // Test fails under MSan, http://crbug.com/446950
2265 #if defined(MEMORY_SANITIZER)
2266 #define MAYBE_TermsOfServiceScreen DISABLED_TermsOfServiceScreen
2267 #else
2268 #define MAYBE_TermsOfServiceScreen TermsOfServiceScreen
2269 #endif
2271 IN_PROC_BROWSER_TEST_P(TermsOfServiceDownloadTest, MAYBE_TermsOfServiceScreen) {
2272 // Specify Terms of Service URL.
2273 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
2274 device_local_account_policy_.payload().mutable_termsofserviceurl()->set_value(
2275 embedded_test_server()->GetURL(
2276 std::string("/") +
2277 (GetParam() ? kExistentTermsOfServicePath
2278 : kNonexistentTermsOfServicePath)).spec());
2279 UploadAndInstallDeviceLocalAccountPolicy();
2280 AddPublicSessionToDevicePolicy(kAccountId1);
2282 WaitForPolicy();
2284 ASSERT_NO_FATAL_FAILURE(StartLogin(std::string(), std::string()));
2286 // Set up an observer that will quit the message loop when login has succeeded
2287 // and the first wizard screen, if any, is being shown.
2288 base::RunLoop login_wait_run_loop;
2289 chromeos::MockAuthStatusConsumer login_status_consumer;
2290 EXPECT_CALL(login_status_consumer, OnAuthSuccess(_)).Times(1).WillOnce(
2291 InvokeWithoutArgs(&login_wait_run_loop, &base::RunLoop::Quit));
2293 // Spin the loop until the observer fires. Then, unregister the observer.
2294 chromeos::ExistingUserController* controller =
2295 chromeos::ExistingUserController::current_controller();
2296 ASSERT_TRUE(controller);
2297 controller->set_login_status_consumer(&login_status_consumer);
2298 login_wait_run_loop.Run();
2299 controller->set_login_status_consumer(NULL);
2301 // Verify that the Terms of Service screen is being shown.
2302 chromeos::WizardController* wizard_controller =
2303 chromeos::WizardController::default_controller();
2304 ASSERT_TRUE(wizard_controller);
2305 ASSERT_TRUE(wizard_controller->current_screen());
2306 EXPECT_EQ(chromeos::WizardController::kTermsOfServiceScreenName,
2307 wizard_controller->current_screen()->GetName());
2309 // Wait for the Terms of Service to finish downloading, then get the status of
2310 // the screen's UI elements.
2311 std::string json;
2312 ASSERT_TRUE(content::ExecuteScriptAndExtractString(contents_,
2313 "var screenElement = document.getElementById('terms-of-service');"
2314 "function SendReplyIfDownloadDone() {"
2315 " if (screenElement.classList.contains('tos-loading'))"
2316 " return false;"
2317 " var status = {};"
2318 " status.heading = document.getElementById('tos-heading').textContent;"
2319 " status.subheading ="
2320 " document.getElementById('tos-subheading').textContent;"
2321 " status.contentHeading ="
2322 " document.getElementById('tos-content-heading').textContent;"
2323 " status.content ="
2324 " document.getElementById('tos-content-main').textContent;"
2325 " status.error = screenElement.classList.contains('error');"
2326 " status.acceptEnabled ="
2327 " !document.getElementById('tos-accept-button').disabled;"
2328 " domAutomationController.send(JSON.stringify(status));"
2329 " observer.disconnect();"
2330 " return true;"
2332 "var observer = new MutationObserver(SendReplyIfDownloadDone);"
2333 "if (!SendReplyIfDownloadDone()) {"
2334 " var options = { attributes: true, attributeFilter: [ 'class' ] };"
2335 " observer.observe(screenElement, options);"
2336 "}",
2337 &json));
2338 scoped_ptr<base::Value> value_ptr(base::JSONReader::Read(json));
2339 const base::DictionaryValue* status = NULL;
2340 ASSERT_TRUE(value_ptr);
2341 ASSERT_TRUE(value_ptr->GetAsDictionary(&status));
2342 std::string heading;
2343 EXPECT_TRUE(status->GetString("heading", &heading));
2344 std::string subheading;
2345 EXPECT_TRUE(status->GetString("subheading", &subheading));
2346 std::string content_heading;
2347 EXPECT_TRUE(status->GetString("contentHeading", &content_heading));
2348 std::string content;
2349 EXPECT_TRUE(status->GetString("content", &content));
2350 bool error;
2351 EXPECT_TRUE(status->GetBoolean("error", &error));
2352 bool accept_enabled;
2353 EXPECT_TRUE(status->GetBoolean("acceptEnabled", &accept_enabled));
2355 // Verify that the screen's headings have been set correctly.
2356 EXPECT_EQ(
2357 l10n_util::GetStringFUTF8(IDS_TERMS_OF_SERVICE_SCREEN_HEADING,
2358 base::UTF8ToUTF16(kDomain)),
2359 heading);
2360 EXPECT_EQ(
2361 l10n_util::GetStringFUTF8(IDS_TERMS_OF_SERVICE_SCREEN_SUBHEADING,
2362 base::UTF8ToUTF16(kDomain)),
2363 subheading);
2364 EXPECT_EQ(
2365 l10n_util::GetStringFUTF8(IDS_TERMS_OF_SERVICE_SCREEN_CONTENT_HEADING,
2366 base::UTF8ToUTF16(kDomain)),
2367 content_heading);
2369 if (!GetParam()) {
2370 // The Terms of Service URL was invalid. Verify that the screen is showing
2371 // an error and the accept button is disabled.
2372 EXPECT_TRUE(error);
2373 EXPECT_FALSE(accept_enabled);
2374 return;
2377 // The Terms of Service URL was valid. Verify that the screen is showing the
2378 // downloaded Terms of Service and the accept button is enabled.
2379 base::FilePath test_dir;
2380 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
2381 std::string terms_of_service;
2382 ASSERT_TRUE(base::ReadFileToString(
2383 test_dir.Append(kExistentTermsOfServicePath), &terms_of_service));
2384 EXPECT_EQ(terms_of_service, content);
2385 EXPECT_FALSE(error);
2386 EXPECT_TRUE(accept_enabled);
2388 // Click the accept button.
2389 ASSERT_TRUE(content::ExecuteScript(contents_,
2390 "$('tos-accept-button').click();"));
2392 WaitForSessionStart();
2395 INSTANTIATE_TEST_CASE_P(TermsOfServiceDownloadTestInstance,
2396 TermsOfServiceDownloadTest, testing::Bool());
2398 } // namespace policy