kiosk_browsertest.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
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
55namespace em = enterprise_management;
56
57namespace chromeos {
58
59namespace {
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
65const 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
72const 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/
81const 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
88const char kTestLocalFsKioskApp[] = "bmbpicmpniaclbbpdkfglgipkkebnbjf";
89
90// Timeout while waiting for network connectivity during tests.
91const int kTestNetworkTimeoutSeconds = 1;
92
93// Email of owner account for test.
94const char kTestOwnerEmail[] = "owner@example.com";
95
96const char kTestEnterpriseAccountId[] = "enterprise-kiosk-app@localhost";
97const char kTestEnterpriseServiceAccountId[] = "service_account@example.com";
98const char kTestRefreshToken[] = "fake-refresh-token";
99const char kTestUserinfoToken[] = "fake-userinfo-token";
100const char kTestLoginToken[] = "fake-login-token";
101const char kTestAccessToken[] = "fake-access-token";
102const char kTestClientId[] = "fake-client-id";
103const char kTestAppScope[] =
104    "https://www.googleapis.com/auth/userinfo.profile";
105
106// Test JS API.
107const char kLaunchAppForTestNewAPI[] =
108    "login.AccountPickerScreen.runAppForTesting";
109const char kLaunchAppForTestOldAPI[] =
110    "login.AppsMenuButton.runAppForTesting";
111const char kCheckDiagnosticModeNewAPI[] =
112    "$('oobe').confirmDiagnosticMode_";
113const char kCheckDiagnosticModeOldAPI[] =
114    "$('show-apps-button').confirmDiagnosticMode_";
115
116// Helper function for GetConsumerKioskAutoLaunchStatusCallback.
117void 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.
127void 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.
137void OnNetworkWaitTimedOut(const base::Closure& runner_quit_task) {
138  runner_quit_task.Run();
139}
140
141// Helper functions for CanConfigureNetwork mock.
142class 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.
181class 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
229class 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
516IN_PROC_BROWSER_TEST_F(KioskTest, InstallAndLaunchApp) {
517  StartAppLaunchFromLoginScreen(SimulateNetworkOnlineClosure());
518  WaitForAppLaunchSuccess();
519}
520
521IN_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
533IN_PROC_BROWSER_TEST_F(KioskTest, PRE_LaunchAppNetworkDown) {
534  // Tests the network down case for the initial app download and launch.
535  RunAppLaunchNetworkDownTest();
536}
537
538IN_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.
545IN_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
577IN_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
596IN_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
615IN_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
632IN_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
657IN_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
686IN_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
718IN_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
754IN_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
790IN_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
827IN_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
873class 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
894IN_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
905IN_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
920IN_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
936IN_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
954IN_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
964IN_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
982class 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
1065IN_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.
1122class 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
1168IN_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