Home | History | Annotate | Download | only in login
      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 (at) example.com";
    122 
    123 const char kTestEnterpriseAccountId[] = "enterprise-kiosk-app@localhost";
    124 const char kTestEnterpriseServiceAccountId[] = "service_account (at) 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
   1783