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@example.com";
103
104 const char kTestEnterpriseAccountId[] = "enterprise-kiosk-app@localhost";
105 const char kTestEnterpriseServiceAccountId[] = "service_account@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.
ConsumerKioskModeStatusCheck(KioskAppManager::ConsumerKioskModeStatus * out_status,const base::Closure & runner_quit_task,KioskAppManager::ConsumerKioskModeStatus in_status)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.
ConsumerKioskModeLockCheck(bool * out_locked,const base::Closure & runner_quit_task,bool in_locked)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.
OnNetworkWaitTimedOut(const base::Closure & runner_quit_task)138 void OnNetworkWaitTimedOut(const base::Closure& runner_quit_task) {
139 runner_quit_task.Run();
140 }
141
142 // Helper function for DeviceOAuth2TokenServiceFactory::Get().
CopyTokenService(DeviceOAuth2TokenService ** out_token_service,DeviceOAuth2TokenService * in_token_service)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:
ScopedCanConfigureNetwork(bool can_configure,bool needs_owner_auth)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 }
~ScopedCanConfigureNetwork()165 ~ScopedCanConfigureNetwork() {
166 AppLaunchController::SetCanConfigureNetworkCallbackForTesting(NULL);
167 AppLaunchController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
168 NULL);
169 }
170
CanConfigureNetwork()171 bool CanConfigureNetwork() {
172 return can_configure_;
173 }
174
NeedsOwnerAuthToConfigureNetwork()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:
ShellWindowObserver(apps::ShellWindowRegistry * registry,const std::string & app_id)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 }
~ShellWindowObserver()197 virtual ~ShellWindowObserver() {
198 registry_->RemoveObserver(this);
199 }
200
Wait()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
OnShellWindowAdded(apps::ShellWindow * shell_window)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 }
OnShellWindowIconChanged(apps::ShellWindow * shell_window)220 virtual void OnShellWindowIconChanged(
221 apps::ShellWindow* shell_window) OVERRIDE {}
OnShellWindowRemoved(apps::ShellWindow * shell_window)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:
KioskTest()236 KioskTest() {
237 set_exit_when_last_browser_closes(false);
238 }
239
~KioskTest()240 virtual ~KioskTest() {}
241
242 protected:
SetUp()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
SetUpInProcessBrowserTestFixture()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
SetUpOnMainThread()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
CleanUpOnMainThread()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
SetUpCommandLine(CommandLine * command_line)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
ReloadKioskApps()324 void ReloadKioskApps() {
325 KioskAppManager::Get()->AddApp(kTestKioskApp);
326 }
327
ReloadAutolaunchKioskApps()328 void ReloadAutolaunchKioskApps() {
329 KioskAppManager::Get()->AddApp(kTestKioskApp);
330 KioskAppManager::Get()->SetAutoLaunchApp(kTestKioskApp);
331 }
332
StartAppLaunchFromLoginScreen(const base::Closure & network_setup_cb)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
WaitForAppLaunchSuccess()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
SimulateNetworkOffline()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
SimulateNetworkOfflineClosure()419 base::Closure SimulateNetworkOfflineClosure() {
420 return base::Bind(&KioskTest::SimulateNetworkOffline,
421 base::Unretained(this));
422 }
423
SimulateNetworkOnline()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
SimulateNetworkOnlineClosure()433 base::Closure SimulateNetworkOnlineClosure() {
434 return base::Bind(&KioskTest::SimulateNetworkOnline,
435 base::Unretained(this));
436 }
437
SimulateNetworkPortal()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
SimulateNetworkPortalClosure()446 base::Closure SimulateNetworkPortalClosure() {
447 return base::Bind(&KioskTest::SimulateNetworkPortal,
448 base::Unretained(this));
449 }
450
WaitForAppLaunchNetworkTimeout()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
EnableConsumerKioskMode()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
GetConsumerKioskModeStatus()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
JsExpect(const std::string & expression)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
GetLoginUI()503 content::WebUI* GetLoginUI() {
504 return static_cast<chromeos::LoginDisplayHostImpl*>(
505 chromeos::LoginDisplayHostImpl::default_host())->GetOobeUI()->web_ui();
506 }
507
GetSigninScreenHandler()508 SigninScreenHandler* GetSigninScreenHandler() {
509 return static_cast<chromeos::LoginDisplayHostImpl*>(
510 chromeos::LoginDisplayHostImpl::default_host())
511 ->GetOobeUI()
512 ->signin_screen_handler_for_test();
513 }
514
GetAppLaunchController()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
IN_PROC_BROWSER_TEST_F(KioskTest,InstallAndLaunchApp)525 IN_PROC_BROWSER_TEST_F(KioskTest, InstallAndLaunchApp) {
526 StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
527 WaitForAppLaunchSuccess();
528 }
529
IN_PROC_BROWSER_TEST_F(KioskTest,LaunchAppNetworkDown)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
IN_PROC_BROWSER_TEST_F(KioskTest,LaunchAppNetworkDownConfigureNotAllowed)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
IN_PROC_BROWSER_TEST_F(KioskTest,LaunchAppNetworkPortal)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
IN_PROC_BROWSER_TEST_F(KioskTest,LaunchAppUserCancel)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
IN_PROC_BROWSER_TEST_F(KioskTest,AutolaunchWarningCancel)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
IN_PROC_BROWSER_TEST_F(KioskTest,AutolaunchWarningConfirm)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
IN_PROC_BROWSER_TEST_F(KioskTest,KioskEnableCancel)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
IN_PROC_BROWSER_TEST_F(KioskTest,KioskEnableConfirmed)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
IN_PROC_BROWSER_TEST_F(KioskTest,KioskEnableAbortedWithAutoEnrollment)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
IN_PROC_BROWSER_TEST_F(KioskTest,KioskEnableAfter2ndSigninScreen)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:
KioskEnterpriseTest()845 KioskEnterpriseTest() {}
846
SetUpInProcessBrowserTestFixture()847 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
848 device_policy_test_helper_.MarkAsEnterpriseOwned();
849 device_policy_test_helper_.InstallOwnerKey();
850
851 KioskTest::SetUpInProcessBrowserTestFixture();
852 }
853
SetUpOnMainThread()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
StorePolicyCallback(bool result)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
IN_PROC_BROWSER_TEST_F(KioskEnterpriseTest,EnterpriseKioskApp)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:
KioskHiddenWebUITest()975 KioskHiddenWebUITest() : wallpaper_loaded_(false) {}
976
977 // KioskTest overrides:
SetUpCommandLine(CommandLine * command_line)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
SetUpOnMainThread()985 virtual void SetUpOnMainThread() OVERRIDE {
986 KioskTest::SetUpOnMainThread();
987 ash::Shell::GetInstance()->desktop_background_controller()
988 ->AddObserver(this);
989 }
990
TearDownOnMainThread()991 virtual void TearDownOnMainThread() OVERRIDE {
992 ash::Shell::GetInstance()->desktop_background_controller()
993 ->RemoveObserver(this);
994 KioskTest::TearDownOnMainThread();
995 }
996
WaitForWallpaper()997 void WaitForWallpaper() {
998 if (!wallpaper_loaded_) {
999 runner_ = new content::MessageLoopRunner;
1000 runner_->Run();
1001 }
1002 }
1003
wallpaper_loaded() const1004 bool wallpaper_loaded() const { return wallpaper_loaded_; }
1005
1006 // ash::DesktopBackgroundControllerObserver overrides:
OnWallpaperDataChanged()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
IN_PROC_BROWSER_TEST_F(KioskHiddenWebUITest,AutolaunchWarning)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