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 "apps/shell_window.h" 6 #include "apps/shell_window_registry.h" 7 #include "apps/ui/native_app_window.h" 8 #include "ash/desktop_background/desktop_background_controller.h" 9 #include "ash/desktop_background/desktop_background_controller_observer.h" 10 #include "ash/shell.h" 11 #include "base/bind.h" 12 #include "base/bind_helpers.h" 13 #include "base/callback.h" 14 #include "base/command_line.h" 15 #include "base/location.h" 16 #include "base/memory/scoped_ptr.h" 17 #include "base/message_loop/message_loop.h" 18 #include "base/path_service.h" 19 #include "base/prefs/scoped_user_pref_update.h" 20 #include "chrome/browser/browser_process.h" 21 #include "chrome/browser/chrome_browser_main.h" 22 #include "chrome/browser/chrome_browser_main_extra_parts.h" 23 #include "chrome/browser/chrome_content_browser_client.h" 24 #include "chrome/browser/chrome_notification_types.h" 25 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h" 26 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" 27 #include "chrome/browser/chromeos/login/app_launch_controller.h" 28 #include "chrome/browser/chromeos/login/app_launch_signin_screen.h" 29 #include "chrome/browser/chromeos/login/existing_user_controller.h" 30 #include "chrome/browser/chromeos/login/fake_user_manager.h" 31 #include "chrome/browser/chromeos/login/login_display_host_impl.h" 32 #include "chrome/browser/chromeos/login/mock_user_manager.h" 33 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h" 34 #include "chrome/browser/chromeos/login/webui_login_display.h" 35 #include "chrome/browser/chromeos/login/wizard_controller.h" 36 #include "chrome/browser/chromeos/net/network_portal_detector_test_impl.h" 37 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h" 38 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h" 39 #include "chrome/browser/chromeos/settings/cros_settings.h" 40 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h" 41 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h" 42 #include "chrome/browser/extensions/extension_service.h" 43 #include "chrome/browser/extensions/extension_system.h" 44 #include "chrome/browser/extensions/extension_test_message_listener.h" 45 #include "chrome/browser/lifetime/application_lifetime.h" 46 #include "chrome/browser/profiles/profile_manager.h" 47 #include "chrome/browser/ui/browser.h" 48 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 49 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" 50 #include "chrome/common/chrome_paths.h" 51 #include "chrome/common/chrome_switches.h" 52 #include "chrome/common/pref_names.h" 53 #include "chrome/test/base/in_process_browser_test.h" 54 #include "chrome/test/base/interactive_test_utils.h" 55 #include "chrome/test/base/ui_test_utils.h" 56 #include "chromeos/chromeos_switches.h" 57 #include "chromeos/settings/cros_settings_names.h" 58 #include "components/policy/core/common/cloud/policy_builder.h" 59 #include "content/public/browser/notification_observer.h" 60 #include "content/public/browser/notification_registrar.h" 61 #include "content/public/browser/notification_service.h" 62 #include "content/public/test/browser_test_utils.h" 63 #include "content/public/test/test_utils.h" 64 #include "extensions/common/extension.h" 65 #include "google_apis/gaia/fake_gaia.h" 66 #include "google_apis/gaia/gaia_constants.h" 67 #include "google_apis/gaia/gaia_switches.h" 68 #include "google_apis/gaia/gaia_urls.h" 69 #include "net/base/network_change_notifier.h" 70 #include "net/dns/mock_host_resolver.h" 71 #include "net/test/embedded_test_server/embedded_test_server.h" 72 #include "net/test/embedded_test_server/http_request.h" 73 #include "net/test/embedded_test_server/http_response.h" 74 #include "testing/gmock/include/gmock/gmock.h" 75 #include "testing/gtest/include/gtest/gtest.h" 76 #include "ui/aura/window.h" 77 #include "ui/compositor/layer.h" 78 79 namespace em = enterprise_management; 80 81 namespace chromeos { 82 83 namespace { 84 85 // This is a simple test app that creates an app window and immediately closes 86 // it again. Webstore data json is in 87 // chrome/test/data/chromeos/app_mode/webstore/inlineinstall/ 88 // detail/ggbflgnkafappblpkiflbgpmkfdpnhhe 89 const char kTestKioskApp[] = "ggbflgnkafappblpkiflbgpmkfdpnhhe"; 90 91 // This app creates a window and declares usage of the identity API in its 92 // manifest, so we can test device robot token minting via the identity API. 93 // Webstore data json is in 94 // chrome/test/data/chromeos/app_mode/webstore/inlineinstall/ 95 // detail/ibjkkfdnfcaoapcpheeijckmpcfkifob 96 const char kTestEnterpriseKioskApp[] = "ibjkkfdnfcaoapcpheeijckmpcfkifob"; 97 98 // Timeout while waiting for network connectivity during tests. 99 const int kTestNetworkTimeoutSeconds = 1; 100 101 // Email of owner account for test. 102 const char kTestOwnerEmail[] = "owner (at) example.com"; 103 104 const char kTestEnterpriseAccountId[] = "enterprise-kiosk-app@localhost"; 105 const char kTestEnterpriseServiceAccountId[] = "service_account (at) example.com"; 106 const char kTestRefreshToken[] = "fake-refresh-token"; 107 const char kTestUserinfoToken[] = "fake-userinfo-token"; 108 const char kTestLoginToken[] = "fake-login-token"; 109 const char kTestAccessToken[] = "fake-access-token"; 110 const char kTestClientId[] = "fake-client-id"; 111 const char kTestAppScope[] = 112 "https://www.googleapis.com/auth/userinfo.profile"; 113 114 // Note the path name must be the same as in shill stub. 115 const char kStubEthernetServicePath[] = "eth1"; 116 117 // Helper function for GetConsumerKioskModeStatusCallback. 118 void ConsumerKioskModeStatusCheck( 119 KioskAppManager::ConsumerKioskModeStatus* out_status, 120 const base::Closure& runner_quit_task, 121 KioskAppManager::ConsumerKioskModeStatus in_status) { 122 LOG(INFO) << "KioskAppManager::ConsumerKioskModeStatus = " << in_status; 123 *out_status = in_status; 124 runner_quit_task.Run(); 125 } 126 127 // Helper KioskAppManager::EnableKioskModeCallback implementation. 128 void ConsumerKioskModeLockCheck( 129 bool* out_locked, 130 const base::Closure& runner_quit_task, 131 bool in_locked) { 132 LOG(INFO) << "kiosk locked = " << in_locked; 133 *out_locked = in_locked; 134 runner_quit_task.Run(); 135 } 136 137 // Helper function for WaitForNetworkTimeOut. 138 void OnNetworkWaitTimedOut(const base::Closure& runner_quit_task) { 139 runner_quit_task.Run(); 140 } 141 142 // Helper function for DeviceOAuth2TokenServiceFactory::Get(). 143 void CopyTokenService(DeviceOAuth2TokenService** out_token_service, 144 DeviceOAuth2TokenService* in_token_service) { 145 *out_token_service = in_token_service; 146 } 147 148 // Helper functions for CanConfigureNetwork mock. 149 class ScopedCanConfigureNetwork { 150 public: 151 ScopedCanConfigureNetwork(bool can_configure, bool needs_owner_auth) 152 : can_configure_(can_configure), 153 needs_owner_auth_(needs_owner_auth), 154 can_configure_network_callback_( 155 base::Bind(&ScopedCanConfigureNetwork::CanConfigureNetwork, 156 base::Unretained(this))), 157 needs_owner_auth_callback_(base::Bind( 158 &ScopedCanConfigureNetwork::NeedsOwnerAuthToConfigureNetwork, 159 base::Unretained(this))) { 160 AppLaunchController::SetCanConfigureNetworkCallbackForTesting( 161 &can_configure_network_callback_); 162 AppLaunchController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting( 163 &needs_owner_auth_callback_); 164 } 165 ~ScopedCanConfigureNetwork() { 166 AppLaunchController::SetCanConfigureNetworkCallbackForTesting(NULL); 167 AppLaunchController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting( 168 NULL); 169 } 170 171 bool CanConfigureNetwork() { 172 return can_configure_; 173 } 174 175 bool NeedsOwnerAuthToConfigureNetwork() { 176 return needs_owner_auth_; 177 } 178 179 private: 180 bool can_configure_; 181 bool needs_owner_auth_; 182 AppLaunchController::ReturnBoolCallback can_configure_network_callback_; 183 AppLaunchController::ReturnBoolCallback needs_owner_auth_callback_; 184 DISALLOW_COPY_AND_ASSIGN(ScopedCanConfigureNetwork); 185 }; 186 187 } // namespace 188 189 // Helper class that monitors app windows to wait for a window to appear. 190 class ShellWindowObserver : public apps::ShellWindowRegistry::Observer { 191 public: 192 ShellWindowObserver(apps::ShellWindowRegistry* registry, 193 const std::string& app_id) 194 : registry_(registry), app_id_(app_id), window_(NULL), running_(false) { 195 registry_->AddObserver(this); 196 } 197 virtual ~ShellWindowObserver() { 198 registry_->RemoveObserver(this); 199 } 200 201 apps::ShellWindow* Wait() { 202 running_ = true; 203 message_loop_runner_ = new content::MessageLoopRunner; 204 message_loop_runner_->Run(); 205 EXPECT_TRUE(window_); 206 return window_; 207 } 208 209 // ShellWindowRegistry::Observer 210 virtual void OnShellWindowAdded(apps::ShellWindow* shell_window) OVERRIDE { 211 if (!running_) 212 return; 213 214 if (shell_window->extension_id() == app_id_) { 215 window_ = shell_window; 216 message_loop_runner_->Quit(); 217 running_ = false; 218 } 219 } 220 virtual void OnShellWindowIconChanged( 221 apps::ShellWindow* shell_window) OVERRIDE {} 222 virtual void OnShellWindowRemoved(apps::ShellWindow* shell_window) OVERRIDE {} 223 224 private: 225 apps::ShellWindowRegistry* registry_; 226 std::string app_id_; 227 scoped_refptr<content::MessageLoopRunner> message_loop_runner_; 228 apps::ShellWindow* window_; 229 bool running_; 230 231 DISALLOW_COPY_AND_ASSIGN(ShellWindowObserver); 232 }; 233 234 class KioskTest : public InProcessBrowserTest { 235 public: 236 KioskTest() { 237 set_exit_when_last_browser_closes(false); 238 } 239 240 virtual ~KioskTest() {} 241 242 protected: 243 virtual void SetUp() OVERRIDE { 244 base::FilePath test_data_dir; 245 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); 246 embedded_test_server()->ServeFilesFromDirectory(test_data_dir); 247 embedded_test_server()->RegisterRequestHandler( 248 base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_))); 249 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 250 // Stop IO thread here because no threads are allowed while 251 // spawning sandbox host process. See crbug.com/322732. 252 embedded_test_server()->StopThread(); 253 254 mock_user_manager_.reset(new MockUserManager); 255 AppLaunchController::SkipSplashWaitForTesting(); 256 AppLaunchController::SetNetworkWaitForTesting(kTestNetworkTimeoutSeconds); 257 258 InProcessBrowserTest::SetUp(); 259 } 260 261 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 262 host_resolver()->AddRule("*", "127.0.0.1"); 263 264 network_portal_detector_ = new NetworkPortalDetectorTestImpl(); 265 NetworkPortalDetector::InitializeForTesting(network_portal_detector_); 266 network_portal_detector_->SetDefaultNetworkPathForTesting( 267 kStubEthernetServicePath); 268 } 269 270 virtual void SetUpOnMainThread() OVERRIDE { 271 // Restart the thread as the sandbox host process has already been spawned. 272 embedded_test_server()->RestartThreadAndListen(); 273 } 274 275 virtual void CleanUpOnMainThread() OVERRIDE { 276 AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL); 277 AppLaunchSigninScreen::SetUserManagerForTesting(NULL); 278 279 // If the login display is still showing, exit gracefully. 280 if (LoginDisplayHostImpl::default_host()) { 281 base::MessageLoop::current()->PostTask(FROM_HERE, 282 base::Bind(&chrome::AttemptExit)); 283 content::RunMessageLoop(); 284 } 285 286 // Clean up while main thread still runs. 287 // See http://crbug.com/176659. 288 KioskAppManager::Get()->CleanUp(); 289 } 290 291 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 292 command_line->AppendSwitch(chromeos::switches::kLoginManager); 293 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); 294 command_line->AppendSwitch(::switches::kDisableBackgroundNetworking); 295 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user"); 296 297 // Create gaia and webstore URL from test server url but using different 298 // host names. This is to avoid gaia response being tagged as from 299 // webstore in chrome_resource_dispatcher_host_delegate.cc. 300 const GURL& server_url = embedded_test_server()->base_url(); 301 302 std::string gaia_host("gaia"); 303 GURL::Replacements replace_gaia_host; 304 replace_gaia_host.SetHostStr(gaia_host); 305 GURL gaia_url = server_url.ReplaceComponents(replace_gaia_host); 306 command_line->AppendSwitchASCII(::switches::kGaiaUrl, gaia_url.spec()); 307 command_line->AppendSwitchASCII(::switches::kLsoUrl, gaia_url.spec()); 308 command_line->AppendSwitchASCII(::switches::kGoogleApisUrl, 309 gaia_url.spec()); 310 311 std::string webstore_host("webstore"); 312 GURL::Replacements replace_webstore_host; 313 replace_webstore_host.SetHostStr(webstore_host); 314 GURL webstore_url = server_url.ReplaceComponents(replace_webstore_host); 315 command_line->AppendSwitchASCII( 316 ::switches::kAppsGalleryURL, 317 webstore_url.Resolve("/chromeos/app_mode/webstore").spec()); 318 command_line->AppendSwitchASCII( 319 ::switches::kAppsGalleryDownloadURL, 320 webstore_url.Resolve( 321 "/chromeos/app_mode/webstore/downloads/%s.crx").spec()); 322 } 323 324 void ReloadKioskApps() { 325 KioskAppManager::Get()->AddApp(kTestKioskApp); 326 } 327 328 void ReloadAutolaunchKioskApps() { 329 KioskAppManager::Get()->AddApp(kTestKioskApp); 330 KioskAppManager::Get()->SetAutoLaunchApp(kTestKioskApp); 331 } 332 333 void StartAppLaunchFromLoginScreen(const base::Closure& network_setup_cb) { 334 EnableConsumerKioskMode(); 335 336 // Start UI, find menu entry for this app and launch it. 337 content::WindowedNotificationObserver login_signal( 338 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, 339 content::NotificationService::AllSources()); 340 chromeos::WizardController::SkipPostLoginScreensForTesting(); 341 chromeos::WizardController* wizard_controller = 342 chromeos::WizardController::default_controller(); 343 CHECK(wizard_controller); 344 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 345 login_signal.Wait(); 346 347 // Wait for the Kiosk App configuration to reload, then launch the app. 348 content::WindowedNotificationObserver apps_loaded_signal( 349 chrome::NOTIFICATION_KIOSK_APPS_LOADED, 350 content::NotificationService::AllSources()); 351 ReloadKioskApps(); 352 apps_loaded_signal.Wait(); 353 354 if (!network_setup_cb.is_null()) 355 network_setup_cb.Run(); 356 357 GetLoginUI()->CallJavascriptFunction( 358 "login.AppsMenuButton.runAppForTesting", 359 base::StringValue(kTestKioskApp)); 360 } 361 362 void WaitForAppLaunchSuccess() { 363 SimulateNetworkOnline(); 364 365 ExtensionTestMessageListener 366 launch_data_check_listener("launchData.isKioskSession = true", false); 367 368 // Wait for the Kiosk App to launch. 369 content::WindowedNotificationObserver( 370 chrome::NOTIFICATION_KIOSK_APP_LAUNCHED, 371 content::NotificationService::AllSources()).Wait(); 372 373 // Default profile switches to app profile after app is launched. 374 Profile* app_profile = ProfileManager::GetPrimaryUserProfile(); 375 ASSERT_TRUE(app_profile); 376 377 // Check installer status. 378 EXPECT_EQ(chromeos::KioskAppLaunchError::NONE, 379 chromeos::KioskAppLaunchError::Get()); 380 381 // Check if the kiosk webapp is really installed for the default profile. 382 const extensions::Extension* app = 383 extensions::ExtensionSystem::Get(app_profile)-> 384 extension_service()->GetInstalledExtension(kTestKioskApp); 385 EXPECT_TRUE(app); 386 387 // App should appear with its window. 388 apps::ShellWindowRegistry* shell_window_registry = 389 apps::ShellWindowRegistry::Get(app_profile); 390 apps::ShellWindow* window = 391 ShellWindowObserver(shell_window_registry, kTestKioskApp).Wait(); 392 EXPECT_TRUE(window); 393 394 // Login screen should be gone or fading out. 395 chromeos::LoginDisplayHost* login_display_host = 396 chromeos::LoginDisplayHostImpl::default_host(); 397 EXPECT_TRUE( 398 login_display_host == NULL || 399 login_display_host->GetNativeWindow()->layer()->GetTargetOpacity() == 400 0.0f); 401 402 // Wait until the app terminates if it is still running. 403 if (!shell_window_registry->GetShellWindowsForApp(kTestKioskApp).empty()) 404 content::RunMessageLoop(); 405 406 // Check that the app had been informed that it is running in a kiosk 407 // session. 408 EXPECT_TRUE(launch_data_check_listener.was_satisfied()); 409 } 410 411 void SimulateNetworkOffline() { 412 NetworkPortalDetector::CaptivePortalState offline_state; 413 offline_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE; 414 network_portal_detector_->SetDetectionResultsForTesting( 415 kStubEthernetServicePath, offline_state); 416 network_portal_detector_->NotifyObserversForTesting(); 417 } 418 419 base::Closure SimulateNetworkOfflineClosure() { 420 return base::Bind(&KioskTest::SimulateNetworkOffline, 421 base::Unretained(this)); 422 } 423 424 void SimulateNetworkOnline() { 425 NetworkPortalDetector::CaptivePortalState online_state; 426 online_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE; 427 online_state.response_code = 204; 428 network_portal_detector_->SetDetectionResultsForTesting( 429 kStubEthernetServicePath, online_state); 430 network_portal_detector_->NotifyObserversForTesting(); 431 } 432 433 base::Closure SimulateNetworkOnlineClosure() { 434 return base::Bind(&KioskTest::SimulateNetworkOnline, 435 base::Unretained(this)); 436 } 437 438 void SimulateNetworkPortal() { 439 NetworkPortalDetector::CaptivePortalState portal_state; 440 portal_state.status = NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL; 441 network_portal_detector_->SetDetectionResultsForTesting( 442 kStubEthernetServicePath, portal_state); 443 network_portal_detector_->NotifyObserversForTesting(); 444 } 445 446 base::Closure SimulateNetworkPortalClosure() { 447 return base::Bind(&KioskTest::SimulateNetworkPortal, 448 base::Unretained(this)); 449 } 450 451 void WaitForAppLaunchNetworkTimeout() { 452 if (GetAppLaunchController()->network_wait_timedout()) 453 return; 454 455 scoped_refptr<content::MessageLoopRunner> runner = 456 new content::MessageLoopRunner; 457 458 base::Closure callback = base::Bind( 459 &OnNetworkWaitTimedOut, runner->QuitClosure()); 460 AppLaunchController::SetNetworkTimeoutCallbackForTesting(&callback); 461 462 runner->Run(); 463 464 CHECK(GetAppLaunchController()->network_wait_timedout()); 465 AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL); 466 } 467 468 void EnableConsumerKioskMode() { 469 scoped_ptr<bool> locked(new bool(false)); 470 scoped_refptr<content::MessageLoopRunner> runner = 471 new content::MessageLoopRunner; 472 KioskAppManager::Get()->EnableConsumerModeKiosk( 473 base::Bind(&ConsumerKioskModeLockCheck, 474 locked.get(), 475 runner->QuitClosure())); 476 runner->Run(); 477 EXPECT_TRUE(*locked.get()); 478 } 479 480 KioskAppManager::ConsumerKioskModeStatus GetConsumerKioskModeStatus() { 481 KioskAppManager::ConsumerKioskModeStatus status = 482 static_cast<KioskAppManager::ConsumerKioskModeStatus>(-1); 483 scoped_refptr<content::MessageLoopRunner> runner = 484 new content::MessageLoopRunner; 485 KioskAppManager::Get()->GetConsumerKioskModeStatus( 486 base::Bind(&ConsumerKioskModeStatusCheck, 487 &status, 488 runner->QuitClosure())); 489 runner->Run(); 490 CHECK_NE(status, static_cast<KioskAppManager::ConsumerKioskModeStatus>(-1)); 491 return status; 492 } 493 494 void JsExpect(const std::string& expression) { 495 bool result; 496 ASSERT_TRUE(content::ExecuteScriptAndExtractBool( 497 GetLoginUI()->GetWebContents(), 498 "window.domAutomationController.send(!!(" + expression + "));", 499 &result)); 500 ASSERT_TRUE(result) << expression; 501 } 502 503 content::WebUI* GetLoginUI() { 504 return static_cast<chromeos::LoginDisplayHostImpl*>( 505 chromeos::LoginDisplayHostImpl::default_host())->GetOobeUI()->web_ui(); 506 } 507 508 SigninScreenHandler* GetSigninScreenHandler() { 509 return static_cast<chromeos::LoginDisplayHostImpl*>( 510 chromeos::LoginDisplayHostImpl::default_host()) 511 ->GetOobeUI() 512 ->signin_screen_handler_for_test(); 513 } 514 515 AppLaunchController* GetAppLaunchController() { 516 return chromeos::LoginDisplayHostImpl::default_host() 517 ->GetAppLaunchController(); 518 } 519 520 FakeGaia fake_gaia_; 521 scoped_ptr<MockUserManager> mock_user_manager_; 522 NetworkPortalDetectorTestImpl* network_portal_detector_; 523 }; 524 525 IN_PROC_BROWSER_TEST_F(KioskTest, InstallAndLaunchApp) { 526 StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure()); 527 WaitForAppLaunchSuccess(); 528 } 529 530 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkDown) { 531 // Mock network could be configured with owner's password. 532 ScopedCanConfigureNetwork can_configure_network(true, true); 533 534 // Start app launch and wait for network connectivity timeout. 535 StartAppLaunchFromLoginScreen(SimulateNetworkOfflineClosure()); 536 OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH); 537 splash_waiter.Wait(); 538 WaitForAppLaunchNetworkTimeout(); 539 540 // Configure network link should be visible. 541 JsExpect("$('splash-config-network').hidden == false"); 542 543 // Set up fake user manager with an owner for the test. 544 mock_user_manager_->SetActiveUser(kTestOwnerEmail); 545 AppLaunchSigninScreen::SetUserManagerForTesting(mock_user_manager_.get()); 546 static_cast<LoginDisplayHostImpl*>(LoginDisplayHostImpl::default_host()) 547 ->GetOobeUI()->ShowOobeUI(false); 548 549 // Configure network should bring up lock screen for owner. 550 OobeScreenWaiter lock_screen_waiter(OobeDisplay::SCREEN_ACCOUNT_PICKER); 551 static_cast<AppLaunchSplashScreenActor::Delegate*>(GetAppLaunchController()) 552 ->OnConfigureNetwork(); 553 lock_screen_waiter.Wait(); 554 555 // A network error screen should be shown after authenticating. 556 OobeScreenWaiter error_screen_waiter(OobeDisplay::SCREEN_ERROR_MESSAGE); 557 static_cast<AppLaunchSigninScreen::Delegate*>(GetAppLaunchController()) 558 ->OnOwnerSigninSuccess(); 559 error_screen_waiter.Wait(); 560 561 ASSERT_TRUE(GetAppLaunchController()->showing_network_dialog()); 562 563 WaitForAppLaunchSuccess(); 564 } 565 566 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkDownConfigureNotAllowed) { 567 // Mock network could not be configured. 568 ScopedCanConfigureNetwork can_configure_network(false, true); 569 570 // Start app launch and wait for network connectivity timeout. 571 StartAppLaunchFromLoginScreen(SimulateNetworkOfflineClosure()); 572 OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH); 573 splash_waiter.Wait(); 574 WaitForAppLaunchNetworkTimeout(); 575 576 // Configure network link should not be visible. 577 JsExpect("$('splash-config-network').hidden == true"); 578 579 // Network becomes online and app launch is resumed. 580 WaitForAppLaunchSuccess(); 581 } 582 583 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkPortal) { 584 // Mock network could be configured without the owner password. 585 ScopedCanConfigureNetwork can_configure_network(true, false); 586 587 // Start app launch with network portal state. 588 StartAppLaunchFromLoginScreen(SimulateNetworkPortalClosure()); 589 OobeScreenWaiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH) 590 .WaitNoAssertCurrentScreen(); 591 WaitForAppLaunchNetworkTimeout(); 592 593 // Network error should show up automatically since this test does not 594 // require owner auth to configure network. 595 OobeScreenWaiter(OobeDisplay::SCREEN_ERROR_MESSAGE).Wait(); 596 597 ASSERT_TRUE(GetAppLaunchController()->showing_network_dialog()); 598 WaitForAppLaunchSuccess(); 599 } 600 601 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppUserCancel) { 602 StartAppLaunchFromLoginScreen(SimulateNetworkOfflineClosure()); 603 OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH); 604 splash_waiter.Wait(); 605 606 CrosSettings::Get()->SetBoolean( 607 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, true); 608 content::WindowedNotificationObserver signal( 609 chrome::NOTIFICATION_APP_TERMINATING, 610 content::NotificationService::AllSources()); 611 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator", 612 base::StringValue("app_launch_bailout")); 613 signal.Wait(); 614 EXPECT_EQ(chromeos::KioskAppLaunchError::USER_CANCEL, 615 chromeos::KioskAppLaunchError::Get()); 616 } 617 618 IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningCancel) { 619 EnableConsumerKioskMode(); 620 // Start UI, find menu entry for this app and launch it. 621 chromeos::WizardController::SkipPostLoginScreensForTesting(); 622 chromeos::WizardController* wizard_controller = 623 chromeos::WizardController::default_controller(); 624 CHECK(wizard_controller); 625 ReloadAutolaunchKioskApps(); 626 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 627 628 EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty()); 629 EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled()); 630 631 // Wait for the auto launch warning come up. 632 content::WindowedNotificationObserver( 633 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE, 634 content::NotificationService::AllSources()).Wait(); 635 GetLoginUI()->CallJavascriptFunction( 636 "login.AutolaunchScreen.confirmAutoLaunchForTesting", 637 base::FundamentalValue(false)); 638 639 // Wait for the auto launch warning to go away. 640 content::WindowedNotificationObserver( 641 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED, 642 content::NotificationService::AllSources()).Wait(); 643 644 EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled()); 645 } 646 647 IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningConfirm) { 648 EnableConsumerKioskMode(); 649 // Start UI, find menu entry for this app and launch it. 650 chromeos::WizardController::SkipPostLoginScreensForTesting(); 651 chromeos::WizardController* wizard_controller = 652 chromeos::WizardController::default_controller(); 653 CHECK(wizard_controller); 654 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 655 656 ReloadAutolaunchKioskApps(); 657 EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty()); 658 EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled()); 659 660 // Wait for the auto launch warning come up. 661 content::WindowedNotificationObserver( 662 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE, 663 content::NotificationService::AllSources()).Wait(); 664 GetLoginUI()->CallJavascriptFunction( 665 "login.AutolaunchScreen.confirmAutoLaunchForTesting", 666 base::FundamentalValue(true)); 667 668 // Wait for the auto launch warning to go away. 669 content::WindowedNotificationObserver( 670 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED, 671 content::NotificationService::AllSources()).Wait(); 672 673 EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty()); 674 EXPECT_TRUE(KioskAppManager::Get()->IsAutoLaunchEnabled()); 675 676 WaitForAppLaunchSuccess(); 677 } 678 679 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableCancel) { 680 chromeos::WizardController::SkipPostLoginScreensForTesting(); 681 chromeos::WizardController* wizard_controller = 682 chromeos::WizardController::default_controller(); 683 CHECK(wizard_controller); 684 685 // Check Kiosk mode status. 686 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE, 687 GetConsumerKioskModeStatus()); 688 689 // Wait for the login UI to come up and switch to the kiosk_enable screen. 690 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 691 content::WindowedNotificationObserver( 692 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, 693 content::NotificationService::AllSources()).Wait(); 694 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator", 695 base::StringValue("kiosk_enable")); 696 697 // Wait for the kiosk_enable screen to show and cancel the screen. 698 content::WindowedNotificationObserver( 699 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE, 700 content::NotificationService::AllSources()).Wait(); 701 GetLoginUI()->CallJavascriptFunction( 702 "login.KioskEnableScreen.enableKioskForTesting", 703 base::FundamentalValue(false)); 704 705 // Wait for the kiosk_enable screen to disappear. 706 content::WindowedNotificationObserver( 707 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED, 708 content::NotificationService::AllSources()).Wait(); 709 710 // Check that the status still says configurable. 711 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE, 712 GetConsumerKioskModeStatus()); 713 } 714 715 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableConfirmed) { 716 // Start UI, find menu entry for this app and launch it. 717 chromeos::WizardController::SkipPostLoginScreensForTesting(); 718 chromeos::WizardController* wizard_controller = 719 chromeos::WizardController::default_controller(); 720 CHECK(wizard_controller); 721 722 // Check Kiosk mode status. 723 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE, 724 GetConsumerKioskModeStatus()); 725 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 726 727 // Wait for the login UI to come up and switch to the kiosk_enable screen. 728 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 729 content::WindowedNotificationObserver( 730 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, 731 content::NotificationService::AllSources()).Wait(); 732 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator", 733 base::StringValue("kiosk_enable")); 734 735 // Wait for the kiosk_enable screen to show and cancel the screen. 736 content::WindowedNotificationObserver( 737 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE, 738 content::NotificationService::AllSources()).Wait(); 739 GetLoginUI()->CallJavascriptFunction( 740 "login.KioskEnableScreen.enableKioskForTesting", 741 base::FundamentalValue(true)); 742 743 // Wait for the signal that indicates Kiosk Mode is enabled. 744 content::WindowedNotificationObserver( 745 chrome::NOTIFICATION_KIOSK_ENABLED, 746 content::NotificationService::AllSources()).Wait(); 747 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_ENABLED, 748 GetConsumerKioskModeStatus()); 749 } 750 751 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableAbortedWithAutoEnrollment) { 752 // Fake an auto enrollment is going to be enforced. 753 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 754 switches::kEnterpriseEnrollmentInitialModulus, "1"); 755 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 756 switches::kEnterpriseEnrollmentModulusLimit, "2"); 757 g_browser_process->local_state()->SetBoolean(prefs::kShouldAutoEnroll, true); 758 g_browser_process->local_state()->SetInteger( 759 prefs::kAutoEnrollmentPowerLimit, 3); 760 761 // Start UI, find menu entry for this app and launch it. 762 chromeos::WizardController::SkipPostLoginScreensForTesting(); 763 chromeos::WizardController* wizard_controller = 764 chromeos::WizardController::default_controller(); 765 CHECK(wizard_controller); 766 767 // Check Kiosk mode status. 768 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE, 769 GetConsumerKioskModeStatus()); 770 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 771 772 // Wait for the login UI to come up and switch to the kiosk_enable screen. 773 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 774 content::WindowedNotificationObserver( 775 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, 776 content::NotificationService::AllSources()).Wait(); 777 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator", 778 base::StringValue("kiosk_enable")); 779 780 // The flow should be aborted due to auto enrollment enforcement. 781 scoped_refptr<content::MessageLoopRunner> runner = 782 new content::MessageLoopRunner; 783 GetSigninScreenHandler()->set_kiosk_enable_flow_aborted_callback_for_test( 784 runner->QuitClosure()); 785 runner->Run(); 786 } 787 788 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableAfter2ndSigninScreen) { 789 // Fake an auto enrollment is not going to be enforced. 790 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 791 switches::kEnterpriseEnrollmentInitialModulus, "1"); 792 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 793 switches::kEnterpriseEnrollmentModulusLimit, "2"); 794 g_browser_process->local_state()->SetBoolean(prefs::kShouldAutoEnroll, false); 795 g_browser_process->local_state()->SetInteger( 796 prefs::kAutoEnrollmentPowerLimit, -1); 797 798 chromeos::WizardController::SkipPostLoginScreensForTesting(); 799 chromeos::WizardController* wizard_controller = 800 chromeos::WizardController::default_controller(); 801 CHECK(wizard_controller); 802 803 // Check Kiosk mode status. 804 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE, 805 GetConsumerKioskModeStatus()); 806 807 // Wait for the login UI to come up and switch to the kiosk_enable screen. 808 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 809 content::WindowedNotificationObserver( 810 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, 811 content::NotificationService::AllSources()).Wait(); 812 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator", 813 base::StringValue("kiosk_enable")); 814 815 // Wait for the kiosk_enable screen to show and cancel the screen. 816 content::WindowedNotificationObserver( 817 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE, 818 content::NotificationService::AllSources()).Wait(); 819 GetLoginUI()->CallJavascriptFunction( 820 "login.KioskEnableScreen.enableKioskForTesting", 821 base::FundamentalValue(false)); 822 823 // Wait for the kiosk_enable screen to disappear. 824 content::WindowedNotificationObserver( 825 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED, 826 content::NotificationService::AllSources()).Wait(); 827 828 // Show signin screen again. 829 chromeos::LoginDisplayHostImpl::default_host()->StartSignInScreen( 830 LoginScreenContext()); 831 OobeScreenWaiter(OobeDisplay::SCREEN_GAIA_SIGNIN).Wait(); 832 833 // Show kiosk enable screen again. 834 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator", 835 base::StringValue("kiosk_enable")); 836 837 // And it should show up. 838 content::WindowedNotificationObserver( 839 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE, 840 content::NotificationService::AllSources()).Wait(); 841 } 842 843 class KioskEnterpriseTest : public KioskTest { 844 protected: 845 KioskEnterpriseTest() {} 846 847 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 848 device_policy_test_helper_.MarkAsEnterpriseOwned(); 849 device_policy_test_helper_.InstallOwnerKey(); 850 851 KioskTest::SetUpInProcessBrowserTestFixture(); 852 } 853 854 virtual void SetUpOnMainThread() OVERRIDE { 855 KioskTest::SetUpOnMainThread(); 856 // Configure kTestEnterpriseKioskApp in device policy. 857 em::DeviceLocalAccountsProto* accounts = 858 device_policy_test_helper_.device_policy()->payload() 859 .mutable_device_local_accounts(); 860 em::DeviceLocalAccountInfoProto* account = accounts->add_account(); 861 account->set_account_id(kTestEnterpriseAccountId); 862 account->set_type( 863 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP); 864 account->mutable_kiosk_app()->set_app_id(kTestEnterpriseKioskApp); 865 accounts->set_auto_login_id(kTestEnterpriseAccountId); 866 em::PolicyData& policy_data = 867 device_policy_test_helper_.device_policy()->policy_data(); 868 policy_data.set_service_account_identity(kTestEnterpriseServiceAccountId); 869 device_policy_test_helper_.device_policy()->Build(); 870 DBusThreadManager::Get()->GetSessionManagerClient()->StoreDevicePolicy( 871 device_policy_test_helper_.device_policy()->GetBlob(), 872 base::Bind(&KioskEnterpriseTest::StorePolicyCallback)); 873 874 DeviceSettingsService::Get()->Load(); 875 876 // Configure OAuth authentication. 877 GaiaUrls* gaia_urls = GaiaUrls::GetInstance(); 878 879 // This token satisfies the userinfo.email request from 880 // DeviceOAuth2TokenService used in token validation. 881 FakeGaia::AccessTokenInfo userinfo_token_info; 882 userinfo_token_info.token = kTestUserinfoToken; 883 userinfo_token_info.scopes.insert( 884 "https://www.googleapis.com/auth/userinfo.email"); 885 userinfo_token_info.audience = gaia_urls->oauth2_chrome_client_id(); 886 userinfo_token_info.email = kTestEnterpriseServiceAccountId; 887 fake_gaia_.IssueOAuthToken(kTestRefreshToken, userinfo_token_info); 888 889 // The any-api access token for accessing the token minting endpoint. 890 FakeGaia::AccessTokenInfo login_token_info; 891 login_token_info.token = kTestLoginToken; 892 login_token_info.scopes.insert(GaiaConstants::kAnyApiOAuth2Scope); 893 login_token_info.audience = gaia_urls->oauth2_chrome_client_id(); 894 fake_gaia_.IssueOAuthToken(kTestRefreshToken, login_token_info); 895 896 // This is the access token requested by the app via the identity API. 897 FakeGaia::AccessTokenInfo access_token_info; 898 access_token_info.token = kTestAccessToken; 899 access_token_info.scopes.insert(kTestAppScope); 900 access_token_info.audience = kTestClientId; 901 access_token_info.email = kTestEnterpriseServiceAccountId; 902 fake_gaia_.IssueOAuthToken(kTestLoginToken, access_token_info); 903 904 DeviceOAuth2TokenService* token_service = NULL; 905 DeviceOAuth2TokenServiceFactory::Get( 906 base::Bind(&CopyTokenService, &token_service)); 907 base::RunLoop().RunUntilIdle(); 908 ASSERT_TRUE(token_service); 909 token_service->SetAndSaveRefreshToken(kTestRefreshToken); 910 } 911 912 static void StorePolicyCallback(bool result) { 913 ASSERT_TRUE(result); 914 } 915 916 policy::DevicePolicyCrosTestHelper device_policy_test_helper_; 917 918 private: 919 DISALLOW_COPY_AND_ASSIGN(KioskEnterpriseTest); 920 }; 921 922 IN_PROC_BROWSER_TEST_F(KioskEnterpriseTest, EnterpriseKioskApp) { 923 chromeos::WizardController::SkipPostLoginScreensForTesting(); 924 chromeos::WizardController* wizard_controller = 925 chromeos::WizardController::default_controller(); 926 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 927 928 // Wait for the Kiosk App configuration to reload, then launch the app. 929 KioskAppManager::App app; 930 content::WindowedNotificationObserver( 931 chrome::NOTIFICATION_KIOSK_APPS_LOADED, 932 base::Bind(&KioskAppManager::GetApp, 933 base::Unretained(KioskAppManager::Get()), 934 kTestEnterpriseKioskApp, &app)).Wait(); 935 936 GetLoginUI()->CallJavascriptFunction( 937 "login.AppsMenuButton.runAppForTesting", 938 base::StringValue(kTestEnterpriseKioskApp)); 939 940 // Wait for the Kiosk App to launch. 941 content::WindowedNotificationObserver( 942 chrome::NOTIFICATION_KIOSK_APP_LAUNCHED, 943 content::NotificationService::AllSources()).Wait(); 944 945 // Check installer status. 946 EXPECT_EQ(chromeos::KioskAppLaunchError::NONE, 947 chromeos::KioskAppLaunchError::Get()); 948 949 // Wait for the window to appear. 950 apps::ShellWindow* window = ShellWindowObserver( 951 apps::ShellWindowRegistry::Get(ProfileManager::GetPrimaryUserProfile()), 952 kTestEnterpriseKioskApp).Wait(); 953 ASSERT_TRUE(window); 954 955 // Check whether the app can retrieve an OAuth2 access token. 956 std::string result; 957 EXPECT_TRUE(content::ExecuteScriptAndExtractString( 958 window->web_contents(), 959 "chrome.identity.getAuthToken({ 'interactive': false }, function(token) {" 960 " window.domAutomationController.send(token);" 961 "});", 962 &result)); 963 EXPECT_EQ(kTestAccessToken, result); 964 965 // Terminate the app. 966 window->GetBaseWindow()->Close(); 967 content::RunAllPendingInMessageLoop(); 968 } 969 970 // Specialized test fixture for testing kiosk mode on the 971 // hidden WebUI initialization flow for slow hardware. 972 class KioskHiddenWebUITest : public KioskTest, 973 public ash::DesktopBackgroundControllerObserver { 974 public: 975 KioskHiddenWebUITest() : wallpaper_loaded_(false) {} 976 977 // KioskTest overrides: 978 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 979 KioskTest::SetUpCommandLine(command_line); 980 command_line->AppendSwitchASCII(switches::kDeviceRegistered, "1"); 981 command_line->AppendSwitch(switches::kDisableBootAnimation); 982 command_line->AppendSwitch(switches::kDisableOobeAnimation); 983 } 984 985 virtual void SetUpOnMainThread() OVERRIDE { 986 KioskTest::SetUpOnMainThread(); 987 ash::Shell::GetInstance()->desktop_background_controller() 988 ->AddObserver(this); 989 } 990 991 virtual void TearDownOnMainThread() OVERRIDE { 992 ash::Shell::GetInstance()->desktop_background_controller() 993 ->RemoveObserver(this); 994 KioskTest::TearDownOnMainThread(); 995 } 996 997 void WaitForWallpaper() { 998 if (!wallpaper_loaded_) { 999 runner_ = new content::MessageLoopRunner; 1000 runner_->Run(); 1001 } 1002 } 1003 1004 bool wallpaper_loaded() const { return wallpaper_loaded_; } 1005 1006 // ash::DesktopBackgroundControllerObserver overrides: 1007 virtual void OnWallpaperDataChanged() OVERRIDE { 1008 wallpaper_loaded_ = true; 1009 if (runner_.get()) 1010 runner_->Quit(); 1011 } 1012 1013 bool wallpaper_loaded_; 1014 scoped_refptr<content::MessageLoopRunner> runner_; 1015 1016 DISALLOW_COPY_AND_ASSIGN(KioskHiddenWebUITest); 1017 }; 1018 1019 IN_PROC_BROWSER_TEST_F(KioskHiddenWebUITest, AutolaunchWarning) { 1020 // Add a device owner. 1021 FakeUserManager* user_manager = new FakeUserManager(); 1022 user_manager->AddUser(kTestOwnerEmail); 1023 ScopedUserManagerEnabler enabler(user_manager); 1024 1025 // Set kiosk app to autolaunch. 1026 EnableConsumerKioskMode(); 1027 chromeos::WizardController::SkipPostLoginScreensForTesting(); 1028 chromeos::WizardController* wizard_controller = 1029 chromeos::WizardController::default_controller(); 1030 CHECK(wizard_controller); 1031 ReloadAutolaunchKioskApps(); 1032 wizard_controller->SkipToLoginForTesting(LoginScreenContext()); 1033 1034 EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty()); 1035 EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled()); 1036 1037 // Wait for the auto launch warning come up. 1038 content::WindowedNotificationObserver( 1039 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE, 1040 content::NotificationService::AllSources()).Wait(); 1041 1042 // Wait for the wallpaper to load. 1043 WaitForWallpaper(); 1044 EXPECT_TRUE(wallpaper_loaded()); 1045 } 1046 1047 } // namespace chromeos 1048