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 "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/command_line.h"
14 #include "base/location.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/path_service.h"
18 #include "base/prefs/scoped_user_pref_update.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/chrome_browser_main.h"
21 #include "chrome/browser/chrome_browser_main_extra_parts.h"
22 #include "chrome/browser/chrome_content_browser_client.h"
23 #include "chrome/browser/chrome_notification_types.h"
24 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
25 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
26 #include "chrome/browser/chromeos/login/app_launch_controller.h"
27 #include "chrome/browser/chromeos/login/app_launch_signin_screen.h"
28 #include "chrome/browser/chromeos/login/existing_user_controller.h"
29 #include "chrome/browser/chromeos/login/fake_user_manager.h"
30 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
31 #include "chrome/browser/chromeos/login/mock_user_manager.h"
32 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
33 #include "chrome/browser/chromeos/login/webui_login_display.h"
34 #include "chrome/browser/chromeos/login/wizard_controller.h"
35 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
36 #include "chrome/browser/chromeos/settings/cros_settings.h"
37 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
38 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
39 #include "chrome/browser/extensions/extension_service.h"
40 #include "chrome/browser/extensions/extension_system.h"
41 #include "chrome/browser/extensions/extension_test_message_listener.h"
42 #include "chrome/browser/lifetime/application_lifetime.h"
43 #include "chrome/browser/policy/cloud/policy_builder.h"
44 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h"
45 #include "chrome/browser/profiles/profile_manager.h"
46 #include "chrome/browser/ui/browser.h"
47 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
48 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
49 #include "chrome/common/chrome_paths.h"
50 #include "chrome/common/chrome_switches.h"
51 #include "chrome/common/extensions/extension.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 "content/public/browser/notification_observer.h"
59 #include "content/public/browser/notification_registrar.h"
60 #include "content/public/browser/notification_service.h"
61 #include "content/public/test/browser_test_utils.h"
62 #include "content/public/test/test_utils.h"
63 #include "google_apis/gaia/fake_gaia.h"
64 #include "google_apis/gaia/gaia_switches.h"
65 #include "net/base/network_change_notifier.h"
66 #include "net/dns/mock_host_resolver.h"
67 #include "net/test/embedded_test_server/embedded_test_server.h"
68 #include "net/test/embedded_test_server/http_request.h"
69 #include "net/test/embedded_test_server/http_response.h"
70 #include "testing/gmock/include/gmock/gmock.h"
71 #include "testing/gtest/include/gtest/gtest.h"
72 #include "ui/aura/window.h"
73 #include "ui/compositor/layer.h"
75 namespace em = enterprise_management;
81 // This is a simple test app that creates an app window and immediately closes
82 // it again. Webstore data json is in
83 // chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
84 // detail/ggbflgnkafappblpkiflbgpmkfdpnhhe
85 const char kTestKioskApp[] = "ggbflgnkafappblpkiflbgpmkfdpnhhe";
87 // This app creates a window and declares usage of the identity API in its
88 // manifest, so we can test device robot token minting via the identity API.
89 // Webstore data json is in
90 // chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
91 // detail/ibjkkfdnfcaoapcpheeijckmpcfkifob
92 const char kTestEnterpriseKioskApp[] = "ibjkkfdnfcaoapcpheeijckmpcfkifob";
94 // Timeout while waiting for network connectivity during tests.
95 const int kTestNetworkTimeoutSeconds = 1;
97 // Email of owner account for test.
98 const char kTestOwnerEmail[] = "owner@example.com";
100 const char kTestEnterpriseAccountId[] = "enterprise-kiosk-app@localhost";
101 const char kTestEnterpriseServiceAccountId[] = "service_account@example.com";
102 const char kTestRefreshToken[] = "fake-refresh-token";
103 const char kTestAccessToken[] = "fake-access-token";
105 // Helper function for GetConsumerKioskModeStatusCallback.
106 void ConsumerKioskModeStatusCheck(
107 KioskAppManager::ConsumerKioskModeStatus* out_status,
108 const base::Closure& runner_quit_task,
109 KioskAppManager::ConsumerKioskModeStatus in_status) {
110 LOG(INFO) << "KioskAppManager::ConsumerKioskModeStatus = " << in_status;
111 *out_status = in_status;
112 runner_quit_task.Run();
115 // Helper KioskAppManager::EnableKioskModeCallback implementation.
116 void ConsumerKioskModeLockCheck(
118 const base::Closure& runner_quit_task,
120 LOG(INFO) << "kiosk locked = " << in_locked;
121 *out_locked = in_locked;
122 runner_quit_task.Run();
125 // Helper function for WaitForNetworkTimeOut.
126 void OnNetworkWaitTimedOut(const base::Closure& runner_quit_task) {
127 runner_quit_task.Run();
130 // Helper function for DeviceOAuth2TokenServiceFactory::Get().
131 void CopyTokenService(DeviceOAuth2TokenService** out_token_service,
132 DeviceOAuth2TokenService* in_token_service) {
133 *out_token_service = in_token_service;
136 // Helper functions for CanConfigureNetwork mock.
137 class ScopedCanConfigureNetwork {
139 explicit ScopedCanConfigureNetwork(bool can_configure)
140 : can_configure_(can_configure),
141 callback_(base::Bind(&ScopedCanConfigureNetwork::CanConfigureNetwork,
142 base::Unretained(this))) {
143 AppLaunchController::SetCanConfigureNetworkCallbackForTesting(&callback_);
145 ~ScopedCanConfigureNetwork() {
146 AppLaunchController::SetCanConfigureNetworkCallbackForTesting(NULL);
149 bool CanConfigureNetwork() {
150 return can_configure_;
155 AppLaunchController::CanConfigureNetworkCallback callback_;
156 DISALLOW_COPY_AND_ASSIGN(ScopedCanConfigureNetwork);
161 // Fake NetworkChangeNotifier used to simulate network connectivity.
162 class FakeNetworkChangeNotifier : public net::NetworkChangeNotifier {
164 FakeNetworkChangeNotifier() : connection_type_(CONNECTION_NONE) {}
166 virtual ConnectionType GetCurrentConnectionType() const OVERRIDE {
167 return connection_type_;
171 SetConnectionType(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
175 SetConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE);
178 void SetConnectionType(ConnectionType type) {
179 connection_type_ = type;
180 NotifyObserversOfNetworkChange(type);
181 base::RunLoop().RunUntilIdle();
184 virtual ~FakeNetworkChangeNotifier() {}
187 ConnectionType connection_type_;
188 DISALLOW_COPY_AND_ASSIGN(FakeNetworkChangeNotifier);
191 // Helper class that monitors app windows to wait for a window to appear.
192 class ShellWindowObserver : public apps::ShellWindowRegistry::Observer {
194 ShellWindowObserver(apps::ShellWindowRegistry* registry,
195 const std::string& app_id)
196 : registry_(registry), app_id_(app_id), window_(NULL), running_(false) {
197 registry_->AddObserver(this);
199 virtual ~ShellWindowObserver() {
200 registry_->RemoveObserver(this);
203 apps::ShellWindow* Wait() {
205 message_loop_runner_ = new content::MessageLoopRunner;
206 message_loop_runner_->Run();
207 EXPECT_TRUE(window_);
211 // ShellWindowRegistry::Observer
212 virtual void OnShellWindowAdded(apps::ShellWindow* shell_window) OVERRIDE {
216 if (shell_window->extension_id() == app_id_) {
217 window_ = shell_window;
218 message_loop_runner_->Quit();
222 virtual void OnShellWindowIconChanged(
223 apps::ShellWindow* shell_window) OVERRIDE {}
224 virtual void OnShellWindowRemoved(apps::ShellWindow* shell_window) OVERRIDE {}
227 apps::ShellWindowRegistry* registry_;
229 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
230 apps::ShellWindow* window_;
233 DISALLOW_COPY_AND_ASSIGN(ShellWindowObserver);
236 class KioskTest : public InProcessBrowserTest {
239 set_exit_when_last_browser_closes(false);
242 virtual ~KioskTest() {}
245 virtual void SetUp() OVERRIDE {
246 base::FilePath test_data_dir;
247 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
248 embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
249 embedded_test_server()->RegisterRequestHandler(
250 base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_)));
251 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
253 mock_user_manager_.reset(new MockUserManager);
254 AppLaunchController::SkipSplashWaitForTesting();
255 AppLaunchController::SetNetworkWaitForTesting(kTestNetworkTimeoutSeconds);
257 InProcessBrowserTest::SetUp();
260 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
261 host_resolver()->AddRule("*", "127.0.0.1");
264 virtual void CleanUpOnMainThread() OVERRIDE {
265 // We need to clean up these objects in this specific order.
266 fake_network_notifier_.reset(NULL);
267 disable_network_notifier_.reset(NULL);
269 AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL);
270 AppLaunchSigninScreen::SetUserManagerForTesting(NULL);
272 // If the login display is still showing, exit gracefully.
273 if (LoginDisplayHostImpl::default_host()) {
274 base::MessageLoop::current()->PostTask(FROM_HERE,
275 base::Bind(&chrome::AttemptExit));
276 content::RunMessageLoop();
279 // Clean up while main thread still runs.
280 // See http://crbug.com/176659.
281 KioskAppManager::Get()->CleanUp();
284 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
285 command_line->AppendSwitch(chromeos::switches::kLoginManager);
286 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests);
287 command_line->AppendSwitch(
288 chromeos::switches::kDisableChromeCaptivePortalDetector);
289 command_line->AppendSwitch(::switches::kDisableBackgroundNetworking);
290 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user");
292 // Create gaia and webstore URL from test server url but using different
293 // host names. This is to avoid gaia response being tagged as from
294 // webstore in chrome_resource_dispatcher_host_delegate.cc.
295 const GURL& server_url = embedded_test_server()->base_url();
297 std::string gaia_host("gaia");
298 GURL::Replacements replace_gaia_host;
299 replace_gaia_host.SetHostStr(gaia_host);
300 GURL gaia_url = server_url.ReplaceComponents(replace_gaia_host);
301 command_line->AppendSwitchASCII(::switches::kGaiaUrl, gaia_url.spec());
302 command_line->AppendSwitchASCII(::switches::kLsoUrl, gaia_url.spec());
303 command_line->AppendSwitchASCII(::switches::kGoogleApisUrl,
306 std::string webstore_host("webstore");
307 GURL::Replacements replace_webstore_host;
308 replace_webstore_host.SetHostStr(webstore_host);
309 GURL webstore_url = server_url.ReplaceComponents(replace_webstore_host);
310 command_line->AppendSwitchASCII(
311 ::switches::kAppsGalleryURL,
312 webstore_url.Resolve("/chromeos/app_mode/webstore").spec());
313 command_line->AppendSwitchASCII(
314 ::switches::kAppsGalleryDownloadURL,
315 webstore_url.Resolve(
316 "/chromeos/app_mode/webstore/downloads/%s.crx").spec());
319 void ReloadKioskApps() {
320 KioskAppManager::Get()->AddApp(kTestKioskApp);
323 void ReloadAutolaunchKioskApps() {
324 KioskAppManager::Get()->AddApp(kTestKioskApp);
325 KioskAppManager::Get()->SetAutoLaunchApp(kTestKioskApp);
328 void StartAppLaunchFromLoginScreen(bool has_connectivity) {
329 EnableConsumerKioskMode();
331 // Start UI, find menu entry for this app and launch it.
332 content::WindowedNotificationObserver login_signal(
333 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
334 content::NotificationService::AllSources());
335 chromeos::WizardController::SkipPostLoginScreensForTesting();
336 chromeos::WizardController* wizard_controller =
337 chromeos::WizardController::default_controller();
338 CHECK(wizard_controller);
339 wizard_controller->SkipToLoginForTesting();
342 // Wait for the Kiosk App configuration to reload, then launch the app.
343 content::WindowedNotificationObserver apps_loaded_signal(
344 chrome::NOTIFICATION_KIOSK_APPS_LOADED,
345 content::NotificationService::AllSources());
347 apps_loaded_signal.Wait();
349 if (!has_connectivity)
350 SimulateNetworkOffline();
352 GetLoginUI()->CallJavascriptFunction(
353 "login.AppsMenuButton.runAppForTesting",
354 base::StringValue(kTestKioskApp));
357 void WaitForAppLaunchSuccess() {
358 SimulateNetworkOnline();
360 ExtensionTestMessageListener
361 launch_data_check_listener("launchData.isKioskSession = true", false);
363 // Wait for the Kiosk App to launch.
364 content::WindowedNotificationObserver(
365 chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
366 content::NotificationService::AllSources()).Wait();
368 // Default profile switches to app profile after app is launched.
369 Profile* app_profile = ProfileManager::GetDefaultProfile();
370 ASSERT_TRUE(app_profile);
372 // Check installer status.
373 EXPECT_EQ(chromeos::KioskAppLaunchError::NONE,
374 chromeos::KioskAppLaunchError::Get());
376 // Check if the kiosk webapp is really installed for the default profile.
377 const extensions::Extension* app =
378 extensions::ExtensionSystem::Get(app_profile)->
379 extension_service()->GetInstalledExtension(kTestKioskApp);
382 // App should appear with its window.
383 apps::ShellWindow* window = ShellWindowObserver(
384 apps::ShellWindowRegistry::Get(app_profile),
385 kTestKioskApp).Wait();
388 // Login screen should be fading out.
390 LoginDisplayHostImpl::default_host()
393 ->GetTargetOpacity());
395 // Wait until the app terminates.
396 content::RunMessageLoop();
398 // Check that the app had been informed that it is running in a kiosk
400 EXPECT_TRUE(launch_data_check_listener.was_satisfied());
403 void SimulateNetworkOffline() {
404 disable_network_notifier_.reset(
405 new net::NetworkChangeNotifier::DisableForTest);
407 fake_network_notifier_.reset(new FakeNetworkChangeNotifier);
410 void SimulateNetworkOnline() {
411 if (fake_network_notifier_.get())
412 fake_network_notifier_->GoOnline();
415 void WaitForAppLaunchNetworkTimeout() {
416 if (GetAppLaunchController()->network_wait_timedout())
419 scoped_refptr<content::MessageLoopRunner> runner =
420 new content::MessageLoopRunner;
422 base::Closure callback = base::Bind(
423 &OnNetworkWaitTimedOut, runner->QuitClosure());
424 AppLaunchController::SetNetworkTimeoutCallbackForTesting(&callback);
428 CHECK(GetAppLaunchController()->network_wait_timedout());
429 AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL);
432 void EnableConsumerKioskMode() {
433 scoped_ptr<bool> locked(new bool(false));
434 scoped_refptr<content::MessageLoopRunner> runner =
435 new content::MessageLoopRunner;
436 KioskAppManager::Get()->EnableConsumerModeKiosk(
437 base::Bind(&ConsumerKioskModeLockCheck,
439 runner->QuitClosure()));
441 EXPECT_TRUE(*locked.get());
444 KioskAppManager::ConsumerKioskModeStatus GetConsumerKioskModeStatus() {
445 KioskAppManager::ConsumerKioskModeStatus status =
446 static_cast<KioskAppManager::ConsumerKioskModeStatus>(-1);
447 scoped_refptr<content::MessageLoopRunner> runner =
448 new content::MessageLoopRunner;
449 KioskAppManager::Get()->GetConsumerKioskModeStatus(
450 base::Bind(&ConsumerKioskModeStatusCheck,
452 runner->QuitClosure()));
454 CHECK_NE(status, static_cast<KioskAppManager::ConsumerKioskModeStatus>(-1));
458 void JsExpect(const std::string& expression) {
460 ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
461 GetLoginUI()->GetWebContents(),
462 "window.domAutomationController.send(!!(" + expression + "));",
464 ASSERT_TRUE(result) << expression;
467 content::WebUI* GetLoginUI() {
468 return static_cast<chromeos::LoginDisplayHostImpl*>(
469 chromeos::LoginDisplayHostImpl::default_host())->GetOobeUI()->web_ui();
472 SigninScreenHandler* GetSigninScreenHandler() {
473 return static_cast<chromeos::LoginDisplayHostImpl*>(
474 chromeos::LoginDisplayHostImpl::default_host())
476 ->signin_screen_handler_for_test();
479 AppLaunchController* GetAppLaunchController() {
480 return chromeos::LoginDisplayHostImpl::default_host()
481 ->GetAppLaunchController();
485 scoped_ptr<net::NetworkChangeNotifier::DisableForTest>
486 disable_network_notifier_;
487 scoped_ptr<FakeNetworkChangeNotifier> fake_network_notifier_;
488 scoped_ptr<MockUserManager> mock_user_manager_;
491 IN_PROC_BROWSER_TEST_F(KioskTest, InstallAndLaunchApp) {
492 StartAppLaunchFromLoginScreen(true);
493 WaitForAppLaunchSuccess();
496 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkDown) {
497 // Mock network could be configured.
498 ScopedCanConfigureNetwork can_configure_network(true);
500 // Start app launch and wait for network connectivity timeout.
501 StartAppLaunchFromLoginScreen(false);
502 OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
503 splash_waiter.Wait();
504 WaitForAppLaunchNetworkTimeout();
506 // Configure network link should be visible.
507 JsExpect("$('splash-config-network').hidden == false");
509 // Set up fake user manager with an owner for the test.
510 mock_user_manager_->SetActiveUser(kTestOwnerEmail);
511 AppLaunchSigninScreen::SetUserManagerForTesting(mock_user_manager_.get());
512 static_cast<LoginDisplayHostImpl*>(LoginDisplayHostImpl::default_host())
513 ->GetOobeUI()->ShowOobeUI(false);
515 // Configure network should bring up lock screen for owner.
516 OobeScreenWaiter lock_screen_waiter(OobeDisplay::SCREEN_ACCOUNT_PICKER);
517 static_cast<AppLaunchSplashScreenActor::Delegate*>(GetAppLaunchController())
518 ->OnConfigureNetwork();
519 lock_screen_waiter.Wait();
521 // A network error screen should be shown after authenticating.
522 OobeScreenWaiter error_screen_waiter(OobeDisplay::SCREEN_ERROR_MESSAGE);
523 static_cast<AppLaunchSigninScreen::Delegate*>(GetAppLaunchController())
524 ->OnOwnerSigninSuccess();
525 error_screen_waiter.Wait();
527 ASSERT_TRUE(GetAppLaunchController()->showing_network_dialog());
529 WaitForAppLaunchSuccess();
532 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkDownConfigureNotAllowed) {
533 // Mock network could not be configured.
534 ScopedCanConfigureNetwork can_configure_network(false);
536 // Start app launch and wait for network connectivity timeout.
537 StartAppLaunchFromLoginScreen(false);
538 OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
539 splash_waiter.Wait();
540 WaitForAppLaunchNetworkTimeout();
542 // Configure network link should not be visible.
543 JsExpect("$('splash-config-network').hidden == true");
545 // Network becomes online and app launch is resumed.
546 WaitForAppLaunchSuccess();
549 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppUserCancel) {
550 StartAppLaunchFromLoginScreen(false);
551 OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
552 splash_waiter.Wait();
554 CrosSettings::Get()->SetBoolean(
555 kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, true);
556 content::WindowedNotificationObserver signal(
557 chrome::NOTIFICATION_APP_TERMINATING,
558 content::NotificationService::AllSources());
559 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
560 base::StringValue("app_launch_bailout"));
562 EXPECT_EQ(chromeos::KioskAppLaunchError::USER_CANCEL,
563 chromeos::KioskAppLaunchError::Get());
566 IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningCancel) {
567 EnableConsumerKioskMode();
568 // Start UI, find menu entry for this app and launch it.
569 chromeos::WizardController::SkipPostLoginScreensForTesting();
570 chromeos::WizardController* wizard_controller =
571 chromeos::WizardController::default_controller();
572 CHECK(wizard_controller);
573 ReloadAutolaunchKioskApps();
574 wizard_controller->SkipToLoginForTesting();
576 EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
577 EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
579 // Wait for the auto launch warning come up.
580 content::WindowedNotificationObserver(
581 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
582 content::NotificationService::AllSources()).Wait();
583 GetLoginUI()->CallJavascriptFunction(
584 "login.AutolaunchScreen.confirmAutoLaunchForTesting",
585 base::FundamentalValue(false));
587 // Wait for the auto launch warning to go away.
588 content::WindowedNotificationObserver(
589 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED,
590 content::NotificationService::AllSources()).Wait();
592 EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
595 IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningConfirm) {
596 EnableConsumerKioskMode();
597 // Start UI, find menu entry for this app and launch it.
598 chromeos::WizardController::SkipPostLoginScreensForTesting();
599 chromeos::WizardController* wizard_controller =
600 chromeos::WizardController::default_controller();
601 CHECK(wizard_controller);
602 wizard_controller->SkipToLoginForTesting();
604 ReloadAutolaunchKioskApps();
605 EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
606 EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
608 // Wait for the auto launch warning come up.
609 content::WindowedNotificationObserver(
610 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
611 content::NotificationService::AllSources()).Wait();
612 GetLoginUI()->CallJavascriptFunction(
613 "login.AutolaunchScreen.confirmAutoLaunchForTesting",
614 base::FundamentalValue(true));
616 // Wait for the auto launch warning to go away.
617 content::WindowedNotificationObserver(
618 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED,
619 content::NotificationService::AllSources()).Wait();
621 EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
622 EXPECT_TRUE(KioskAppManager::Get()->IsAutoLaunchEnabled());
624 WaitForAppLaunchSuccess();
627 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableCancel) {
628 chromeos::WizardController::SkipPostLoginScreensForTesting();
629 chromeos::WizardController* wizard_controller =
630 chromeos::WizardController::default_controller();
631 CHECK(wizard_controller);
633 // Check Kiosk mode status.
634 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE,
635 GetConsumerKioskModeStatus());
637 // Wait for the login UI to come up and switch to the kiosk_enable screen.
638 wizard_controller->SkipToLoginForTesting();
639 content::WindowedNotificationObserver(
640 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
641 content::NotificationService::AllSources()).Wait();
642 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
643 base::StringValue("kiosk_enable"));
645 // Wait for the kiosk_enable screen to show and cancel the screen.
646 content::WindowedNotificationObserver(
647 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
648 content::NotificationService::AllSources()).Wait();
649 GetLoginUI()->CallJavascriptFunction(
650 "login.KioskEnableScreen.enableKioskForTesting",
651 base::FundamentalValue(false));
653 // Wait for the kiosk_enable screen to disappear.
654 content::WindowedNotificationObserver(
655 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED,
656 content::NotificationService::AllSources()).Wait();
658 // Check that the status still says configurable.
659 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE,
660 GetConsumerKioskModeStatus());
663 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableConfirmed) {
664 // Start UI, find menu entry for this app and launch it.
665 chromeos::WizardController::SkipPostLoginScreensForTesting();
666 chromeos::WizardController* wizard_controller =
667 chromeos::WizardController::default_controller();
668 CHECK(wizard_controller);
670 // Check Kiosk mode status.
671 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE,
672 GetConsumerKioskModeStatus());
673 wizard_controller->SkipToLoginForTesting();
675 // Wait for the login UI to come up and switch to the kiosk_enable screen.
676 wizard_controller->SkipToLoginForTesting();
677 content::WindowedNotificationObserver(
678 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
679 content::NotificationService::AllSources()).Wait();
680 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
681 base::StringValue("kiosk_enable"));
683 // Wait for the kiosk_enable screen to show and cancel the screen.
684 content::WindowedNotificationObserver(
685 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
686 content::NotificationService::AllSources()).Wait();
687 GetLoginUI()->CallJavascriptFunction(
688 "login.KioskEnableScreen.enableKioskForTesting",
689 base::FundamentalValue(true));
691 // Wait for the signal that indicates Kiosk Mode is enabled.
692 content::WindowedNotificationObserver(
693 chrome::NOTIFICATION_KIOSK_ENABLED,
694 content::NotificationService::AllSources()).Wait();
695 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_ENABLED,
696 GetConsumerKioskModeStatus());
699 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableAbortedWithAutoEnrollment) {
700 // Fake an auto enrollment is going to be enforced.
701 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
702 switches::kEnterpriseEnrollmentInitialModulus, "1");
703 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
704 switches::kEnterpriseEnrollmentModulusLimit, "2");
705 g_browser_process->local_state()->SetBoolean(prefs::kShouldAutoEnroll, true);
706 g_browser_process->local_state()->SetInteger(
707 prefs::kAutoEnrollmentPowerLimit, 3);
709 // Start UI, find menu entry for this app and launch it.
710 chromeos::WizardController::SkipPostLoginScreensForTesting();
711 chromeos::WizardController* wizard_controller =
712 chromeos::WizardController::default_controller();
713 CHECK(wizard_controller);
715 // Check Kiosk mode status.
716 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE,
717 GetConsumerKioskModeStatus());
718 wizard_controller->SkipToLoginForTesting();
720 // Wait for the login UI to come up and switch to the kiosk_enable screen.
721 wizard_controller->SkipToLoginForTesting();
722 content::WindowedNotificationObserver(
723 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
724 content::NotificationService::AllSources()).Wait();
725 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
726 base::StringValue("kiosk_enable"));
728 // The flow should be aborted due to auto enrollment enforcement.
729 scoped_refptr<content::MessageLoopRunner> runner =
730 new content::MessageLoopRunner;
731 GetSigninScreenHandler()->set_kiosk_enable_flow_aborted_callback_for_test(
732 runner->QuitClosure());
736 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableAfter2ndSigninScreen) {
737 // Fake an auto enrollment is not going to be enforced.
738 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
739 switches::kEnterpriseEnrollmentInitialModulus, "1");
740 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
741 switches::kEnterpriseEnrollmentModulusLimit, "2");
742 g_browser_process->local_state()->SetBoolean(prefs::kShouldAutoEnroll, false);
743 g_browser_process->local_state()->SetInteger(
744 prefs::kAutoEnrollmentPowerLimit, -1);
746 chromeos::WizardController::SkipPostLoginScreensForTesting();
747 chromeos::WizardController* wizard_controller =
748 chromeos::WizardController::default_controller();
749 CHECK(wizard_controller);
751 // Check Kiosk mode status.
752 EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE,
753 GetConsumerKioskModeStatus());
755 // Wait for the login UI to come up and switch to the kiosk_enable screen.
756 wizard_controller->SkipToLoginForTesting();
757 content::WindowedNotificationObserver(
758 chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
759 content::NotificationService::AllSources()).Wait();
760 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
761 base::StringValue("kiosk_enable"));
763 // Wait for the kiosk_enable screen to show and cancel the screen.
764 content::WindowedNotificationObserver(
765 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
766 content::NotificationService::AllSources()).Wait();
767 GetLoginUI()->CallJavascriptFunction(
768 "login.KioskEnableScreen.enableKioskForTesting",
769 base::FundamentalValue(false));
771 // Wait for the kiosk_enable screen to disappear.
772 content::WindowedNotificationObserver(
773 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED,
774 content::NotificationService::AllSources()).Wait();
776 // Show signin screen again.
777 chromeos::LoginDisplayHostImpl::default_host()->StartSignInScreen();
778 OobeScreenWaiter(OobeDisplay::SCREEN_GAIA_SIGNIN).Wait();
780 // Show kiosk enable screen again.
781 GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
782 base::StringValue("kiosk_enable"));
784 // And it should show up.
785 content::WindowedNotificationObserver(
786 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
787 content::NotificationService::AllSources()).Wait();
790 class KioskEnterpriseTest : public KioskTest {
792 KioskEnterpriseTest() {}
794 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
795 device_policy_test_helper_.MarkAsEnterpriseOwned();
796 device_policy_test_helper_.InstallOwnerKey();
798 KioskTest::SetUpInProcessBrowserTestFixture();
801 virtual void SetUpOnMainThread() OVERRIDE {
802 // Configure kTestEnterpriseKioskApp in device policy.
803 em::DeviceLocalAccountsProto* accounts =
804 device_policy_test_helper_.device_policy()->payload()
805 .mutable_device_local_accounts();
806 em::DeviceLocalAccountInfoProto* account = accounts->add_account();
807 account->set_account_id(kTestEnterpriseAccountId);
809 em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP);
810 account->mutable_kiosk_app()->set_app_id(kTestEnterpriseKioskApp);
811 accounts->set_auto_login_id(kTestEnterpriseAccountId);
812 em::PolicyData& policy_data =
813 device_policy_test_helper_.device_policy()->policy_data();
814 policy_data.set_service_account_identity(kTestEnterpriseServiceAccountId);
815 device_policy_test_helper_.device_policy()->Build();
816 DBusThreadManager::Get()->GetSessionManagerClient()->StoreDevicePolicy(
817 device_policy_test_helper_.device_policy()->GetBlob(),
818 base::Bind(&KioskEnterpriseTest::StorePolicyCallback));
820 DeviceSettingsService::Get()->Load();
822 // Configure OAuth authentication.
823 FakeGaia::AccessTokenInfo token_info;
824 token_info.token = kTestAccessToken;
825 token_info.email = kTestEnterpriseServiceAccountId;
826 fake_gaia_.IssueOAuthToken(kTestRefreshToken, token_info);
827 DeviceOAuth2TokenService* token_service = NULL;
828 DeviceOAuth2TokenServiceFactory::Get(
829 base::Bind(&CopyTokenService, &token_service));
830 base::RunLoop().RunUntilIdle();
831 ASSERT_TRUE(token_service);
832 token_service->SetAndSaveRefreshToken(kTestRefreshToken);
834 KioskTest::SetUpOnMainThread();
837 static void StorePolicyCallback(bool result) {
841 policy::DevicePolicyCrosTestHelper device_policy_test_helper_;
844 DISALLOW_COPY_AND_ASSIGN(KioskEnterpriseTest);
847 // Disabled due to failures; http://crbug.com/306611.
848 IN_PROC_BROWSER_TEST_F(KioskEnterpriseTest, DISABLED_EnterpriseKioskApp) {
849 chromeos::WizardController::SkipPostLoginScreensForTesting();
850 chromeos::WizardController* wizard_controller =
851 chromeos::WizardController::default_controller();
852 wizard_controller->SkipToLoginForTesting();
854 // Wait for the Kiosk App configuration to reload, then launch the app.
855 KioskAppManager::App app;
856 content::WindowedNotificationObserver(
857 chrome::NOTIFICATION_KIOSK_APPS_LOADED,
858 base::Bind(&KioskAppManager::GetApp,
859 base::Unretained(KioskAppManager::Get()),
860 kTestEnterpriseKioskApp, &app)).Wait();
862 GetLoginUI()->CallJavascriptFunction(
863 "login.AppsMenuButton.runAppForTesting",
864 base::StringValue(kTestEnterpriseKioskApp));
866 // Wait for the Kiosk App to launch.
867 content::WindowedNotificationObserver(
868 chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
869 content::NotificationService::AllSources()).Wait();
871 // Check installer status.
872 EXPECT_EQ(chromeos::KioskAppLaunchError::NONE,
873 chromeos::KioskAppLaunchError::Get());
875 // Wait for the window to appear.
876 apps::ShellWindow* window = ShellWindowObserver(
877 apps::ShellWindowRegistry::Get(ProfileManager::GetDefaultProfile()),
878 kTestEnterpriseKioskApp).Wait();
881 // Check whether the app can retrieve an OAuth2 access token.
883 EXPECT_TRUE(content::ExecuteScriptAndExtractString(
884 window->web_contents(),
885 "chrome.identity.getAuthToken({ 'interactive': false }, function(token) {"
886 " window.domAutomationController.send(token);"
889 EXPECT_EQ(kTestAccessToken, result);
891 // Terminate the app.
892 window->GetBaseWindow()->Close();
893 content::RunAllPendingInMessageLoop();
896 // Specialized test fixture for testing kiosk mode on the
897 // hidden WebUI initialization flow for slow hardware.
898 class KioskHiddenWebUITest : public KioskTest,
899 public ash::DesktopBackgroundControllerObserver {
901 KioskHiddenWebUITest() : wallpaper_loaded_(false) {}
903 // KioskTest overrides:
904 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
905 KioskTest::SetUpCommandLine(command_line);
906 command_line->AppendSwitchASCII(switches::kDeviceRegistered, "1");
907 command_line->AppendSwitch(switches::kDisableBootAnimation);
908 command_line->AppendSwitch(switches::kDisableOobeAnimation);
911 virtual void SetUpOnMainThread() OVERRIDE {
912 KioskTest::SetUpOnMainThread();
913 ash::Shell::GetInstance()->desktop_background_controller()
917 virtual void TearDownOnMainThread() OVERRIDE {
918 ash::Shell::GetInstance()->desktop_background_controller()
919 ->RemoveObserver(this);
920 KioskTest::TearDownOnMainThread();
923 void WaitForWallpaper() {
924 if (!wallpaper_loaded_) {
925 runner_ = new content::MessageLoopRunner;
930 bool wallpaper_loaded() const { return wallpaper_loaded_; }
932 // ash::DesktopBackgroundControllerObserver overrides:
933 virtual void OnWallpaperDataChanged() OVERRIDE {
934 wallpaper_loaded_ = true;
939 bool wallpaper_loaded_;
940 scoped_refptr<content::MessageLoopRunner> runner_;
942 DISALLOW_COPY_AND_ASSIGN(KioskHiddenWebUITest);
945 IN_PROC_BROWSER_TEST_F(KioskHiddenWebUITest, AutolaunchWarning) {
946 // Add a device owner.
947 FakeUserManager* user_manager = new FakeUserManager();
948 user_manager->AddUser(kTestOwnerEmail);
949 ScopedUserManagerEnabler enabler(user_manager);
951 // Set kiosk app to autolaunch.
952 EnableConsumerKioskMode();
953 chromeos::WizardController::SkipPostLoginScreensForTesting();
954 chromeos::WizardController* wizard_controller =
955 chromeos::WizardController::default_controller();
956 CHECK(wizard_controller);
957 ReloadAutolaunchKioskApps();
958 wizard_controller->SkipToLoginForTesting();
960 EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
961 EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
963 // Wait for the auto launch warning come up.
964 content::WindowedNotificationObserver(
965 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
966 content::NotificationService::AllSources()).Wait();
968 // Wait for the wallpaper to load.
970 EXPECT_TRUE(wallpaper_loaded());
973 } // namespace chromeos