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