• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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