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