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