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