Upstream version 10.39.225.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 "ash/desktop_background/desktop_background_controller.h"
6 #include "ash/desktop_background/desktop_background_controller_observer.h"
7 #include "ash/shell.h"
8 #include "base/bind.h"
9 #include "base/bind_helpers.h"
10 #include "base/files/file_util.h"
11 #include "base/location.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/path_service.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/strings/string_number_conversions.h"
16 #include "base/strings/string_util.h"
17 #include "base/synchronization/lock.h"
18 #include "chrome/browser/browser_process.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/chromeos/app_mode/fake_cws.h"
21 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
22 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
23 #include "chrome/browser/chromeos/file_manager/fake_disk_mount_manager.h"
24 #include "chrome/browser/chromeos/login/app_launch_controller.h"
25 #include "chrome/browser/chromeos/login/startup_utils.h"
26 #include "chrome/browser/chromeos/login/test/app_window_waiter.h"
27 #include "chrome/browser/chromeos/login/test/oobe_base_test.h"
28 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
29 #include "chrome/browser/chromeos/login/users/fake_user_manager.h"
30 #include "chrome/browser/chromeos/login/users/mock_user_manager.h"
31 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
32 #include "chrome/browser/chromeos/login/wizard_controller.h"
33 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
34 #include "chrome/browser/chromeos/policy/proto/chrome_device_policy.pb.h"
35 #include "chrome/browser/chromeos/profiles/profile_helper.h"
36 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
37 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
38 #include "chrome/browser/extensions/extension_service.h"
39 #include "chrome/browser/profiles/profile_impl.h"
40 #include "chrome/browser/profiles/profile_manager.h"
41 #include "chrome/browser/profiles/profiles_state.h"
42 #include "chrome/browser/ui/webui/chromeos/login/kiosk_app_menu_handler.h"
43 #include "chrome/common/chrome_constants.h"
44 #include "chrome/common/chrome_paths.h"
45 #include "chrome/common/pref_names.h"
46 #include "chromeos/chromeos_switches.h"
47 #include "chromeos/dbus/cryptohome_client.h"
48 #include "chromeos/disks/disk_mount_manager.h"
49 #include "components/native_app_window/native_app_window_views.h"
50 #include "components/signin/core/common/signin_pref_names.h"
51 #include "content/public/browser/browser_thread.h"
52 #include "content/public/browser/notification_observer.h"
53 #include "content/public/browser/notification_registrar.h"
54 #include "content/public/browser/notification_service.h"
55 #include "content/public/test/browser_test_utils.h"
56 #include "extensions/browser/app_window/app_window.h"
57 #include "extensions/browser/app_window/app_window_registry.h"
58 #include "extensions/browser/app_window/native_app_window.h"
59 #include "extensions/browser/extension_system.h"
60 #include "extensions/test/extension_test_message_listener.h"
61 #include "extensions/test/result_catcher.h"
62 #include "google_apis/gaia/gaia_constants.h"
63 #include "google_apis/gaia/gaia_switches.h"
64 #include "google_apis/gaia/gaia_urls.h"
65 #include "net/test/embedded_test_server/embedded_test_server.h"
66 #include "ui/base/accelerators/accelerator.h"
67
68 namespace em = enterprise_management;
69
70 namespace chromeos {
71
72 namespace {
73
74 // This is a simple test app that creates an app window and immediately closes
75 // it again. Webstore data json is in
76 //   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
77 //       detail/ggbflgnkafappblpkiflbgpmkfdpnhhe
78 const char kTestKioskApp[] = "ggbflgnkafappblpkiflbgpmkfdpnhhe";
79
80 // This app creates a window and declares usage of the identity API in its
81 // manifest, so we can test device robot token minting via the identity API.
82 // Webstore data json is in
83 //   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
84 //       detail/ibjkkfdnfcaoapcpheeijckmpcfkifob
85 const char kTestEnterpriseKioskApp[] = "ibjkkfdnfcaoapcpheeijckmpcfkifob";
86
87 // An offline enable test app. Webstore data json is in
88 //   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
89 //       detail/ajoggoflpgplnnjkjamcmbepjdjdnpdp
90 // An app profile with version 1.0.0 installed is in
91 //   chrome/test/data/chromeos/app_mode/offline_enabled_app_profile
92 // The version 2.0.0 crx is in
93 //   chrome/test/data/chromeos/app_mode/webstore/downloads/
94 const char kTestOfflineEnabledKioskApp[] = "ajoggoflpgplnnjkjamcmbepjdjdnpdp";
95
96 // An app to test local fs data persistence across app update. V1 app writes
97 // data into local fs. V2 app reads and verifies the data.
98 // Webstore data json is in
99 //   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
100 //       detail/bmbpicmpniaclbbpdkfglgipkkebnbjf
101 const char kTestLocalFsKioskApp[] = "bmbpicmpniaclbbpdkfglgipkkebnbjf";
102
103 // Fake usb stick mount path.
104 const char kFakeUsbMountPathUpdatePass[] =
105     "chromeos/app_mode/external_update/update_pass";
106 const char kFakeUsbMountPathNoManifest[] =
107     "chromeos/app_mode/external_update/no_manifest";
108 const char kFakeUsbMountPathBadManifest[] =
109     "chromeos/app_mode/external_update/bad_manifest";
110 const char kFakeUsbMountPathLowerAppVersion[] =
111     "chromeos/app_mode/external_update/lower_app_version";
112 const char kFakeUsbMountPathLowerCrxVersion[] =
113     "chromeos/app_mode/external_update/lower_crx_version";
114 const char kFakeUsbMountPathBadCrx[] =
115     "chromeos/app_mode/external_update/bad_crx";
116
117 // Timeout while waiting for network connectivity during tests.
118 const int kTestNetworkTimeoutSeconds = 1;
119
120 // Email of owner account for test.
121 const char kTestOwnerEmail[] = "owner@example.com";
122
123 const char kTestEnterpriseAccountId[] = "enterprise-kiosk-app@localhost";
124 const char kTestEnterpriseServiceAccountId[] = "service_account@example.com";
125 const char kTestRefreshToken[] = "fake-refresh-token";
126 const char kTestUserinfoToken[] = "fake-userinfo-token";
127 const char kTestLoginToken[] = "fake-login-token";
128 const char kTestAccessToken[] = "fake-access-token";
129 const char kTestClientId[] = "fake-client-id";
130 const char kTestAppScope[] =
131     "https://www.googleapis.com/auth/userinfo.profile";
132
133 // Test JS API.
134 const char kLaunchAppForTestNewAPI[] =
135     "login.AccountPickerScreen.runAppForTesting";
136 const char kLaunchAppForTestOldAPI[] =
137     "login.AppsMenuButton.runAppForTesting";
138 const char kCheckDiagnosticModeNewAPI[] =
139     "$('oobe').confirmDiagnosticMode_";
140 const char kCheckDiagnosticModeOldAPI[] =
141     "$('show-apps-button').confirmDiagnosticMode_";
142
143 // Helper function for GetConsumerKioskAutoLaunchStatusCallback.
144 void ConsumerKioskAutoLaunchStatusCheck(
145     KioskAppManager::ConsumerKioskAutoLaunchStatus* out_status,
146     const base::Closure& runner_quit_task,
147     KioskAppManager::ConsumerKioskAutoLaunchStatus in_status) {
148   LOG(INFO) << "KioskAppManager::ConsumerKioskModeStatus = " << in_status;
149   *out_status = in_status;
150   runner_quit_task.Run();
151 }
152
153 // Helper KioskAppManager::EnableKioskModeCallback implementation.
154 void ConsumerKioskModeAutoStartLockCheck(
155     bool* out_locked,
156     const base::Closure& runner_quit_task,
157     bool in_locked) {
158   LOG(INFO) << "kiosk locked  = " << in_locked;
159   *out_locked = in_locked;
160   runner_quit_task.Run();
161 }
162
163 // Helper function for WaitForNetworkTimeOut.
164 void OnNetworkWaitTimedOut(const base::Closure& runner_quit_task) {
165   runner_quit_task.Run();
166 }
167
168 // Helper function for LockFileThread.
169 void LockAndUnlock(scoped_ptr<base::Lock> lock) {
170   lock->Acquire();
171   lock->Release();
172 }
173
174 // Helper functions for CanConfigureNetwork mock.
175 class ScopedCanConfigureNetwork {
176  public:
177   ScopedCanConfigureNetwork(bool can_configure, bool needs_owner_auth)
178       : can_configure_(can_configure),
179         needs_owner_auth_(needs_owner_auth),
180         can_configure_network_callback_(
181             base::Bind(&ScopedCanConfigureNetwork::CanConfigureNetwork,
182                        base::Unretained(this))),
183         needs_owner_auth_callback_(base::Bind(
184             &ScopedCanConfigureNetwork::NeedsOwnerAuthToConfigureNetwork,
185             base::Unretained(this))) {
186     AppLaunchController::SetCanConfigureNetworkCallbackForTesting(
187         &can_configure_network_callback_);
188     AppLaunchController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
189         &needs_owner_auth_callback_);
190   }
191   ~ScopedCanConfigureNetwork() {
192     AppLaunchController::SetCanConfigureNetworkCallbackForTesting(NULL);
193     AppLaunchController::SetNeedOwnerAuthToConfigureNetworkCallbackForTesting(
194         NULL);
195   }
196
197   bool CanConfigureNetwork() {
198     return can_configure_;
199   }
200
201   bool NeedsOwnerAuthToConfigureNetwork() {
202     return needs_owner_auth_;
203   }
204
205  private:
206   bool can_configure_;
207   bool needs_owner_auth_;
208   AppLaunchController::ReturnBoolCallback can_configure_network_callback_;
209   AppLaunchController::ReturnBoolCallback needs_owner_auth_callback_;
210   DISALLOW_COPY_AND_ASSIGN(ScopedCanConfigureNetwork);
211 };
212
213 // Helper class to wait until a js condition becomes true.
214 class JsConditionWaiter {
215  public:
216   JsConditionWaiter(content::WebContents* web_contents,
217                     const std::string& js)
218       : web_contents_(web_contents),
219         js_(js) {
220   }
221
222   void Wait() {
223     if (CheckJs())
224       return;
225
226     base::RepeatingTimer<JsConditionWaiter> check_timer;
227     check_timer.Start(
228         FROM_HERE,
229         base::TimeDelta::FromMilliseconds(10),
230         this,
231         &JsConditionWaiter::OnTimer);
232
233     runner_ = new content::MessageLoopRunner;
234     runner_->Run();
235   }
236
237  private:
238   bool CheckJs() {
239     bool result;
240     CHECK(content::ExecuteScriptAndExtractBool(
241         web_contents_,
242         "window.domAutomationController.send(!!(" + js_ + "));",
243         &result));
244     return result;
245   }
246
247   void OnTimer() {
248     DCHECK(runner_.get());
249     if (CheckJs())
250       runner_->Quit();
251   }
252
253   content::WebContents* web_contents_;
254   const std::string js_;
255   scoped_refptr<content::MessageLoopRunner> runner_;
256
257   DISALLOW_COPY_AND_ASSIGN(JsConditionWaiter);
258 };
259
260 class KioskFakeDiskMountManager : public file_manager::FakeDiskMountManager {
261  public:
262   KioskFakeDiskMountManager() {}
263
264   virtual ~KioskFakeDiskMountManager() {}
265
266   void set_usb_mount_path(const std::string& usb_mount_path) {
267     usb_mount_path_ = usb_mount_path;
268   }
269
270   void MountUsbStick() {
271     DCHECK(!usb_mount_path_.empty());
272     MountPath(usb_mount_path_, "", "", chromeos::MOUNT_TYPE_DEVICE);
273   }
274
275   void UnMountUsbStick() {
276     DCHECK(!usb_mount_path_.empty());
277     UnmountPath(usb_mount_path_,
278                 UNMOUNT_OPTIONS_NONE,
279                 disks::DiskMountManager::UnmountPathCallback());
280   }
281
282  private:
283   std::string usb_mount_path_;
284
285   DISALLOW_COPY_AND_ASSIGN(KioskFakeDiskMountManager);
286 };
287
288 }  // namespace
289
290 class KioskTest : public OobeBaseTest {
291  public:
292   KioskTest() : fake_cws_(new FakeCWS) {
293     set_exit_when_last_browser_closes(false);
294   }
295
296   virtual ~KioskTest() {}
297
298  protected:
299   virtual void SetUp() OVERRIDE {
300     test_app_id_ = kTestKioskApp;
301     set_test_app_version("1.0.0");
302     set_test_crx_file(test_app_id() + ".crx");
303     needs_background_networking_ = true;
304     mock_user_manager_.reset(new MockUserManager);
305     ProfileHelper::SetAlwaysReturnPrimaryUserForTesting(true);
306     AppLaunchController::SkipSplashWaitForTesting();
307     AppLaunchController::SetNetworkWaitForTesting(kTestNetworkTimeoutSeconds);
308
309     OobeBaseTest::SetUp();
310   }
311
312   virtual void TearDown() OVERRIDE {
313     ProfileHelper::SetAlwaysReturnPrimaryUserForTesting(false);
314     OobeBaseTest::TearDown();
315   }
316
317   virtual void SetUpOnMainThread() OVERRIDE {
318     OobeBaseTest::SetUpOnMainThread();
319     // Needed to avoid showing Gaia screen instead of owner signin for
320     // consumer network down test cases.
321     StartupUtils::MarkDeviceRegistered(base::Closure());
322   }
323
324   virtual void TearDownOnMainThread() OVERRIDE {
325     AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL);
326     AppLaunchSigninScreen::SetUserManagerForTesting(NULL);
327
328     OobeBaseTest::TearDownOnMainThread();
329
330     // Clean up while main thread still runs.
331     // See http://crbug.com/176659.
332     KioskAppManager::Get()->CleanUp();
333   }
334
335   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
336     OobeBaseTest::SetUpCommandLine(command_line);
337     fake_cws_->Init(embedded_test_server());
338   }
339
340   void LaunchApp(const std::string& app_id, bool diagnostic_mode) {
341     bool new_kiosk_ui = KioskAppMenuHandler::EnableNewKioskUI();
342     GetLoginUI()->CallJavascriptFunction(new_kiosk_ui ?
343         kLaunchAppForTestNewAPI : kLaunchAppForTestOldAPI,
344         base::StringValue(app_id),
345         base::FundamentalValue(diagnostic_mode));
346   }
347
348   void ReloadKioskApps() {
349     SetupTestAppUpdateCheck();
350
351     // Remove then add to ensure NOTIFICATION_KIOSK_APPS_LOADED fires.
352     KioskAppManager::Get()->RemoveApp(test_app_id_);
353     KioskAppManager::Get()->AddApp(test_app_id_);
354   }
355
356   void FireKioskAppSettingsChanged() {
357     KioskAppManager::Get()->UpdateAppData();
358   }
359
360   void SetupTestAppUpdateCheck() {
361     if (!test_app_version().empty()) {
362       fake_cws_->SetUpdateCrx(
363           test_app_id(), test_crx_file(), test_app_version());
364     }
365   }
366
367   void ReloadAutolaunchKioskApps() {
368     SetupTestAppUpdateCheck();
369
370     KioskAppManager::Get()->AddApp(test_app_id_);
371     KioskAppManager::Get()->SetAutoLaunchApp(test_app_id_);
372   }
373
374   void StartUIForAppLaunch() {
375     EnableConsumerKioskMode();
376
377     // Start UI
378     chromeos::WizardController::SkipPostLoginScreensForTesting();
379     chromeos::WizardController* wizard_controller =
380         chromeos::WizardController::default_controller();
381     if (wizard_controller) {
382       wizard_controller->SkipToLoginForTesting(LoginScreenContext());
383       OobeScreenWaiter(OobeDisplay::SCREEN_GAIA_SIGNIN).Wait();
384     } else {
385       // No wizard and running with an existing profile and it should land
386       // on account picker when new kiosk UI is enabled. Otherwise, just
387       // wait for the login signal from Gaia.
388       if (KioskAppMenuHandler::EnableNewKioskUI())
389         OobeScreenWaiter(OobeDisplay::SCREEN_ACCOUNT_PICKER).Wait();
390       else
391         OobeScreenWaiter(OobeDisplay::SCREEN_GAIA_SIGNIN).Wait();
392     }
393   }
394
395   void PrepareAppLaunch() {
396     // Start UI
397     StartUIForAppLaunch();
398
399     // Wait for the Kiosk App configuration to reload.
400     content::WindowedNotificationObserver apps_loaded_signal(
401         chrome::NOTIFICATION_KIOSK_APPS_LOADED,
402         content::NotificationService::AllSources());
403     ReloadKioskApps();
404     apps_loaded_signal.Wait();
405   }
406
407   void StartAppLaunchFromLoginScreen(const base::Closure& network_setup_cb) {
408     PrepareAppLaunch();
409
410     if (!network_setup_cb.is_null())
411       network_setup_cb.Run();
412
413     LaunchApp(test_app_id(), false);
414   }
415
416   const extensions::Extension* GetInstalledApp() {
417     Profile* app_profile = ProfileManager::GetPrimaryUserProfile();
418     return extensions::ExtensionSystem::Get(app_profile)->
419         extension_service()->GetInstalledExtension(test_app_id_);
420   }
421
422   const Version& GetInstalledAppVersion() {
423     return *GetInstalledApp()->version();
424   }
425
426   void WaitForAppLaunchAndOptionallyTerminateApp(bool terminate_app) {
427     ExtensionTestMessageListener
428         launch_data_check_listener("launchData.isKioskSession = true", false);
429
430     // Wait for the Kiosk App to launch.
431     content::WindowedNotificationObserver(
432         chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
433         content::NotificationService::AllSources()).Wait();
434
435     // Default profile switches to app profile after app is launched.
436     Profile* app_profile = ProfileManager::GetPrimaryUserProfile();
437     ASSERT_TRUE(app_profile);
438
439     // Check ChromeOS preference is initialized.
440     EXPECT_TRUE(
441         static_cast<ProfileImpl*>(app_profile)->chromeos_preferences_);
442
443     // Check installer status.
444     EXPECT_EQ(chromeos::KioskAppLaunchError::NONE,
445               chromeos::KioskAppLaunchError::Get());
446
447     // Check if the kiosk webapp is really installed for the default profile.
448     const extensions::Extension* app =
449         extensions::ExtensionSystem::Get(app_profile)->
450         extension_service()->GetInstalledExtension(test_app_id_);
451     EXPECT_TRUE(app);
452
453     // App should appear with its window.
454     extensions::AppWindowRegistry* app_window_registry =
455         extensions::AppWindowRegistry::Get(app_profile);
456     extensions::AppWindow* window =
457         AppWindowWaiter(app_window_registry, test_app_id_).Wait();
458     EXPECT_TRUE(window);
459
460     // Login screen should be gone or fading out.
461     chromeos::LoginDisplayHost* login_display_host =
462         chromeos::LoginDisplayHostImpl::default_host();
463     EXPECT_TRUE(
464         login_display_host == NULL ||
465         login_display_host->GetNativeWindow()->layer()->GetTargetOpacity() ==
466             0.0f);
467
468     // Terminate the app.
469     if (terminate_app)
470       window->GetBaseWindow()->Close();
471
472     // Wait until the app terminates if it is still running.
473     if (!app_window_registry->GetAppWindowsForApp(test_app_id_).empty())
474       content::RunMessageLoop();
475
476     // Check that the app had been informed that it is running in a kiosk
477     // session.
478     EXPECT_TRUE(launch_data_check_listener.was_satisfied());
479   }
480
481   void WaitForAppLaunchSuccess() {
482     WaitForAppLaunchAndOptionallyTerminateApp(true);
483   }
484
485   void WaitForAppLaunchNetworkTimeout() {
486     if (GetAppLaunchController()->network_wait_timedout())
487       return;
488
489     scoped_refptr<content::MessageLoopRunner> runner =
490         new content::MessageLoopRunner;
491
492     base::Closure callback = base::Bind(
493         &OnNetworkWaitTimedOut, runner->QuitClosure());
494     AppLaunchController::SetNetworkTimeoutCallbackForTesting(&callback);
495
496     runner->Run();
497
498     CHECK(GetAppLaunchController()->network_wait_timedout());
499     AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL);
500   }
501
502   void EnableConsumerKioskMode() {
503     scoped_ptr<bool> locked(new bool(false));
504     scoped_refptr<content::MessageLoopRunner> runner =
505         new content::MessageLoopRunner;
506     KioskAppManager::Get()->EnableConsumerKioskAutoLaunch(
507         base::Bind(&ConsumerKioskModeAutoStartLockCheck,
508                    locked.get(),
509                    runner->QuitClosure()));
510     runner->Run();
511     EXPECT_TRUE(*locked.get());
512   }
513
514   KioskAppManager::ConsumerKioskAutoLaunchStatus
515   GetConsumerKioskModeStatus() {
516     KioskAppManager::ConsumerKioskAutoLaunchStatus status =
517         static_cast<KioskAppManager::ConsumerKioskAutoLaunchStatus>(-1);
518     scoped_refptr<content::MessageLoopRunner> runner =
519         new content::MessageLoopRunner;
520     KioskAppManager::Get()->GetConsumerKioskAutoLaunchStatus(
521         base::Bind(&ConsumerKioskAutoLaunchStatusCheck,
522                    &status,
523                    runner->QuitClosure()));
524     runner->Run();
525     CHECK_NE(status,
526              static_cast<KioskAppManager::ConsumerKioskAutoLaunchStatus>(-1));
527     return status;
528   }
529
530   void RunAppLaunchNetworkDownTest() {
531     mock_user_manager()->SetActiveUser(kTestOwnerEmail);
532     AppLaunchSigninScreen::SetUserManagerForTesting(mock_user_manager());
533
534     // Mock network could be configured with owner's password.
535     ScopedCanConfigureNetwork can_configure_network(true, true);
536
537     // Start app launch and wait for network connectivity timeout.
538     StartAppLaunchFromLoginScreen(SimulateNetworkOfflineClosure());
539     OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
540     splash_waiter.Wait();
541     WaitForAppLaunchNetworkTimeout();
542
543     // Configure network link should be visible.
544     JsExpect("$('splash-config-network').hidden == false");
545
546     // Set up fake user manager with an owner for the test.
547     static_cast<LoginDisplayHostImpl*>(LoginDisplayHostImpl::default_host())
548         ->GetOobeUI()->ShowOobeUI(false);
549
550     // Configure network should bring up lock screen for owner.
551     OobeScreenWaiter lock_screen_waiter(OobeDisplay::SCREEN_ACCOUNT_PICKER);
552     static_cast<AppLaunchSplashScreenActor::Delegate*>(GetAppLaunchController())
553         ->OnConfigureNetwork();
554     lock_screen_waiter.Wait();
555
556     // There should be only one owner pod on this screen.
557     JsExpect("$('pod-row').alwaysFocusSinglePod");
558
559     // A network error screen should be shown after authenticating.
560     OobeScreenWaiter error_screen_waiter(OobeDisplay::SCREEN_ERROR_MESSAGE);
561     static_cast<AppLaunchSigninScreen::Delegate*>(GetAppLaunchController())
562         ->OnOwnerSigninSuccess();
563     error_screen_waiter.Wait();
564
565     ASSERT_TRUE(GetAppLaunchController()->showing_network_dialog());
566
567     SimulateNetworkOnline();
568     WaitForAppLaunchSuccess();
569   }
570
571   AppLaunchController* GetAppLaunchController() {
572     return chromeos::LoginDisplayHostImpl::default_host()
573         ->GetAppLaunchController();
574   }
575
576   // Returns a lock that is holding a task on the FILE thread. Any tasks posted
577   // to the FILE thread after this call will be blocked until the returned
578   // lock is released.
579   // This can be used to prevent app installation from completing until some
580   // other conditions are checked and triggered. For example, this can be used
581   // to trigger the network screen during app launch without racing with the
582   // app launching process itself.
583   scoped_ptr<base::AutoLock> LockFileThread() {
584     scoped_ptr<base::Lock> lock(new base::Lock);
585     scoped_ptr<base::AutoLock> auto_lock(new base::AutoLock(*lock));
586     content::BrowserThread::PostTask(
587         content::BrowserThread::FILE, FROM_HERE,
588         base::Bind(&LockAndUnlock, base::Passed(&lock)));
589     return auto_lock.Pass();
590   }
591
592   MockUserManager* mock_user_manager() { return mock_user_manager_.get(); }
593
594   void set_test_app_id(const std::string& test_app_id) {
595     test_app_id_ = test_app_id;
596   }
597   const std::string& test_app_id() const { return test_app_id_; }
598   void set_test_app_version(const std::string& version) {
599     test_app_version_ = version;
600   }
601   const std::string& test_app_version() const { return test_app_version_; }
602   void set_test_crx_file(const std::string& filename) {
603     test_crx_file_ = filename;
604   }
605   const std::string& test_crx_file() const { return test_crx_file_; }
606   FakeCWS* fake_cws() { return fake_cws_.get(); }
607
608  private:
609   std::string test_app_id_;
610   std::string test_app_version_;
611   std::string test_crx_file_;
612   scoped_ptr<FakeCWS> fake_cws_;
613   scoped_ptr<MockUserManager> mock_user_manager_;
614
615   DISALLOW_COPY_AND_ASSIGN(KioskTest);
616 };
617
618 IN_PROC_BROWSER_TEST_F(KioskTest, InstallAndLaunchApp) {
619   StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
620   WaitForAppLaunchSuccess();
621 }
622
623 IN_PROC_BROWSER_TEST_F(KioskTest, ZoomSupport) {
624   ExtensionTestMessageListener
625       app_window_loaded_listener("appWindowLoaded", false);
626   StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
627   app_window_loaded_listener.WaitUntilSatisfied();
628
629   Profile* app_profile = ProfileManager::GetPrimaryUserProfile();
630   ASSERT_TRUE(app_profile);
631
632   extensions::AppWindowRegistry* app_window_registry =
633       extensions::AppWindowRegistry::Get(app_profile);
634   extensions::AppWindow* window =
635       AppWindowWaiter(app_window_registry, test_app_id()).Wait();
636   ASSERT_TRUE(window);
637
638   // Gets the original width of the app window.
639   int original_width;
640   EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
641       window->web_contents(),
642       "window.domAutomationController.setAutomationId(0);"
643       "window.domAutomationController.send(window.innerWidth);",
644       &original_width));
645
646   native_app_window::NativeAppWindowViews* native_app_window_views =
647       static_cast<native_app_window::NativeAppWindowViews*>(
648           window->GetBaseWindow());
649   ui::AcceleratorTarget* accelerator_target =
650       static_cast<ui::AcceleratorTarget*>(native_app_window_views);
651
652   // Zoom in. Text is bigger and content window width becomes smaller.
653   accelerator_target->AcceleratorPressed(ui::Accelerator(
654       ui::VKEY_ADD, ui::EF_CONTROL_DOWN));
655   int width_zoomed_in;
656   EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
657       window->web_contents(),
658       "window.domAutomationController.setAutomationId(0);"
659       "window.domAutomationController.send(window.innerWidth);",
660       &width_zoomed_in));
661   DCHECK_LT(width_zoomed_in, original_width);
662
663   // Go back to normal. Window width is restored.
664   accelerator_target->AcceleratorPressed(ui::Accelerator(
665       ui::VKEY_0, ui::EF_CONTROL_DOWN));
666   int width_zoom_normal;
667   EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
668       window->web_contents(),
669       "window.domAutomationController.setAutomationId(0);"
670       "window.domAutomationController.send(window.innerWidth);",
671       &width_zoom_normal));
672   DCHECK_EQ(width_zoom_normal, original_width);
673
674   // Zoom out. Text is smaller and content window width becomes larger.
675   accelerator_target->AcceleratorPressed(ui::Accelerator(
676       ui::VKEY_SUBTRACT, ui::EF_CONTROL_DOWN));
677   int width_zoomed_out;
678   EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
679       window->web_contents(),
680       "window.domAutomationController.setAutomationId(0);"
681       "window.domAutomationController.send(window.innerWidth);",
682       &width_zoomed_out));
683   DCHECK_GT(width_zoomed_out, original_width);
684
685   // Terminate the app.
686   window->GetBaseWindow()->Close();
687   content::RunAllPendingInMessageLoop();
688 }
689
690 IN_PROC_BROWSER_TEST_F(KioskTest, NotSignedInWithGAIAAccount) {
691   // Tests that the kiosk session is not considered to be logged in with a GAIA
692   // account.
693   StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
694   WaitForAppLaunchSuccess();
695
696   Profile* app_profile = ProfileManager::GetPrimaryUserProfile();
697   ASSERT_TRUE(app_profile);
698   EXPECT_FALSE(app_profile->GetPrefs()->HasPrefPath(
699       prefs::kGoogleServicesUsername));
700 }
701
702 IN_PROC_BROWSER_TEST_F(KioskTest, PRE_LaunchAppNetworkDown) {
703   // Tests the network down case for the initial app download and launch.
704   RunAppLaunchNetworkDownTest();
705 }
706
707 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkDown) {
708   // Tests the network down case for launching an existing app that is
709   // installed in PRE_LaunchAppNetworkDown.
710   RunAppLaunchNetworkDownTest();
711 }
712
713 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppWithNetworkConfigAccelerator) {
714   ScopedCanConfigureNetwork can_configure_network(true, false);
715
716   // Block app loading until the network screen is shown.
717   scoped_ptr<base::AutoLock> lock = LockFileThread();
718
719   // Start app launch and wait for network connectivity timeout.
720   StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
721   OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
722   splash_waiter.Wait();
723
724   // A network error screen should be shown after authenticating.
725   OobeScreenWaiter error_screen_waiter(OobeDisplay::SCREEN_ERROR_MESSAGE);
726   // Simulate Ctrl+Alt+N accelerator.
727   GetLoginUI()->CallJavascriptFunction(
728       "cr.ui.Oobe.handleAccelerator",
729       base::StringValue("app_launch_network_config"));
730   error_screen_waiter.Wait();
731   ASSERT_TRUE(GetAppLaunchController()->showing_network_dialog());
732
733   // Continue button should be visible since we are online.
734   JsExpect("$('continue-network-config-btn').hidden == false");
735
736   // Click on [Continue] button.
737   ASSERT_TRUE(content::ExecuteScript(
738       GetLoginUI()->GetWebContents(),
739       "(function() {"
740       "var e = new Event('click');"
741       "$('continue-network-config-btn').dispatchEvent(e);"
742       "})();"));
743
744   // Let app launching resume.
745   lock.reset();
746
747   WaitForAppLaunchSuccess();
748 }
749
750 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkDownConfigureNotAllowed) {
751   // Mock network could not be configured.
752   ScopedCanConfigureNetwork can_configure_network(false, true);
753
754   // Start app launch and wait for network connectivity timeout.
755   StartAppLaunchFromLoginScreen(SimulateNetworkOfflineClosure());
756   OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
757   splash_waiter.Wait();
758   WaitForAppLaunchNetworkTimeout();
759
760   // Configure network link should not be visible.
761   JsExpect("$('splash-config-network').hidden == true");
762
763   // Network becomes online and app launch is resumed.
764   SimulateNetworkOnline();
765   WaitForAppLaunchSuccess();
766 }
767
768 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkPortal) {
769   // Mock network could be configured without the owner password.
770   ScopedCanConfigureNetwork can_configure_network(true, false);
771
772   // Start app launch with network portal state.
773   StartAppLaunchFromLoginScreen(SimulateNetworkPortalClosure());
774   OobeScreenWaiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH)
775       .WaitNoAssertCurrentScreen();
776   WaitForAppLaunchNetworkTimeout();
777
778   // Network error should show up automatically since this test does not
779   // require owner auth to configure network.
780   OobeScreenWaiter(OobeDisplay::SCREEN_ERROR_MESSAGE).Wait();
781
782   ASSERT_TRUE(GetAppLaunchController()->showing_network_dialog());
783   SimulateNetworkOnline();
784   WaitForAppLaunchSuccess();
785 }
786
787 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppUserCancel) {
788   // Make fake_cws_ return empty update response.
789   set_test_app_version("");
790   StartAppLaunchFromLoginScreen(SimulateNetworkOfflineClosure());
791   OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
792   splash_waiter.Wait();
793
794   CrosSettings::Get()->SetBoolean(
795       kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, true);
796   content::WindowedNotificationObserver signal(
797       chrome::NOTIFICATION_APP_TERMINATING,
798       content::NotificationService::AllSources());
799   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
800                                        base::StringValue("app_launch_bailout"));
801   signal.Wait();
802   EXPECT_EQ(chromeos::KioskAppLaunchError::USER_CANCEL,
803             chromeos::KioskAppLaunchError::Get());
804 }
805
806 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchInDiagnosticMode) {
807   PrepareAppLaunch();
808   SimulateNetworkOnline();
809
810   LaunchApp(kTestKioskApp, true);
811
812   content::WebContents* login_contents = GetLoginUI()->GetWebContents();
813
814   bool new_kiosk_ui = KioskAppMenuHandler::EnableNewKioskUI();
815   JsConditionWaiter(login_contents, new_kiosk_ui ?
816       kCheckDiagnosticModeNewAPI : kCheckDiagnosticModeOldAPI).Wait();
817
818   std::string diagnosticMode(new_kiosk_ui ?
819       kCheckDiagnosticModeNewAPI : kCheckDiagnosticModeOldAPI);
820   ASSERT_TRUE(content::ExecuteScript(
821       login_contents,
822       "(function() {"
823          "var e = new Event('click');" +
824          diagnosticMode + "."
825              "okButton_.dispatchEvent(e);"
826       "})();"));
827
828   WaitForAppLaunchSuccess();
829 }
830
831 IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningCancel) {
832   EnableConsumerKioskMode();
833
834   chromeos::WizardController::SkipPostLoginScreensForTesting();
835   chromeos::WizardController* wizard_controller =
836       chromeos::WizardController::default_controller();
837   CHECK(wizard_controller);
838
839   // Start login screen after configuring auto launch app since the warning
840   // is triggered when switching to login screen.
841   wizard_controller->AdvanceToScreen(WizardController::kNetworkScreenName);
842   ReloadAutolaunchKioskApps();
843   EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
844   EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
845   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
846
847   // Wait for the auto launch warning come up.
848   content::WindowedNotificationObserver(
849       chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
850       content::NotificationService::AllSources()).Wait();
851   GetLoginUI()->CallJavascriptFunction(
852       "login.AutolaunchScreen.confirmAutoLaunchForTesting",
853       base::FundamentalValue(false));
854
855   // Wait for the auto launch warning to go away.
856   content::WindowedNotificationObserver(
857       chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED,
858       content::NotificationService::AllSources()).Wait();
859
860   EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
861 }
862
863 IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningConfirm) {
864   EnableConsumerKioskMode();
865
866   chromeos::WizardController::SkipPostLoginScreensForTesting();
867   chromeos::WizardController* wizard_controller =
868       chromeos::WizardController::default_controller();
869   CHECK(wizard_controller);
870
871   // Start login screen after configuring auto launch app since the warning
872   // is triggered when switching to login screen.
873   wizard_controller->AdvanceToScreen(WizardController::kNetworkScreenName);
874   ReloadAutolaunchKioskApps();
875   EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
876   EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
877   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
878
879   // Wait for the auto launch warning come up.
880   content::WindowedNotificationObserver(
881       chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
882       content::NotificationService::AllSources()).Wait();
883   GetLoginUI()->CallJavascriptFunction(
884       "login.AutolaunchScreen.confirmAutoLaunchForTesting",
885       base::FundamentalValue(true));
886
887   // Wait for the auto launch warning to go away.
888   content::WindowedNotificationObserver(
889       chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED,
890       content::NotificationService::AllSources()).Wait();
891
892   EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
893   EXPECT_TRUE(KioskAppManager::Get()->IsAutoLaunchEnabled());
894
895   WaitForAppLaunchSuccess();
896 }
897
898 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableCancel) {
899   chromeos::WizardController::SkipPostLoginScreensForTesting();
900   chromeos::WizardController* wizard_controller =
901       chromeos::WizardController::default_controller();
902   CHECK(wizard_controller);
903
904   // Check Kiosk mode status.
905   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE,
906             GetConsumerKioskModeStatus());
907
908   // Wait for the login UI to come up and switch to the kiosk_enable screen.
909   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
910   OobeScreenWaiter(OobeDisplay::SCREEN_GAIA_SIGNIN).Wait();
911   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
912                                        base::StringValue("kiosk_enable"));
913
914   // Wait for the kiosk_enable screen to show and cancel the screen.
915   content::WindowedNotificationObserver(
916       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
917       content::NotificationService::AllSources()).Wait();
918   GetLoginUI()->CallJavascriptFunction(
919       "login.KioskEnableScreen.enableKioskForTesting",
920       base::FundamentalValue(false));
921
922   // Wait for the kiosk_enable screen to disappear.
923   content::WindowedNotificationObserver(
924       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED,
925       content::NotificationService::AllSources()).Wait();
926
927   // Check that the status still says configurable.
928   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE,
929             GetConsumerKioskModeStatus());
930 }
931
932 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableConfirmed) {
933   // Start UI, find menu entry for this app and launch it.
934   chromeos::WizardController::SkipPostLoginScreensForTesting();
935   chromeos::WizardController* wizard_controller =
936       chromeos::WizardController::default_controller();
937   CHECK(wizard_controller);
938
939   // Check Kiosk mode status.
940   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE,
941             GetConsumerKioskModeStatus());
942
943   // Wait for the login UI to come up and switch to the kiosk_enable screen.
944   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
945   OobeScreenWaiter(OobeDisplay::SCREEN_GAIA_SIGNIN).Wait();
946   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
947                                        base::StringValue("kiosk_enable"));
948
949   // Wait for the kiosk_enable screen to show and cancel the screen.
950   content::WindowedNotificationObserver(
951       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
952       content::NotificationService::AllSources()).Wait();
953   GetLoginUI()->CallJavascriptFunction(
954       "login.KioskEnableScreen.enableKioskForTesting",
955       base::FundamentalValue(true));
956
957   // Wait for the signal that indicates Kiosk Mode is enabled.
958   content::WindowedNotificationObserver(
959       chrome::NOTIFICATION_KIOSK_ENABLED,
960       content::NotificationService::AllSources()).Wait();
961   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_ENABLED,
962             GetConsumerKioskModeStatus());
963 }
964
965 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableAbortedWithAutoEnrollment) {
966   // Fake an auto enrollment is going to be enforced.
967   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
968       switches::kEnterpriseEnrollmentInitialModulus, "1");
969   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
970       switches::kEnterpriseEnrollmentModulusLimit, "2");
971   g_browser_process->local_state()->SetBoolean(prefs::kShouldAutoEnroll, true);
972   g_browser_process->local_state()->SetInteger(
973       prefs::kAutoEnrollmentPowerLimit, 3);
974
975   // Start UI, find menu entry for this app and launch it.
976   chromeos::WizardController::SkipPostLoginScreensForTesting();
977   chromeos::WizardController* wizard_controller =
978       chromeos::WizardController::default_controller();
979   CHECK(wizard_controller);
980
981   // Check Kiosk mode status.
982   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE,
983             GetConsumerKioskModeStatus());
984
985   // Wait for the login UI to come up and switch to the kiosk_enable screen.
986   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
987   OobeScreenWaiter(OobeDisplay::SCREEN_GAIA_SIGNIN).Wait();
988   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
989                                        base::StringValue("kiosk_enable"));
990
991   // The flow should be aborted due to auto enrollment enforcement.
992   scoped_refptr<content::MessageLoopRunner> runner =
993       new content::MessageLoopRunner;
994   GetSigninScreenHandler()->set_kiosk_enable_flow_aborted_callback_for_test(
995       runner->QuitClosure());
996   runner->Run();
997 }
998
999 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableAfter2ndSigninScreen) {
1000   chromeos::WizardController::SkipPostLoginScreensForTesting();
1001   chromeos::WizardController* wizard_controller =
1002       chromeos::WizardController::default_controller();
1003   CHECK(wizard_controller);
1004
1005   // Check Kiosk mode status.
1006   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE,
1007             GetConsumerKioskModeStatus());
1008
1009   // Wait for the login UI to come up and switch to the kiosk_enable screen.
1010   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
1011   OobeScreenWaiter(OobeDisplay::SCREEN_GAIA_SIGNIN).Wait();
1012   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
1013                                        base::StringValue("kiosk_enable"));
1014
1015   // Wait for the kiosk_enable screen to show and cancel the screen.
1016   content::WindowedNotificationObserver(
1017       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
1018       content::NotificationService::AllSources()).Wait();
1019   GetLoginUI()->CallJavascriptFunction(
1020       "login.KioskEnableScreen.enableKioskForTesting",
1021       base::FundamentalValue(false));
1022
1023   // Wait for the kiosk_enable screen to disappear.
1024   content::WindowedNotificationObserver(
1025       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED,
1026       content::NotificationService::AllSources()).Wait();
1027
1028   // Show signin screen again.
1029   chromeos::LoginDisplayHostImpl::default_host()->StartSignInScreen(
1030       LoginScreenContext());
1031   OobeScreenWaiter(OobeDisplay::SCREEN_GAIA_SIGNIN).Wait();
1032
1033   // Show kiosk enable screen again.
1034   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
1035                                        base::StringValue("kiosk_enable"));
1036
1037   // And it should show up.
1038   content::WindowedNotificationObserver(
1039       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
1040       content::NotificationService::AllSources()).Wait();
1041 }
1042
1043 class KioskUpdateTest : public KioskTest {
1044  public:
1045   KioskUpdateTest() {}
1046   virtual ~KioskUpdateTest() {}
1047
1048  protected:
1049   virtual void SetUp() OVERRIDE {
1050     fake_disk_mount_manager_ = new KioskFakeDiskMountManager();
1051     disks::DiskMountManager::InitializeForTesting(fake_disk_mount_manager_);
1052
1053     KioskTest::SetUp();
1054   }
1055
1056   virtual void TearDown() OVERRIDE {
1057     disks::DiskMountManager::Shutdown();
1058
1059     KioskTest::TearDown();
1060   }
1061
1062   virtual void SetUpOnMainThread() OVERRIDE {
1063     KioskTest::SetUpOnMainThread();
1064   }
1065
1066   void PreCacheApp(const std::string& app_id,
1067                    const std::string& version,
1068                    const std::string& crx_file) {
1069     set_test_app_id(app_id);
1070     set_test_app_version(version);
1071     set_test_crx_file(crx_file);
1072
1073     KioskAppManager* manager = KioskAppManager::Get();
1074     AppDataLoadWaiter waiter(manager, app_id, version);
1075     ReloadKioskApps();
1076     waiter.Wait();
1077     EXPECT_TRUE(waiter.loaded());
1078     std::string cached_version;
1079     base::FilePath file_path;
1080     EXPECT_TRUE(manager->GetCachedCrx(app_id, &file_path, &cached_version));
1081     EXPECT_EQ(version, cached_version);
1082   }
1083
1084   void UpdateExternalCache(const std::string& version,
1085                            const std::string& crx_file) {
1086     set_test_app_version(version);
1087     set_test_crx_file(crx_file);
1088     SetupTestAppUpdateCheck();
1089
1090     KioskAppManager* manager = KioskAppManager::Get();
1091     AppDataLoadWaiter waiter(manager, test_app_id(), version);
1092     KioskAppManager::Get()->UpdateExternalCache();
1093     waiter.Wait();
1094     EXPECT_TRUE(waiter.loaded());
1095     std::string cached_version;
1096     base::FilePath file_path;
1097     EXPECT_TRUE(
1098         manager->GetCachedCrx(test_app_id(), &file_path, &cached_version));
1099     EXPECT_EQ(version, cached_version);
1100   }
1101
1102   void SetupFakeDiskMountManagerMountPath(const std::string mount_path) {
1103     base::FilePath test_data_dir;
1104     PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
1105     test_data_dir = test_data_dir.AppendASCII(mount_path);
1106     fake_disk_mount_manager_->set_usb_mount_path(test_data_dir.value());
1107   }
1108
1109   void SimulateUpdateAppFromUsbStick(const std::string& usb_mount_path,
1110                                      bool* app_update_notified,
1111                                      bool* update_success) {
1112     SetupFakeDiskMountManagerMountPath(usb_mount_path);
1113     KioskAppExternalUpdateWaiter waiter(KioskAppManager::Get(), test_app_id());
1114     fake_disk_mount_manager_->MountUsbStick();
1115     waiter.Wait();
1116     fake_disk_mount_manager_->UnMountUsbStick();
1117     *update_success = waiter.update_success();
1118     *app_update_notified = waiter.app_update_notified();
1119   }
1120
1121   void PreCacheAndLaunchApp(const std::string& app_id,
1122                             const std::string& version,
1123                             const std::string& crx_file) {
1124     set_test_app_id(app_id);
1125     set_test_app_version(version);
1126     set_test_crx_file(crx_file);
1127     PrepareAppLaunch();
1128     SimulateNetworkOnline();
1129     LaunchApp(test_app_id(), false);
1130     WaitForAppLaunchSuccess();
1131     EXPECT_EQ(version, GetInstalledAppVersion().GetString());
1132   }
1133
1134  private:
1135   class KioskAppExternalUpdateWaiter : public KioskAppManagerObserver {
1136    public:
1137     KioskAppExternalUpdateWaiter(KioskAppManager* manager,
1138                                  const std::string& app_id)
1139         : runner_(NULL),
1140           manager_(manager),
1141           app_id_(app_id),
1142           quit_(false),
1143           update_success_(false),
1144           app_update_notified_(false) {
1145       manager_->AddObserver(this);
1146     }
1147
1148     virtual ~KioskAppExternalUpdateWaiter() { manager_->RemoveObserver(this); }
1149
1150     void Wait() {
1151       if (quit_)
1152         return;
1153       runner_ = new content::MessageLoopRunner;
1154       runner_->Run();
1155     }
1156
1157     bool update_success() const { return update_success_; }
1158
1159     bool app_update_notified() const { return app_update_notified_; }
1160
1161    private:
1162     // KioskAppManagerObserver overrides:
1163     virtual void OnKioskAppCacheUpdated(const std::string& app_id) OVERRIDE {
1164       if (app_id_ != app_id)
1165         return;
1166       app_update_notified_ = true;
1167     }
1168
1169     virtual void OnKioskAppExternalUpdateComplete(bool success) OVERRIDE {
1170       quit_ = true;
1171       update_success_ = success;
1172       if (runner_.get())
1173         runner_->Quit();
1174     }
1175
1176     scoped_refptr<content::MessageLoopRunner> runner_;
1177     KioskAppManager* manager_;
1178     bool wait_for_update_success_;
1179     const std::string app_id_;
1180     bool quit_;
1181     bool update_success_;
1182     bool app_update_notified_;
1183
1184     DISALLOW_COPY_AND_ASSIGN(KioskAppExternalUpdateWaiter);
1185   };
1186
1187   class AppDataLoadWaiter : public KioskAppManagerObserver {
1188    public:
1189     AppDataLoadWaiter(KioskAppManager* manager,
1190                       const std::string& app_id,
1191                       const std::string& version)
1192         : runner_(NULL),
1193           manager_(manager),
1194           loaded_(false),
1195           quit_(false),
1196           app_id_(app_id),
1197           version_(version) {
1198       manager_->AddObserver(this);
1199     }
1200
1201     virtual ~AppDataLoadWaiter() { manager_->RemoveObserver(this); }
1202
1203     void Wait() {
1204       if (quit_)
1205         return;
1206       runner_ = new content::MessageLoopRunner;
1207       runner_->Run();
1208     }
1209
1210     bool loaded() const { return loaded_; }
1211
1212    private:
1213     // KioskAppManagerObserver overrides:
1214     virtual void OnKioskExtensionLoadedInCache(
1215         const std::string& app_id) OVERRIDE {
1216       std::string cached_version;
1217       base::FilePath file_path;
1218       if (!manager_->GetCachedCrx(app_id_, &file_path, &cached_version))
1219         return;
1220       if (version_ != cached_version)
1221         return;
1222       loaded_ = true;
1223       quit_ = true;
1224       if (runner_.get())
1225         runner_->Quit();
1226     }
1227
1228     virtual void OnKioskExtensionDownloadFailed(
1229         const std::string& app_id) OVERRIDE {
1230       loaded_ = false;
1231       quit_ = true;
1232       if (runner_.get())
1233         runner_->Quit();
1234     }
1235
1236     scoped_refptr<content::MessageLoopRunner> runner_;
1237     KioskAppManager* manager_;
1238     bool loaded_;
1239     bool quit_;
1240     std::string app_id_;
1241     std::string version_;
1242
1243     DISALLOW_COPY_AND_ASSIGN(AppDataLoadWaiter);
1244   };
1245
1246   // Owned by DiskMountManager.
1247   KioskFakeDiskMountManager* fake_disk_mount_manager_;
1248
1249   DISALLOW_COPY_AND_ASSIGN(KioskUpdateTest);
1250 };
1251
1252 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_LaunchOfflineEnabledAppNoNetwork) {
1253   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
1254                        "1.0.0",
1255                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
1256 }
1257
1258 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, LaunchOfflineEnabledAppNoNetwork) {
1259   set_test_app_id(kTestOfflineEnabledKioskApp);
1260   StartUIForAppLaunch();
1261   SimulateNetworkOffline();
1262   LaunchApp(test_app_id(), false);
1263   WaitForAppLaunchSuccess();
1264
1265   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
1266 }
1267
1268 IN_PROC_BROWSER_TEST_F(KioskUpdateTest,
1269                        PRE_LaunchCachedOfflineEnabledAppNoNetwork) {
1270   PreCacheApp(kTestOfflineEnabledKioskApp,
1271               "1.0.0",
1272               std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
1273 }
1274
1275 IN_PROC_BROWSER_TEST_F(KioskUpdateTest,
1276                        LaunchCachedOfflineEnabledAppNoNetwork) {
1277   set_test_app_id(kTestOfflineEnabledKioskApp);
1278   EXPECT_TRUE(
1279       KioskAppManager::Get()->HasCachedCrx(kTestOfflineEnabledKioskApp));
1280   StartUIForAppLaunch();
1281   SimulateNetworkOffline();
1282   LaunchApp(test_app_id(), false);
1283   WaitForAppLaunchSuccess();
1284
1285   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
1286 }
1287
1288 // Network offline, app v1.0 has run before, has cached v2.0 crx and v2.0 should
1289 // be installed and launched during next launch.
1290 IN_PROC_BROWSER_TEST_F(KioskUpdateTest,
1291                        PRE_LaunchCachedNewVersionOfflineEnabledAppNoNetwork) {
1292   // Install and launch v1 app.
1293   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
1294                        "1.0.0",
1295                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
1296   // Update cache for v2 app.
1297   UpdateExternalCache("2.0.0",
1298                       std::string(kTestOfflineEnabledKioskApp) + ".crx");
1299   // The installed app is still in v1.
1300   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
1301 }
1302
1303 IN_PROC_BROWSER_TEST_F(KioskUpdateTest,
1304                        LaunchCachedNewVersionOfflineEnabledAppNoNetwork) {
1305   set_test_app_id(kTestOfflineEnabledKioskApp);
1306   EXPECT_TRUE(KioskAppManager::Get()->HasCachedCrx(test_app_id()));
1307
1308   StartUIForAppLaunch();
1309   SimulateNetworkOffline();
1310   LaunchApp(test_app_id(), false);
1311   WaitForAppLaunchSuccess();
1312
1313   // v2 app should have been installed.
1314   EXPECT_EQ("2.0.0", GetInstalledAppVersion().GetString());
1315 }
1316
1317 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_LaunchOfflineEnabledAppNoUpdate) {
1318   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
1319                        "1.0.0",
1320                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
1321 }
1322
1323 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, LaunchOfflineEnabledAppNoUpdate) {
1324   set_test_app_id(kTestOfflineEnabledKioskApp);
1325   fake_cws()->SetNoUpdate(test_app_id());
1326
1327   StartUIForAppLaunch();
1328   SimulateNetworkOnline();
1329   LaunchApp(test_app_id(), false);
1330   WaitForAppLaunchSuccess();
1331
1332   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
1333 }
1334
1335 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_LaunchOfflineEnabledAppHasUpdate) {
1336   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
1337                        "1.0.0",
1338                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
1339 }
1340
1341 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, LaunchOfflineEnabledAppHasUpdate) {
1342   set_test_app_id(kTestOfflineEnabledKioskApp);
1343   fake_cws()->SetUpdateCrx(
1344       test_app_id(), "ajoggoflpgplnnjkjamcmbepjdjdnpdp.crx", "2.0.0");
1345
1346   StartUIForAppLaunch();
1347   SimulateNetworkOnline();
1348   LaunchApp(test_app_id(), false);
1349   WaitForAppLaunchSuccess();
1350
1351   EXPECT_EQ("2.0.0", GetInstalledAppVersion().GetString());
1352 }
1353
1354 // Pre-cache v1 kiosk app, then launch the app without network,
1355 // plug in usb stick with a v2 app for offline updating.
1356 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_UsbStickUpdateAppNoNetwork) {
1357   PreCacheApp(kTestOfflineEnabledKioskApp,
1358               "1.0.0",
1359               std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
1360
1361   set_test_app_id(kTestOfflineEnabledKioskApp);
1362   StartUIForAppLaunch();
1363   SimulateNetworkOffline();
1364   LaunchApp(test_app_id(), false);
1365   WaitForAppLaunchSuccess();
1366   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
1367
1368   // Simulate mounting of usb stick with v2 app on the stick.
1369   bool update_success;
1370   bool app_update_notified;
1371   SimulateUpdateAppFromUsbStick(
1372       kFakeUsbMountPathUpdatePass, &app_update_notified, &update_success);
1373   EXPECT_TRUE(update_success);
1374   EXPECT_TRUE(app_update_notified);
1375
1376   // The v2 kiosk app is loaded into external cache, but won't be installed
1377   // until next time the device is started.
1378   base::FilePath crx_path;
1379   std::string cached_version;
1380   EXPECT_TRUE(KioskAppManager::Get()->GetCachedCrx(
1381       test_app_id(), &crx_path, &cached_version));
1382   EXPECT_EQ("2.0.0", cached_version);
1383   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
1384 }
1385
1386 // Restart the device, verify the app has been updated to v2.
1387 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppNoNetwork) {
1388   // Verify the kiosk app has been updated to v2.
1389   set_test_app_id(kTestOfflineEnabledKioskApp);
1390   StartUIForAppLaunch();
1391   SimulateNetworkOffline();
1392   LaunchApp(test_app_id(), false);
1393   WaitForAppLaunchSuccess();
1394   EXPECT_EQ("2.0.0", GetInstalledAppVersion().GetString());
1395 }
1396
1397 // Usb stick is plugged in without a manifest file on it.
1398 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppNoManifest) {
1399   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
1400                        "1.0.0",
1401                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
1402   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
1403
1404   // Simulate mounting of usb stick with v2 app on the stick.
1405   bool update_success;
1406   bool app_update_notified;
1407   SimulateUpdateAppFromUsbStick(
1408       kFakeUsbMountPathNoManifest, &app_update_notified, &update_success);
1409   EXPECT_FALSE(update_success);
1410
1411   // Kiosk app is not updated.
1412   base::FilePath crx_path;
1413   std::string cached_version;
1414   EXPECT_TRUE(KioskAppManager::Get()->GetCachedCrx(
1415       test_app_id(), &crx_path, &cached_version));
1416   EXPECT_EQ("1.0.0", cached_version);
1417 }
1418
1419 // Usb stick is plugged in with a bad manifest file on it.
1420 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppBadManifest) {
1421   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
1422                        "1.0.0",
1423                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
1424   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
1425
1426   // Simulate mounting of usb stick with v2 app on the stick.
1427   bool update_success;
1428   bool app_update_notified;
1429   SimulateUpdateAppFromUsbStick(
1430       kFakeUsbMountPathBadManifest, &app_update_notified, &update_success);
1431   EXPECT_FALSE(update_success);
1432
1433   // Kiosk app is not updated.
1434   base::FilePath crx_path;
1435   std::string cached_version;
1436   EXPECT_TRUE(KioskAppManager::Get()->GetCachedCrx(
1437       test_app_id(), &crx_path, &cached_version));
1438   EXPECT_EQ("1.0.0", cached_version);
1439 }
1440
1441 // Usb stick is plugged in with a lower version of crx file specified in
1442 // manifest.
1443 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppLowerAppVersion) {
1444   // Precache v2 version of app.
1445   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
1446                        "2.0.0",
1447                        std::string(kTestOfflineEnabledKioskApp) + ".crx");
1448   EXPECT_EQ("2.0.0", GetInstalledAppVersion().GetString());
1449
1450   // Simulate mounting of usb stick with v1 app on the stick.
1451   bool update_success;
1452   bool app_update_notified;
1453   SimulateUpdateAppFromUsbStick(
1454       kFakeUsbMountPathLowerAppVersion, &app_update_notified, &update_success);
1455   EXPECT_FALSE(update_success);
1456
1457   // Kiosk app is NOT updated to the lower version.
1458   base::FilePath crx_path;
1459   std::string cached_version;
1460   EXPECT_TRUE(KioskAppManager::Get()->GetCachedCrx(
1461       test_app_id(), &crx_path, &cached_version));
1462   EXPECT_EQ("2.0.0", cached_version);
1463 }
1464
1465 // Usb stick is plugged in with a v1 crx file, although the manifest says
1466 // this is a v3 version.
1467 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppLowerCrxVersion) {
1468   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
1469                        "2.0.0",
1470                        std::string(kTestOfflineEnabledKioskApp) + ".crx");
1471   EXPECT_EQ("2.0.0", GetInstalledAppVersion().GetString());
1472
1473   // Simulate mounting of usb stick with v1 crx file on the stick, although
1474   // the manifest says it is v3 app.
1475   bool update_success;
1476   bool app_update_notified;
1477   SimulateUpdateAppFromUsbStick(
1478       kFakeUsbMountPathLowerCrxVersion, &app_update_notified, &update_success);
1479   EXPECT_FALSE(update_success);
1480
1481   // Kiosk app is NOT updated to the lower version.
1482   base::FilePath crx_path;
1483   std::string cached_version;
1484   EXPECT_TRUE(KioskAppManager::Get()->GetCachedCrx(
1485       test_app_id(), &crx_path, &cached_version));
1486   EXPECT_EQ("2.0.0", cached_version);
1487 }
1488
1489 // Usb stick is plugged in with a bad crx file.
1490 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, UsbStickUpdateAppBadCrx) {
1491   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
1492                        "1.0.0",
1493                        std::string(kTestOfflineEnabledKioskApp) + "_v1.crx");
1494   EXPECT_EQ("1.0.0", GetInstalledAppVersion().GetString());
1495
1496   // Simulate mounting of usb stick with v1 crx file on the stick, although
1497   // the manifest says it is v3 app.
1498   bool update_success;
1499   bool app_update_notified;
1500   SimulateUpdateAppFromUsbStick(
1501       kFakeUsbMountPathBadCrx, &app_update_notified, &update_success);
1502   EXPECT_FALSE(update_success);
1503
1504   // Kiosk app is NOT updated.
1505   base::FilePath crx_path;
1506   std::string cached_version;
1507   EXPECT_TRUE(KioskAppManager::Get()->GetCachedCrx(
1508       test_app_id(), &crx_path, &cached_version));
1509   EXPECT_EQ("1.0.0", cached_version);
1510 }
1511
1512 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_PermissionChange) {
1513   PreCacheAndLaunchApp(kTestOfflineEnabledKioskApp,
1514                        "2.0.0",
1515                        std::string(kTestOfflineEnabledKioskApp) + ".crx");
1516 }
1517
1518 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PermissionChange) {
1519   set_test_app_id(kTestOfflineEnabledKioskApp);
1520   set_test_app_version("2.0.0");
1521   set_test_crx_file(test_app_id() + "_v2_permission_change.crx");
1522
1523   StartUIForAppLaunch();
1524   SimulateNetworkOnline();
1525   LaunchApp(test_app_id(), false);
1526   WaitForAppLaunchSuccess();
1527
1528   EXPECT_EQ("2.0.0", GetInstalledAppVersion().GetString());
1529 }
1530
1531 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PRE_PreserveLocalData) {
1532   // Installs v1 app and writes some local data.
1533   set_test_app_id(kTestLocalFsKioskApp);
1534   set_test_app_version("1.0.0");
1535   set_test_crx_file(test_app_id() + ".crx");
1536
1537   extensions::ResultCatcher catcher;
1538   StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
1539   WaitForAppLaunchAndOptionallyTerminateApp(false);
1540   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
1541 }
1542
1543 IN_PROC_BROWSER_TEST_F(KioskUpdateTest, PreserveLocalData) {
1544   // Update existing v1 app installed in PRE_PreserveLocalData to v2
1545   // that reads and verifies the local data.
1546   set_test_app_id(kTestLocalFsKioskApp);
1547   set_test_app_version("2.0.0");
1548   set_test_crx_file(test_app_id() + "_v2_read_and_verify_data.crx");
1549   extensions::ResultCatcher catcher;
1550   StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
1551   WaitForAppLaunchAndOptionallyTerminateApp(false);
1552
1553   EXPECT_EQ("2.0.0", GetInstalledAppVersion().GetString());
1554   ASSERT_TRUE(catcher.GetNextResult()) << catcher.message();
1555 }
1556
1557 class KioskEnterpriseTest : public KioskTest {
1558  protected:
1559   KioskEnterpriseTest() {}
1560
1561   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
1562     device_policy_test_helper_.MarkAsEnterpriseOwned();
1563     device_policy_test_helper_.InstallOwnerKey();
1564
1565     KioskTest::SetUpInProcessBrowserTestFixture();
1566   }
1567
1568   virtual void SetUpOnMainThread() OVERRIDE {
1569     set_test_app_id(kTestEnterpriseKioskApp);
1570     set_test_app_version("1.0.0");
1571     set_test_crx_file(test_app_id() + ".crx");
1572     SetupTestAppUpdateCheck();
1573
1574     KioskTest::SetUpOnMainThread();
1575     // Configure kTestEnterpriseKioskApp in device policy.
1576     em::DeviceLocalAccountsProto* accounts =
1577         device_policy_test_helper_.device_policy()->payload()
1578             .mutable_device_local_accounts();
1579     em::DeviceLocalAccountInfoProto* account = accounts->add_account();
1580     account->set_account_id(kTestEnterpriseAccountId);
1581     account->set_type(
1582         em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP);
1583     account->mutable_kiosk_app()->set_app_id(kTestEnterpriseKioskApp);
1584     accounts->set_auto_login_id(kTestEnterpriseAccountId);
1585     em::PolicyData& policy_data =
1586         device_policy_test_helper_.device_policy()->policy_data();
1587     policy_data.set_service_account_identity(kTestEnterpriseServiceAccountId);
1588     device_policy_test_helper_.device_policy()->Build();
1589
1590     base::RunLoop run_loop;
1591     DBusThreadManager::Get()->GetSessionManagerClient()->StoreDevicePolicy(
1592         device_policy_test_helper_.device_policy()->GetBlob(),
1593         base::Bind(&KioskEnterpriseTest::StorePolicyCallback,
1594                    run_loop.QuitClosure()));
1595     run_loop.Run();
1596
1597     DeviceSettingsService::Get()->Load();
1598
1599     // Configure OAuth authentication.
1600     GaiaUrls* gaia_urls = GaiaUrls::GetInstance();
1601
1602     // This token satisfies the userinfo.email request from
1603     // DeviceOAuth2TokenService used in token validation.
1604     FakeGaia::AccessTokenInfo userinfo_token_info;
1605     userinfo_token_info.token = kTestUserinfoToken;
1606     userinfo_token_info.scopes.insert(
1607         "https://www.googleapis.com/auth/userinfo.email");
1608     userinfo_token_info.audience = gaia_urls->oauth2_chrome_client_id();
1609     userinfo_token_info.email = kTestEnterpriseServiceAccountId;
1610     fake_gaia_->IssueOAuthToken(kTestRefreshToken, userinfo_token_info);
1611
1612     // The any-api access token for accessing the token minting endpoint.
1613     FakeGaia::AccessTokenInfo login_token_info;
1614     login_token_info.token = kTestLoginToken;
1615     login_token_info.scopes.insert(GaiaConstants::kAnyApiOAuth2Scope);
1616     login_token_info.audience = gaia_urls->oauth2_chrome_client_id();
1617     fake_gaia_->IssueOAuthToken(kTestRefreshToken, login_token_info);
1618
1619     // This is the access token requested by the app via the identity API.
1620     FakeGaia::AccessTokenInfo access_token_info;
1621     access_token_info.token = kTestAccessToken;
1622     access_token_info.scopes.insert(kTestAppScope);
1623     access_token_info.audience = kTestClientId;
1624     access_token_info.email = kTestEnterpriseServiceAccountId;
1625     fake_gaia_->IssueOAuthToken(kTestLoginToken, access_token_info);
1626
1627     DeviceOAuth2TokenService* token_service =
1628         DeviceOAuth2TokenServiceFactory::Get();
1629     token_service->SetAndSaveRefreshToken(
1630         kTestRefreshToken, DeviceOAuth2TokenService::StatusCallback());
1631     base::RunLoop().RunUntilIdle();
1632   }
1633
1634   static void StorePolicyCallback(const base::Closure& callback, bool result) {
1635     ASSERT_TRUE(result);
1636     callback.Run();
1637   }
1638
1639   policy::DevicePolicyCrosTestHelper device_policy_test_helper_;
1640
1641  private:
1642   DISALLOW_COPY_AND_ASSIGN(KioskEnterpriseTest);
1643 };
1644
1645 IN_PROC_BROWSER_TEST_F(KioskEnterpriseTest, EnterpriseKioskApp) {
1646   chromeos::WizardController::SkipPostLoginScreensForTesting();
1647   chromeos::WizardController* wizard_controller =
1648       chromeos::WizardController::default_controller();
1649   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
1650
1651   // Wait for the Kiosk App configuration to reload, then launch the app.
1652   KioskAppManager::App app;
1653   content::WindowedNotificationObserver app_config_waiter(
1654       chrome::NOTIFICATION_KIOSK_APPS_LOADED,
1655       base::Bind(&KioskAppManager::GetApp,
1656                  base::Unretained(KioskAppManager::Get()),
1657                  kTestEnterpriseKioskApp, &app));
1658   FireKioskAppSettingsChanged();
1659   app_config_waiter.Wait();
1660
1661   LaunchApp(kTestEnterpriseKioskApp, false);
1662
1663   // Wait for the Kiosk App to launch.
1664   content::WindowedNotificationObserver(
1665       chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
1666       content::NotificationService::AllSources()).Wait();
1667
1668   // Check installer status.
1669   EXPECT_EQ(chromeos::KioskAppLaunchError::NONE,
1670             chromeos::KioskAppLaunchError::Get());
1671
1672   // Wait for the window to appear.
1673   extensions::AppWindow* window =
1674       AppWindowWaiter(
1675           extensions::AppWindowRegistry::Get(
1676               ProfileManager::GetPrimaryUserProfile()),
1677           kTestEnterpriseKioskApp).Wait();
1678   ASSERT_TRUE(window);
1679
1680   // Check whether the app can retrieve an OAuth2 access token.
1681   std::string result;
1682   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
1683       window->web_contents(),
1684       "chrome.identity.getAuthToken({ 'interactive': false }, function(token) {"
1685       "    window.domAutomationController.setAutomationId(0);"
1686       "    window.domAutomationController.send(token);"
1687       "});",
1688       &result));
1689   EXPECT_EQ(kTestAccessToken, result);
1690
1691   // Verify that the session is not considered to be logged in with a GAIA
1692   // account.
1693   Profile* app_profile = ProfileManager::GetPrimaryUserProfile();
1694   ASSERT_TRUE(app_profile);
1695   EXPECT_FALSE(app_profile->GetPrefs()->HasPrefPath(
1696       prefs::kGoogleServicesUsername));
1697
1698   // Terminate the app.
1699   window->GetBaseWindow()->Close();
1700   content::RunAllPendingInMessageLoop();
1701 }
1702
1703 // Specialized test fixture for testing kiosk mode on the
1704 // hidden WebUI initialization flow for slow hardware.
1705 class KioskHiddenWebUITest : public KioskTest,
1706                              public ash::DesktopBackgroundControllerObserver {
1707  public:
1708   KioskHiddenWebUITest() : wallpaper_loaded_(false) {}
1709
1710   // KioskTest overrides:
1711   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
1712     KioskTest::SetUpCommandLine(command_line);
1713     command_line->AppendSwitch(switches::kDisableBootAnimation);
1714   }
1715
1716   virtual void SetUpOnMainThread() OVERRIDE {
1717     KioskTest::SetUpOnMainThread();
1718     ash::Shell::GetInstance()->desktop_background_controller()
1719         ->AddObserver(this);
1720   }
1721
1722   virtual void TearDownOnMainThread() OVERRIDE {
1723     ash::Shell::GetInstance()->desktop_background_controller()
1724         ->RemoveObserver(this);
1725     KioskTest::TearDownOnMainThread();
1726   }
1727
1728   void WaitForWallpaper() {
1729     if (!wallpaper_loaded_) {
1730       runner_ = new content::MessageLoopRunner;
1731       runner_->Run();
1732     }
1733   }
1734
1735   bool wallpaper_loaded() const { return wallpaper_loaded_; }
1736
1737   // ash::DesktopBackgroundControllerObserver overrides:
1738   virtual void OnWallpaperDataChanged() OVERRIDE {
1739     wallpaper_loaded_ = true;
1740     if (runner_.get())
1741       runner_->Quit();
1742   }
1743
1744   bool wallpaper_loaded_;
1745   scoped_refptr<content::MessageLoopRunner> runner_;
1746
1747   DISALLOW_COPY_AND_ASSIGN(KioskHiddenWebUITest);
1748 };
1749
1750 IN_PROC_BROWSER_TEST_F(KioskHiddenWebUITest, AutolaunchWarning) {
1751   // Add a device owner.
1752   FakeUserManager* user_manager = new FakeUserManager();
1753   user_manager->AddUser(kTestOwnerEmail);
1754   ScopedUserManagerEnabler enabler(user_manager);
1755
1756   // Set kiosk app to autolaunch.
1757   EnableConsumerKioskMode();
1758   chromeos::WizardController::SkipPostLoginScreensForTesting();
1759   chromeos::WizardController* wizard_controller =
1760       chromeos::WizardController::default_controller();
1761   CHECK(wizard_controller);
1762
1763   // Start login screen after configuring auto launch app since the warning
1764   // is triggered when switching to login screen.
1765   wizard_controller->AdvanceToScreen(WizardController::kNetworkScreenName);
1766   ReloadAutolaunchKioskApps();
1767   wizard_controller->SkipToLoginForTesting(LoginScreenContext());
1768
1769   EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
1770   EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
1771
1772   // Wait for the auto launch warning come up.
1773   content::WindowedNotificationObserver(
1774       chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
1775       content::NotificationService::AllSources()).Wait();
1776
1777   // Wait for the wallpaper to load.
1778   WaitForWallpaper();
1779   EXPECT_TRUE(wallpaper_loaded());
1780 }
1781
1782 }  // namespace chromeos