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