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