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