device_local_account_browsertest.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
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. 4 5#include <map> 6#include <string> 7 8#include "base/basictypes.h" 9#include "base/bind.h" 10#include "base/callback.h" 11#include "base/command_line.h" 12#include "base/file_util.h" 13#include "base/files/file_path.h" 14#include "base/files/scoped_temp_dir.h" 15#include "base/message_loop.h" 16#include "base/path_service.h" 17#include "base/run_loop.h" 18#include "base/stl_util.h" 19#include "base/string_util.h" 20#include "base/utf_string_conversions.h" 21#include "chrome/browser/browser_process.h" 22#include "chrome/browser/chromeos/login/existing_user_controller.h" 23#include "chrome/browser/chromeos/login/user.h" 24#include "chrome/browser/chromeos/login/user_manager.h" 25#include "chrome/browser/chromeos/login/wizard_controller.h" 26#include "chrome/browser/chromeos/policy/device_policy_builder.h" 27#include "chrome/browser/chromeos/policy/enterprise_install_attributes.h" 28#include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" 29#include "chrome/browser/chromeos/policy/proto/install_attributes.pb.h" 30#include "chrome/browser/lifetime/application_lifetime.h" 31#include "chrome/browser/policy/cloud/cloud_policy_constants.h" 32#include "chrome/browser/policy/cloud/policy_builder.h" 33#include "chrome/browser/policy/policy_service.h" 34#include "chrome/browser/policy/test/local_policy_test_server.h" 35#include "chrome/browser/prefs/session_startup_pref.h" 36#include "chrome/browser/ui/browser.h" 37#include "chrome/browser/ui/browser_finder.h" 38#include "chrome/browser/ui/host_desktop.h" 39#include "chrome/browser/ui/tabs/tab_strip_model.h" 40#include "chrome/common/chrome_notification_types.h" 41#include "chrome/common/chrome_paths.h" 42#include "chrome/common/chrome_switches.h" 43#include "chrome/test/base/in_process_browser_test.h" 44#include "chromeos/dbus/cryptohome_client.h" 45#include "chromeos/dbus/dbus_method_call_status.h" 46#include "chromeos/dbus/dbus_thread_manager.h" 47#include "chromeos/dbus/mock_dbus_thread_manager.h" 48#include "chromeos/dbus/mock_update_engine_client.h" 49#include "chromeos/dbus/session_manager_client.h" 50#include "content/public/browser/notification_observer.h" 51#include "content/public/browser/notification_registrar.h" 52#include "content/public/browser/notification_service.h" 53#include "content/public/browser/web_contents.h" 54#include "testing/gmock/include/gmock/gmock.h" 55#include "third_party/cros_system_api/dbus/service_constants.h" 56 57namespace em = enterprise_management; 58 59using testing::Return; 60 61namespace policy { 62 63namespace { 64 65const char kAccountId1[] = "dla1@example.com"; 66const char kAccountId2[] = "dla2@example.com"; 67const char kDisplayName1[] = "display name for account 1"; 68const char kDisplayName2[] = "display name for account 2"; 69const char* kStartupURLs[] = { 70 "chrome://policy", 71 "chrome://about", 72}; 73 74// Observes a specific notification type and quits the message loop once a 75// condition holds. 76class NotificationWatcher : public content::NotificationObserver { 77 public: 78 // Callback invoked on notifications. Should return true when the condition 79 // that the caller is waiting for is satisfied. 80 typedef base::Callback<bool(void)> ConditionTestCallback; 81 82 explicit NotificationWatcher(int notification_type, 83 const ConditionTestCallback& callback) 84 : type_(notification_type), 85 callback_(callback) {} 86 87 void Run() { 88 if (callback_.Run()) 89 return; 90 91 content::NotificationRegistrar registrar; 92 registrar.Add(this, type_, content::NotificationService::AllSources()); 93 run_loop_.Run(); 94 } 95 96 // content::NotificationObserver: 97 virtual void Observe(int type, 98 const content::NotificationSource& source, 99 const content::NotificationDetails& details) OVERRIDE { 100 if (callback_.Run()) 101 run_loop_.Quit(); 102 } 103 104 private: 105 int type_; 106 ConditionTestCallback callback_; 107 base::RunLoop run_loop_; 108 109 DISALLOW_COPY_AND_ASSIGN(NotificationWatcher); 110}; 111 112// A fake implementation of session_manager. Accepts policy blobs to be set and 113// returns them unmodified. 114class FakeSessionManagerClient : public chromeos::SessionManagerClient { 115 public: 116 FakeSessionManagerClient() {} 117 virtual ~FakeSessionManagerClient() {} 118 119 // SessionManagerClient: 120 virtual void AddObserver(Observer* observer) OVERRIDE {} 121 virtual void RemoveObserver(Observer* observer) OVERRIDE {} 122 virtual bool HasObserver(Observer* observer) OVERRIDE { return false; } 123 virtual void EmitLoginPromptReady() OVERRIDE {} 124 virtual void EmitLoginPromptVisible() OVERRIDE {} 125 virtual void RestartJob(int pid, const std::string& command_line) OVERRIDE {} 126 virtual void RestartEntd() OVERRIDE {} 127 virtual void StartSession(const std::string& user_email) OVERRIDE {} 128 virtual void StopSession() OVERRIDE {} 129 virtual void StartDeviceWipe() OVERRIDE {} 130 virtual void RequestLockScreen() OVERRIDE {} 131 virtual void NotifyLockScreenShown() OVERRIDE {} 132 virtual void RequestUnlockScreen() OVERRIDE {} 133 virtual void NotifyLockScreenDismissed() OVERRIDE {} 134 virtual void RetrieveDevicePolicy( 135 const RetrievePolicyCallback& callback) OVERRIDE { 136 MessageLoop::current()->PostTask(FROM_HERE, 137 base::Bind(callback, device_policy_)); 138 } 139 virtual void RetrieveUserPolicy( 140 const RetrievePolicyCallback& callback) OVERRIDE { 141 MessageLoop::current()->PostTask(FROM_HERE, 142 base::Bind(callback, user_policy_)); 143 } 144 virtual void RetrieveDeviceLocalAccountPolicy( 145 const std::string& account_id, 146 const RetrievePolicyCallback& callback) OVERRIDE { 147 MessageLoop::current()->PostTask( 148 FROM_HERE, 149 base::Bind(callback, device_local_account_policy_[account_id])); 150 } 151 virtual void StoreDevicePolicy(const std::string& policy_blob, 152 const StorePolicyCallback& callback) OVERRIDE { 153 device_policy_ = policy_blob; 154 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); 155 } 156 virtual void StoreUserPolicy(const std::string& policy_blob, 157 const StorePolicyCallback& callback) OVERRIDE { 158 user_policy_ = policy_blob; 159 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); 160 } 161 virtual void StoreDeviceLocalAccountPolicy( 162 const std::string& account_id, 163 const std::string& policy_blob, 164 const StorePolicyCallback& callback) OVERRIDE { 165 device_local_account_policy_[account_id] = policy_blob; 166 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, true)); 167 } 168 169 const std::string& device_policy() const { 170 return device_policy_; 171 } 172 void set_device_policy(const std::string& policy_blob) { 173 device_policy_ = policy_blob; 174 } 175 176 const std::string& user_policy() const { 177 return user_policy_; 178 } 179 void set_user_policy(const std::string& policy_blob) { 180 user_policy_ = policy_blob; 181 } 182 183 const std::string& device_local_account_policy( 184 const std::string& account_id) const { 185 std::map<std::string, std::string>::const_iterator entry = 186 device_local_account_policy_.find(account_id); 187 return entry != device_local_account_policy_.end() ? entry->second 188 : EmptyString(); 189 } 190 void set_device_local_account_policy(const std::string& account_id, 191 const std::string& policy_blob) { 192 device_local_account_policy_[account_id] = policy_blob; 193 } 194 195 private: 196 std::string device_policy_; 197 std::string user_policy_; 198 std::map<std::string, std::string> device_local_account_policy_; 199 200 DISALLOW_COPY_AND_ASSIGN(FakeSessionManagerClient); 201}; 202 203class FakeCryptohomeClient : public chromeos::CryptohomeClient { 204 public: 205 using chromeos::CryptohomeClient::AsyncMethodCallback; 206 using chromeos::CryptohomeClient::AsyncCallStatusHandler; 207 using chromeos::CryptohomeClient::AsyncCallStatusWithDataHandler; 208 209 FakeCryptohomeClient() {} 210 virtual ~FakeCryptohomeClient() {} 211 212 virtual void SetAsyncCallStatusHandlers( 213 const AsyncCallStatusHandler& handler, 214 const AsyncCallStatusWithDataHandler& data_handler) OVERRIDE { 215 handler_ = handler; 216 data_handler_ = data_handler; 217 } 218 virtual void ResetAsyncCallStatusHandlers() OVERRIDE { 219 handler_.Reset(); 220 data_handler_.Reset(); 221 } 222 virtual void IsMounted( 223 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 224 virtual bool Unmount(bool* success) OVERRIDE { 225 *success = true; 226 return true; 227 } 228 virtual void AsyncCheckKey(const std::string& username, 229 const std::string& key, 230 const AsyncMethodCallback& callback) OVERRIDE {} 231 virtual void AsyncMigrateKey(const std::string& username, 232 const std::string& from_key, 233 const std::string& to_key, 234 const AsyncMethodCallback& callback) OVERRIDE {} 235 virtual void AsyncRemove(const std::string& username, 236 const AsyncMethodCallback& callback) OVERRIDE {} 237 virtual bool GetSystemSalt(std::vector<uint8>* salt) OVERRIDE { 238 return false; 239 } 240 virtual void GetSanitizedUsername( 241 const std::string& username, 242 const chromeos::StringDBusMethodCallback& callback) OVERRIDE {} 243 virtual void AsyncMount(const std::string& username, 244 const std::string& key, 245 int flags, 246 const AsyncMethodCallback& callback) OVERRIDE { 247 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback, 1)); 248 MessageLoop::current()->PostTask( 249 FROM_HERE, base::Bind(handler_, 1, true, cryptohome::MOUNT_ERROR_NONE)); 250 } 251 virtual void AsyncMountGuest(const AsyncMethodCallback& callback) OVERRIDE {} 252 virtual void TpmIsReady( 253 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 254 virtual void TpmIsEnabled( 255 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 256 virtual bool CallTpmIsEnabledAndBlock(bool* enabled) OVERRIDE { 257 return false; 258 } 259 virtual void TpmGetPassword( 260 const chromeos::StringDBusMethodCallback& callback) OVERRIDE {} 261 virtual void TpmIsOwned( 262 const chromeos::BoolDBusMethodCallback& kallback) OVERRIDE {} 263 virtual bool CallTpmIsOwnedAndBlock(bool* owned) OVERRIDE { 264 return false; 265 } 266 virtual void TpmIsBeingOwned( 267 const chromeos::BoolDBusMethodCallback& kallback) OVERRIDE {} 268 virtual bool CallTpmIsBeingOwnedAndBlock(bool* owning) OVERRIDE { 269 return false; 270 } 271 virtual void TpmCanAttemptOwnership( 272 const chromeos::VoidDBusMethodCallback& callback) OVERRIDE {} 273 virtual bool CallTpmClearStoredPasswordAndBlock() OVERRIDE { 274 return false; 275 } 276 virtual void TpmClearStoredPassword( 277 const chromeos::VoidDBusMethodCallback& kallback) OVERRIDE {} 278 virtual void Pkcs11IsTpmTokenReady( 279 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 280 virtual void Pkcs11GetTpmTokenInfo( 281 const Pkcs11GetTpmTokenInfoCallback& callback) OVERRIDE {} 282 virtual bool InstallAttributesGet(const std::string& name, 283 std::vector<uint8>* value, 284 bool* successful) OVERRIDE { 285 return false; 286 } 287 virtual bool InstallAttributesSet(const std::string& name, 288 const std::vector<uint8>& value, 289 bool* successful) OVERRIDE { 290 return false; 291 } 292 virtual bool InstallAttributesFinalize(bool* successful) OVERRIDE { 293 return false; 294 } 295 virtual bool InstallAttributesIsReady(bool* is_ready) OVERRIDE { 296 return false; 297 } 298 virtual bool InstallAttributesIsInvalid(bool* is_invalid) OVERRIDE { 299 return true; 300 } 301 virtual bool InstallAttributesIsFirstInstall( 302 bool* is_first_install) OVERRIDE { 303 return false; 304 } 305 virtual void TpmAttestationIsPrepared( 306 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 307 virtual void TpmAttestationIsEnrolled( 308 const chromeos::BoolDBusMethodCallback& callback) OVERRIDE {} 309 virtual void AsyncTpmAttestationCreateEnrollRequest( 310 const AsyncMethodCallback& callback) OVERRIDE {} 311 virtual void AsyncTpmAttestationEnroll( 312 const std::string& pca_response, 313 const AsyncMethodCallback& callback) OVERRIDE {} 314 virtual void AsyncTpmAttestationCreateCertRequest( 315 bool is_cert_for_owner, 316 const AsyncMethodCallback& callback) OVERRIDE {} 317 virtual void AsyncTpmAttestationFinishCertRequest( 318 const std::string& pca_response, 319 const AsyncMethodCallback& callback) OVERRIDE {} 320 321 private: 322 AsyncCallStatusHandler handler_; 323 AsyncCallStatusWithDataHandler data_handler_; 324 325 DISALLOW_COPY_AND_ASSIGN(FakeCryptohomeClient); 326}; 327 328} // namespace 329 330class DeviceLocalAccountTest : public InProcessBrowserTest { 331 protected: 332 DeviceLocalAccountTest() {} 333 virtual ~DeviceLocalAccountTest() {} 334 335 virtual void SetUp() OVERRIDE { 336 // Configure and start the test server. 337 scoped_ptr<crypto::RSAPrivateKey> signing_key( 338 PolicyBuilder::CreateTestSigningKey()); 339 ASSERT_TRUE(test_server_.SetSigningKey(signing_key.get())); 340 signing_key.reset(); 341 test_server_.RegisterClient(PolicyBuilder::kFakeToken, 342 PolicyBuilder::kFakeDeviceId); 343 ASSERT_TRUE(test_server_.Start()); 344 345 InProcessBrowserTest::SetUp(); 346 } 347 348 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 349 command_line->AppendSwitch(switches::kLoginManager); 350 command_line->AppendSwitch(switches::kForceLoginManagerInTests); 351 command_line->AppendSwitchASCII( 352 switches::kLoginScreen, chromeos::WizardController::kLoginScreenName); 353 command_line->AppendSwitchASCII( 354 switches::kDeviceManagementUrl, test_server_.GetServiceURL().spec()); 355 command_line->AppendSwitchASCII( 356 switches::kLoginProfile, "user"); 357 } 358 359 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 360 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 361 362 // Clear command-line arguments (but keep command-line switches) so the 363 // startup pages policy takes effect. 364 CommandLine* command_line = CommandLine::ForCurrentProcess(); 365 CommandLine::StringVector argv(command_line->argv()); 366 argv.erase(argv.begin() + argv.size() - command_line->GetArgs().size(), 367 argv.end()); 368 command_line->InitFromArgv(argv); 369 370 // Mark the device enterprise-enrolled. 371 SetUpInstallAttributes(); 372 373 SetUpPolicy(); 374 375 // Redirect session_manager DBus calls to FakeSessionManagerClient. 376 chromeos::MockDBusThreadManager* dbus_thread_manager = 377 new chromeos::MockDBusThreadManager(); 378 EXPECT_CALL(*dbus_thread_manager, GetSessionManagerClient()) 379 .WillRepeatedly(Return(&session_manager_client_)); 380 chromeos::DBusThreadManager::InitializeForTesting(dbus_thread_manager); 381 382 // Mock out cryptohome mount calls to succeed immediately. 383 EXPECT_CALL(*dbus_thread_manager, GetCryptohomeClient()) 384 .WillRepeatedly(Return(&cryptohome_client_)); 385 386 // Set up the MockUpdateEngineClient. 387 EXPECT_CALL(*dbus_thread_manager->mock_update_engine_client(), 388 GetLastStatus()) 389 .Times(1) 390 .WillOnce(Return(chromeos::MockUpdateEngineClient::Status())); 391 } 392 393 virtual void CleanUpOnMainThread() OVERRIDE { 394 // This shuts down the login UI. 395 MessageLoop::current()->PostTask(FROM_HERE, 396 base::Bind(&chrome::AttemptExit)); 397 base::RunLoop().RunUntilIdle(); 398 } 399 400 void SetUpInstallAttributes() { 401 cryptohome::SerializedInstallAttributes install_attrs_proto; 402 cryptohome::SerializedInstallAttributes::Attribute* attribute = NULL; 403 404 attribute = install_attrs_proto.add_attributes(); 405 attribute->set_name(EnterpriseInstallAttributes::kAttrEnterpriseOwned); 406 attribute->set_value("true"); 407 408 attribute = install_attrs_proto.add_attributes(); 409 attribute->set_name(EnterpriseInstallAttributes::kAttrEnterpriseUser); 410 attribute->set_value(PolicyBuilder::kFakeUsername); 411 412 base::FilePath install_attrs_file = 413 temp_dir_.path().AppendASCII("install_attributes.pb"); 414 const std::string install_attrs_blob( 415 install_attrs_proto.SerializeAsString()); 416 ASSERT_EQ(static_cast<int>(install_attrs_blob.size()), 417 file_util::WriteFile(install_attrs_file, 418 install_attrs_blob.c_str(), 419 install_attrs_blob.size())); 420 ASSERT_TRUE(PathService::Override(chrome::FILE_INSTALL_ATTRIBUTES, 421 install_attrs_file)); 422 } 423 424 void SetUpPolicy() { 425 // Configure two device-local accounts in device settings. 426 DevicePolicyBuilder device_policy; 427 device_policy.policy_data().set_public_key_version(1); 428 em::ChromeDeviceSettingsProto& proto(device_policy.payload()); 429 proto.mutable_show_user_names()->set_show_user_names(true); 430 proto.mutable_device_local_accounts()->add_account()->set_id(kAccountId1); 431 proto.mutable_device_local_accounts()->add_account()->set_id(kAccountId2); 432 device_policy.Build(); 433 session_manager_client_.set_device_policy(device_policy.GetBlob()); 434 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, 435 std::string(), proto.SerializeAsString()); 436 437 // Install the owner key. 438 base::FilePath owner_key_file = temp_dir_.path().AppendASCII("owner.key"); 439 std::vector<uint8> owner_key_bits; 440 ASSERT_TRUE(device_policy.signing_key()->ExportPublicKey(&owner_key_bits)); 441 ASSERT_EQ( 442 static_cast<int>(owner_key_bits.size()), 443 file_util::WriteFile( 444 owner_key_file, 445 reinterpret_cast<const char*>(vector_as_array(&owner_key_bits)), 446 owner_key_bits.size())); 447 ASSERT_TRUE(PathService::Override(chrome::FILE_OWNER_KEY, owner_key_file)); 448 449 // Configure device-local account policy for the first device-local account. 450 UserPolicyBuilder device_local_account_policy; 451 device_local_account_policy.policy_data().set_policy_type( 452 dm_protocol::kChromePublicAccountPolicyType); 453 device_local_account_policy.policy_data().set_username(kAccountId1); 454 device_local_account_policy.policy_data().set_settings_entity_id( 455 kAccountId1); 456 device_local_account_policy.policy_data().set_public_key_version(1); 457 device_local_account_policy.payload().mutable_restoreonstartup()->set_value( 458 SessionStartupPref::kPrefValueURLs); 459 em::StringListPolicyProto* startup_urls_proto = 460 device_local_account_policy.payload().mutable_restoreonstartupurls(); 461 for (size_t i = 0; i < arraysize(kStartupURLs); ++i) 462 startup_urls_proto->mutable_value()->add_entries(kStartupURLs[i]); 463 device_local_account_policy.payload().mutable_userdisplayname()->set_value( 464 kDisplayName1); 465 device_local_account_policy.Build(); 466 session_manager_client_.set_device_local_account_policy( 467 kAccountId1, device_local_account_policy.GetBlob()); 468 test_server_.UpdatePolicy( 469 dm_protocol::kChromePublicAccountPolicyType, kAccountId1, 470 device_local_account_policy.payload().SerializeAsString()); 471 472 // Make policy for the second account available from the server. 473 device_local_account_policy.payload().mutable_userdisplayname()->set_value( 474 kDisplayName2); 475 test_server_.UpdatePolicy( 476 dm_protocol::kChromePublicAccountPolicyType, kAccountId2, 477 device_local_account_policy.payload().SerializeAsString()); 478 479 // Don't install policy for |kAccountId2| yet so initial download gets 480 // test coverage. 481 ASSERT_TRUE(session_manager_client_.device_local_account_policy( 482 kAccountId2).empty()); 483 } 484 485 void CheckPublicSessionPresent(const std::string& id) { 486 const chromeos::User* user = chromeos::UserManager::Get()->FindUser(id); 487 ASSERT_TRUE(user); 488 EXPECT_EQ(id, user->email()); 489 EXPECT_EQ(chromeos::User::USER_TYPE_PUBLIC_ACCOUNT, user->GetType()); 490 } 491 492 LocalPolicyTestServer test_server_; 493 base::ScopedTempDir temp_dir_; 494 495 FakeSessionManagerClient session_manager_client_; 496 FakeCryptohomeClient cryptohome_client_; 497}; 498 499static bool IsKnownUser(const std::string& account_id) { 500 return chromeos::UserManager::Get()->IsKnownUser(account_id); 501} 502 503IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, LoginScreen) { 504 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, 505 base::Bind(&IsKnownUser, kAccountId1)).Run(); 506 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, 507 base::Bind(&IsKnownUser, kAccountId2)).Run(); 508 509 CheckPublicSessionPresent(kAccountId1); 510 CheckPublicSessionPresent(kAccountId2); 511} 512 513static bool DisplayNameMatches(const std::string& account_id, 514 const std::string& display_name) { 515 const chromeos::User* user = 516 chromeos::UserManager::Get()->FindUser(account_id); 517 if (!user || user->display_name().empty()) 518 return false; 519 EXPECT_EQ(UTF8ToUTF16(display_name), user->display_name()); 520 return true; 521} 522 523IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DisplayName) { 524 NotificationWatcher( 525 chrome::NOTIFICATION_USER_LIST_CHANGED, 526 base::Bind(&DisplayNameMatches, kAccountId1, kDisplayName1)).Run(); 527} 528 529IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, PolicyDownload) { 530 // Policy for kAccountId2 is not installed in session_manager_client, make 531 // sure it gets fetched from the server. Note that the test setup doesn't set 532 // up policy for kAccountId2, so the presence of the display name can be used 533 // as signal to indicate successful policy download. 534 NotificationWatcher( 535 chrome::NOTIFICATION_USER_LIST_CHANGED, 536 base::Bind(&DisplayNameMatches, kAccountId2, kDisplayName2)).Run(); 537 538 // Sanity check: The policy should be present now. 539 ASSERT_FALSE(session_manager_client_.device_local_account_policy( 540 kAccountId2).empty()); 541} 542 543static bool IsNotKnownUser(const std::string& account_id) { 544 return !IsKnownUser(account_id); 545} 546 547IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, DevicePolicyChange) { 548 // Wait until the login screen is up. 549 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, 550 base::Bind(&IsKnownUser, kAccountId1)).Run(); 551 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, 552 base::Bind(&IsKnownUser, kAccountId2)).Run(); 553 554 // Update policy to remove kAccountId2. 555 em::ChromeDeviceSettingsProto policy; 556 policy.mutable_show_user_names()->set_show_user_names(true); 557 policy.mutable_device_local_accounts()->add_account()->set_id(kAccountId1); 558 559 test_server_.UpdatePolicy(dm_protocol::kChromeDevicePolicyType, std::string(), 560 policy.SerializeAsString()); 561 g_browser_process->policy_service()->RefreshPolicies(base::Closure()); 562 563 // Make sure the second device-local account disappears. 564 NotificationWatcher(chrome::NOTIFICATION_USER_LIST_CHANGED, 565 base::Bind(&IsNotKnownUser, kAccountId2)).Run(); 566} 567 568static bool IsSessionStarted() { 569 return chromeos::UserManager::Get()->IsSessionStarted(); 570} 571 572IN_PROC_BROWSER_TEST_F(DeviceLocalAccountTest, StartSession) { 573 // This observes the display name becoming available as this indicates 574 // device-local account policy is fully loaded, which is a prerequisite for 575 // successful login. 576 NotificationWatcher( 577 chrome::NOTIFICATION_USER_LIST_CHANGED, 578 base::Bind(&DisplayNameMatches, kAccountId1, kDisplayName1)).Run(); 579 580 chromeos::ExistingUserController* controller = 581 chromeos::ExistingUserController::current_controller(); 582 ASSERT_TRUE(controller); 583 controller->LoginAsPublicAccount(kAccountId1); 584 585 // Wait for the session to start. 586 NotificationWatcher(chrome::NOTIFICATION_SESSION_STARTED, 587 base::Bind(IsSessionStarted)).Run(); 588 589 // Check that the startup pages specified in policy were opened. 590 EXPECT_EQ(1U, chrome::GetTotalBrowserCount()); 591 Browser* browser = 592 chrome::FindLastActiveWithHostDesktopType(chrome::HOST_DESKTOP_TYPE_ASH); 593 ASSERT_TRUE(browser); 594 595 TabStripModel* tabs = browser->tab_strip_model(); 596 ASSERT_TRUE(tabs); 597 int expected_tab_count = static_cast<int>(arraysize(kStartupURLs)); 598 EXPECT_EQ(expected_tab_count, tabs->count()); 599 for (int i = 0; i < expected_tab_count && i < tabs->count(); ++i) 600 EXPECT_EQ(GURL(kStartupURLs[i]), tabs->GetWebContentsAt(i)->GetURL()); 601} 602 603} // namespace policy 604