- add sources.
[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/shell_window.h"
6 #include "apps/shell_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/bind.h"
12 #include "base/bind_helpers.h"
13 #include "base/command_line.h"
14 #include "base/location.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/message_loop/message_loop.h"
17 #include "base/path_service.h"
18 #include "base/prefs/scoped_user_pref_update.h"
19 #include "chrome/browser/browser_process.h"
20 #include "chrome/browser/chrome_browser_main.h"
21 #include "chrome/browser/chrome_browser_main_extra_parts.h"
22 #include "chrome/browser/chrome_content_browser_client.h"
23 #include "chrome/browser/chrome_notification_types.h"
24 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h"
25 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
26 #include "chrome/browser/chromeos/login/app_launch_controller.h"
27 #include "chrome/browser/chromeos/login/app_launch_signin_screen.h"
28 #include "chrome/browser/chromeos/login/existing_user_controller.h"
29 #include "chrome/browser/chromeos/login/fake_user_manager.h"
30 #include "chrome/browser/chromeos/login/login_display_host_impl.h"
31 #include "chrome/browser/chromeos/login/mock_user_manager.h"
32 #include "chrome/browser/chromeos/login/test/oobe_screen_waiter.h"
33 #include "chrome/browser/chromeos/login/webui_login_display.h"
34 #include "chrome/browser/chromeos/login/wizard_controller.h"
35 #include "chrome/browser/chromeos/policy/device_policy_cros_browser_test.h"
36 #include "chrome/browser/chromeos/settings/cros_settings.h"
37 #include "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
38 #include "chrome/browser/chromeos/settings/device_oauth2_token_service_factory.h"
39 #include "chrome/browser/extensions/extension_service.h"
40 #include "chrome/browser/extensions/extension_system.h"
41 #include "chrome/browser/extensions/extension_test_message_listener.h"
42 #include "chrome/browser/lifetime/application_lifetime.h"
43 #include "chrome/browser/policy/cloud/policy_builder.h"
44 #include "chrome/browser/policy/proto/chromeos/chrome_device_policy.pb.h"
45 #include "chrome/browser/profiles/profile_manager.h"
46 #include "chrome/browser/ui/browser.h"
47 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h"
48 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
49 #include "chrome/common/chrome_paths.h"
50 #include "chrome/common/chrome_switches.h"
51 #include "chrome/common/extensions/extension.h"
52 #include "chrome/common/pref_names.h"
53 #include "chrome/test/base/in_process_browser_test.h"
54 #include "chrome/test/base/interactive_test_utils.h"
55 #include "chrome/test/base/ui_test_utils.h"
56 #include "chromeos/chromeos_switches.h"
57 #include "chromeos/settings/cros_settings_names.h"
58 #include "content/public/browser/notification_observer.h"
59 #include "content/public/browser/notification_registrar.h"
60 #include "content/public/browser/notification_service.h"
61 #include "content/public/test/browser_test_utils.h"
62 #include "content/public/test/test_utils.h"
63 #include "google_apis/gaia/fake_gaia.h"
64 #include "google_apis/gaia/gaia_switches.h"
65 #include "net/base/network_change_notifier.h"
66 #include "net/dns/mock_host_resolver.h"
67 #include "net/test/embedded_test_server/embedded_test_server.h"
68 #include "net/test/embedded_test_server/http_request.h"
69 #include "net/test/embedded_test_server/http_response.h"
70 #include "testing/gmock/include/gmock/gmock.h"
71 #include "testing/gtest/include/gtest/gtest.h"
72 #include "ui/aura/window.h"
73 #include "ui/compositor/layer.h"
74
75 namespace em = enterprise_management;
76
77 namespace chromeos {
78
79 namespace {
80
81 // This is a simple test app that creates an app window and immediately closes
82 // it again. Webstore data json is in
83 //   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
84 //       detail/ggbflgnkafappblpkiflbgpmkfdpnhhe
85 const char kTestKioskApp[] = "ggbflgnkafappblpkiflbgpmkfdpnhhe";
86
87 // This app creates a window and declares usage of the identity API in its
88 // manifest, so we can test device robot token minting via the identity API.
89 // Webstore data json is in
90 //   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
91 //       detail/ibjkkfdnfcaoapcpheeijckmpcfkifob
92 const char kTestEnterpriseKioskApp[] = "ibjkkfdnfcaoapcpheeijckmpcfkifob";
93
94 // Timeout while waiting for network connectivity during tests.
95 const int kTestNetworkTimeoutSeconds = 1;
96
97 // Email of owner account for test.
98 const char kTestOwnerEmail[] = "owner@example.com";
99
100 const char kTestEnterpriseAccountId[] = "enterprise-kiosk-app@localhost";
101 const char kTestEnterpriseServiceAccountId[] = "service_account@example.com";
102 const char kTestRefreshToken[] = "fake-refresh-token";
103 const char kTestAccessToken[] = "fake-access-token";
104
105 // Helper function for GetConsumerKioskModeStatusCallback.
106 void ConsumerKioskModeStatusCheck(
107     KioskAppManager::ConsumerKioskModeStatus* out_status,
108     const base::Closure& runner_quit_task,
109     KioskAppManager::ConsumerKioskModeStatus in_status) {
110   LOG(INFO) << "KioskAppManager::ConsumerKioskModeStatus = " << in_status;
111   *out_status = in_status;
112   runner_quit_task.Run();
113 }
114
115 // Helper KioskAppManager::EnableKioskModeCallback implementation.
116 void ConsumerKioskModeLockCheck(
117     bool* out_locked,
118     const base::Closure& runner_quit_task,
119     bool in_locked) {
120   LOG(INFO) << "kiosk locked  = " << in_locked;
121   *out_locked = in_locked;
122   runner_quit_task.Run();
123 }
124
125 // Helper function for WaitForNetworkTimeOut.
126 void OnNetworkWaitTimedOut(const base::Closure& runner_quit_task) {
127   runner_quit_task.Run();
128 }
129
130 // Helper function for DeviceOAuth2TokenServiceFactory::Get().
131 void CopyTokenService(DeviceOAuth2TokenService** out_token_service,
132                       DeviceOAuth2TokenService* in_token_service) {
133   *out_token_service = in_token_service;
134 }
135
136 // Helper functions for CanConfigureNetwork mock.
137 class ScopedCanConfigureNetwork {
138  public:
139   explicit ScopedCanConfigureNetwork(bool can_configure)
140       : can_configure_(can_configure),
141         callback_(base::Bind(&ScopedCanConfigureNetwork::CanConfigureNetwork,
142                              base::Unretained(this))) {
143     AppLaunchController::SetCanConfigureNetworkCallbackForTesting(&callback_);
144   }
145   ~ScopedCanConfigureNetwork() {
146     AppLaunchController::SetCanConfigureNetworkCallbackForTesting(NULL);
147   }
148
149   bool CanConfigureNetwork() {
150     return can_configure_;
151   }
152
153  private:
154   bool can_configure_;
155   AppLaunchController::CanConfigureNetworkCallback callback_;
156   DISALLOW_COPY_AND_ASSIGN(ScopedCanConfigureNetwork);
157 };
158
159 }  // namespace
160
161 // Fake NetworkChangeNotifier used to simulate network connectivity.
162 class FakeNetworkChangeNotifier : public net::NetworkChangeNotifier {
163  public:
164   FakeNetworkChangeNotifier() : connection_type_(CONNECTION_NONE) {}
165
166   virtual ConnectionType GetCurrentConnectionType() const OVERRIDE {
167     return connection_type_;
168   }
169
170   void GoOnline() {
171     SetConnectionType(net::NetworkChangeNotifier::CONNECTION_ETHERNET);
172   }
173
174   void GoOffline() {
175     SetConnectionType(net::NetworkChangeNotifier::CONNECTION_NONE);
176   }
177
178   void SetConnectionType(ConnectionType type) {
179     connection_type_ = type;
180     NotifyObserversOfNetworkChange(type);
181     base::RunLoop().RunUntilIdle();
182   }
183
184   virtual ~FakeNetworkChangeNotifier() {}
185
186  private:
187   ConnectionType connection_type_;
188   DISALLOW_COPY_AND_ASSIGN(FakeNetworkChangeNotifier);
189 };
190
191 // Helper class that monitors app windows to wait for a window to appear.
192 class ShellWindowObserver : public apps::ShellWindowRegistry::Observer {
193  public:
194   ShellWindowObserver(apps::ShellWindowRegistry* registry,
195                       const std::string& app_id)
196       : registry_(registry), app_id_(app_id), window_(NULL), running_(false) {
197     registry_->AddObserver(this);
198   }
199   virtual ~ShellWindowObserver() {
200     registry_->RemoveObserver(this);
201   }
202
203   apps::ShellWindow* Wait() {
204     running_ = true;
205     message_loop_runner_ = new content::MessageLoopRunner;
206     message_loop_runner_->Run();
207     EXPECT_TRUE(window_);
208     return window_;
209   }
210
211   // ShellWindowRegistry::Observer
212   virtual void OnShellWindowAdded(apps::ShellWindow* shell_window) OVERRIDE {
213     if (!running_)
214       return;
215
216     if (shell_window->extension_id() == app_id_) {
217       window_ = shell_window;
218       message_loop_runner_->Quit();
219       running_ = false;
220     }
221   }
222   virtual void OnShellWindowIconChanged(
223       apps::ShellWindow* shell_window) OVERRIDE {}
224   virtual void OnShellWindowRemoved(apps::ShellWindow* shell_window) OVERRIDE {}
225
226  private:
227   apps::ShellWindowRegistry* registry_;
228   std::string app_id_;
229   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
230   apps::ShellWindow* window_;
231   bool running_;
232
233   DISALLOW_COPY_AND_ASSIGN(ShellWindowObserver);
234 };
235
236 class KioskTest : public InProcessBrowserTest {
237  public:
238   KioskTest() {
239     set_exit_when_last_browser_closes(false);
240   }
241
242   virtual ~KioskTest() {}
243
244  protected:
245   virtual void SetUp() OVERRIDE {
246     base::FilePath test_data_dir;
247     PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
248     embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
249     embedded_test_server()->RegisterRequestHandler(
250         base::Bind(&FakeGaia::HandleRequest, base::Unretained(&fake_gaia_)));
251     ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
252
253     mock_user_manager_.reset(new MockUserManager);
254     AppLaunchController::SkipSplashWaitForTesting();
255     AppLaunchController::SetNetworkWaitForTesting(kTestNetworkTimeoutSeconds);
256
257     InProcessBrowserTest::SetUp();
258   }
259
260   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
261     host_resolver()->AddRule("*", "127.0.0.1");
262   }
263
264   virtual void CleanUpOnMainThread() OVERRIDE {
265     // We need to clean up these objects in this specific order.
266     fake_network_notifier_.reset(NULL);
267     disable_network_notifier_.reset(NULL);
268
269     AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL);
270     AppLaunchSigninScreen::SetUserManagerForTesting(NULL);
271
272     // If the login display is still showing, exit gracefully.
273     if (LoginDisplayHostImpl::default_host()) {
274       base::MessageLoop::current()->PostTask(FROM_HERE,
275                                              base::Bind(&chrome::AttemptExit));
276       content::RunMessageLoop();
277     }
278
279     // Clean up while main thread still runs.
280     // See http://crbug.com/176659.
281     KioskAppManager::Get()->CleanUp();
282   }
283
284   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
285     command_line->AppendSwitch(chromeos::switches::kLoginManager);
286     command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests);
287     command_line->AppendSwitch(
288         chromeos::switches::kDisableChromeCaptivePortalDetector);
289     command_line->AppendSwitch(::switches::kDisableBackgroundNetworking);
290     command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user");
291
292     // Create gaia and webstore URL from test server url but using different
293     // host names. This is to avoid gaia response being tagged as from
294     // webstore in chrome_resource_dispatcher_host_delegate.cc.
295     const GURL& server_url = embedded_test_server()->base_url();
296
297     std::string gaia_host("gaia");
298     GURL::Replacements replace_gaia_host;
299     replace_gaia_host.SetHostStr(gaia_host);
300     GURL gaia_url = server_url.ReplaceComponents(replace_gaia_host);
301     command_line->AppendSwitchASCII(::switches::kGaiaUrl, gaia_url.spec());
302     command_line->AppendSwitchASCII(::switches::kLsoUrl, gaia_url.spec());
303     command_line->AppendSwitchASCII(::switches::kGoogleApisUrl,
304                                     gaia_url.spec());
305
306     std::string webstore_host("webstore");
307     GURL::Replacements replace_webstore_host;
308     replace_webstore_host.SetHostStr(webstore_host);
309     GURL webstore_url = server_url.ReplaceComponents(replace_webstore_host);
310     command_line->AppendSwitchASCII(
311         ::switches::kAppsGalleryURL,
312         webstore_url.Resolve("/chromeos/app_mode/webstore").spec());
313     command_line->AppendSwitchASCII(
314         ::switches::kAppsGalleryDownloadURL,
315         webstore_url.Resolve(
316             "/chromeos/app_mode/webstore/downloads/%s.crx").spec());
317   }
318
319   void ReloadKioskApps() {
320     KioskAppManager::Get()->AddApp(kTestKioskApp);
321   }
322
323   void ReloadAutolaunchKioskApps() {
324     KioskAppManager::Get()->AddApp(kTestKioskApp);
325     KioskAppManager::Get()->SetAutoLaunchApp(kTestKioskApp);
326   }
327
328   void StartAppLaunchFromLoginScreen(bool has_connectivity) {
329     EnableConsumerKioskMode();
330
331     // Start UI, find menu entry for this app and launch it.
332     content::WindowedNotificationObserver login_signal(
333       chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
334       content::NotificationService::AllSources());
335     chromeos::WizardController::SkipPostLoginScreensForTesting();
336     chromeos::WizardController* wizard_controller =
337         chromeos::WizardController::default_controller();
338     CHECK(wizard_controller);
339     wizard_controller->SkipToLoginForTesting();
340     login_signal.Wait();
341
342     // Wait for the Kiosk App configuration to reload, then launch the app.
343     content::WindowedNotificationObserver apps_loaded_signal(
344         chrome::NOTIFICATION_KIOSK_APPS_LOADED,
345         content::NotificationService::AllSources());
346     ReloadKioskApps();
347     apps_loaded_signal.Wait();
348
349     if (!has_connectivity)
350       SimulateNetworkOffline();
351
352     GetLoginUI()->CallJavascriptFunction(
353         "login.AppsMenuButton.runAppForTesting",
354         base::StringValue(kTestKioskApp));
355   }
356
357   void WaitForAppLaunchSuccess() {
358     SimulateNetworkOnline();
359
360     ExtensionTestMessageListener
361         launch_data_check_listener("launchData.isKioskSession = true", false);
362
363     // Wait for the Kiosk App to launch.
364     content::WindowedNotificationObserver(
365         chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
366         content::NotificationService::AllSources()).Wait();
367
368     // Default profile switches to app profile after app is launched.
369     Profile* app_profile = ProfileManager::GetDefaultProfile();
370     ASSERT_TRUE(app_profile);
371
372     // Check installer status.
373     EXPECT_EQ(chromeos::KioskAppLaunchError::NONE,
374               chromeos::KioskAppLaunchError::Get());
375
376     // Check if the kiosk webapp is really installed for the default profile.
377     const extensions::Extension* app =
378         extensions::ExtensionSystem::Get(app_profile)->
379         extension_service()->GetInstalledExtension(kTestKioskApp);
380     EXPECT_TRUE(app);
381
382     // App should appear with its window.
383     apps::ShellWindow* window = ShellWindowObserver(
384         apps::ShellWindowRegistry::Get(app_profile),
385         kTestKioskApp).Wait();
386     EXPECT_TRUE(window);
387
388     // Login screen should be fading out.
389     EXPECT_EQ(0.0f,
390               LoginDisplayHostImpl::default_host()
391                   ->GetNativeWindow()
392                   ->layer()
393                   ->GetTargetOpacity());
394
395     // Wait until the app terminates.
396     content::RunMessageLoop();
397
398     // Check that the app had been informed that it is running in a kiosk
399     // session.
400     EXPECT_TRUE(launch_data_check_listener.was_satisfied());
401   }
402
403   void SimulateNetworkOffline() {
404     disable_network_notifier_.reset(
405         new net::NetworkChangeNotifier::DisableForTest);
406
407     fake_network_notifier_.reset(new FakeNetworkChangeNotifier);
408   }
409
410   void SimulateNetworkOnline() {
411     if (fake_network_notifier_.get())
412       fake_network_notifier_->GoOnline();
413   }
414
415   void WaitForAppLaunchNetworkTimeout() {
416     if (GetAppLaunchController()->network_wait_timedout())
417       return;
418
419     scoped_refptr<content::MessageLoopRunner> runner =
420         new content::MessageLoopRunner;
421
422     base::Closure callback = base::Bind(
423         &OnNetworkWaitTimedOut, runner->QuitClosure());
424     AppLaunchController::SetNetworkTimeoutCallbackForTesting(&callback);
425
426     runner->Run();
427
428     CHECK(GetAppLaunchController()->network_wait_timedout());
429     AppLaunchController::SetNetworkTimeoutCallbackForTesting(NULL);
430   }
431
432   void EnableConsumerKioskMode() {
433     scoped_ptr<bool> locked(new bool(false));
434     scoped_refptr<content::MessageLoopRunner> runner =
435         new content::MessageLoopRunner;
436     KioskAppManager::Get()->EnableConsumerModeKiosk(
437         base::Bind(&ConsumerKioskModeLockCheck,
438                    locked.get(),
439                    runner->QuitClosure()));
440     runner->Run();
441     EXPECT_TRUE(*locked.get());
442   }
443
444   KioskAppManager::ConsumerKioskModeStatus GetConsumerKioskModeStatus() {
445     KioskAppManager::ConsumerKioskModeStatus status =
446         static_cast<KioskAppManager::ConsumerKioskModeStatus>(-1);
447     scoped_refptr<content::MessageLoopRunner> runner =
448         new content::MessageLoopRunner;
449     KioskAppManager::Get()->GetConsumerKioskModeStatus(
450         base::Bind(&ConsumerKioskModeStatusCheck,
451                    &status,
452                    runner->QuitClosure()));
453     runner->Run();
454     CHECK_NE(status, static_cast<KioskAppManager::ConsumerKioskModeStatus>(-1));
455     return status;
456   }
457
458   void JsExpect(const std::string& expression) {
459     bool result;
460     ASSERT_TRUE(content::ExecuteScriptAndExtractBool(
461         GetLoginUI()->GetWebContents(),
462         "window.domAutomationController.send(!!(" + expression + "));",
463          &result));
464     ASSERT_TRUE(result) << expression;
465   }
466
467   content::WebUI* GetLoginUI() {
468     return static_cast<chromeos::LoginDisplayHostImpl*>(
469         chromeos::LoginDisplayHostImpl::default_host())->GetOobeUI()->web_ui();
470   }
471
472   SigninScreenHandler* GetSigninScreenHandler() {
473     return static_cast<chromeos::LoginDisplayHostImpl*>(
474         chromeos::LoginDisplayHostImpl::default_host())
475         ->GetOobeUI()
476         ->signin_screen_handler_for_test();
477   }
478
479   AppLaunchController* GetAppLaunchController() {
480     return chromeos::LoginDisplayHostImpl::default_host()
481         ->GetAppLaunchController();
482   }
483
484   FakeGaia fake_gaia_;
485   scoped_ptr<net::NetworkChangeNotifier::DisableForTest>
486       disable_network_notifier_;
487   scoped_ptr<FakeNetworkChangeNotifier> fake_network_notifier_;
488   scoped_ptr<MockUserManager> mock_user_manager_;
489 };
490
491 IN_PROC_BROWSER_TEST_F(KioskTest, InstallAndLaunchApp) {
492   StartAppLaunchFromLoginScreen(true);
493   WaitForAppLaunchSuccess();
494 }
495
496 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkDown) {
497   // Mock network could be configured.
498   ScopedCanConfigureNetwork can_configure_network(true);
499
500   // Start app launch and wait for network connectivity timeout.
501   StartAppLaunchFromLoginScreen(false);
502   OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
503   splash_waiter.Wait();
504   WaitForAppLaunchNetworkTimeout();
505
506   // Configure network link should be visible.
507   JsExpect("$('splash-config-network').hidden == false");
508
509   // Set up fake user manager with an owner for the test.
510   mock_user_manager_->SetActiveUser(kTestOwnerEmail);
511   AppLaunchSigninScreen::SetUserManagerForTesting(mock_user_manager_.get());
512   static_cast<LoginDisplayHostImpl*>(LoginDisplayHostImpl::default_host())
513       ->GetOobeUI()->ShowOobeUI(false);
514
515   // Configure network should bring up lock screen for owner.
516   OobeScreenWaiter lock_screen_waiter(OobeDisplay::SCREEN_ACCOUNT_PICKER);
517   static_cast<AppLaunchSplashScreenActor::Delegate*>(GetAppLaunchController())
518     ->OnConfigureNetwork();
519   lock_screen_waiter.Wait();
520
521   // A network error screen should be shown after authenticating.
522   OobeScreenWaiter error_screen_waiter(OobeDisplay::SCREEN_ERROR_MESSAGE);
523   static_cast<AppLaunchSigninScreen::Delegate*>(GetAppLaunchController())
524       ->OnOwnerSigninSuccess();
525   error_screen_waiter.Wait();
526
527   ASSERT_TRUE(GetAppLaunchController()->showing_network_dialog());
528
529   WaitForAppLaunchSuccess();
530 }
531
532 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppNetworkDownConfigureNotAllowed) {
533   // Mock network could not be configured.
534   ScopedCanConfigureNetwork can_configure_network(false);
535
536   // Start app launch and wait for network connectivity timeout.
537   StartAppLaunchFromLoginScreen(false);
538   OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
539   splash_waiter.Wait();
540   WaitForAppLaunchNetworkTimeout();
541
542   // Configure network link should not be visible.
543   JsExpect("$('splash-config-network').hidden == true");
544
545   // Network becomes online and app launch is resumed.
546   WaitForAppLaunchSuccess();
547 }
548
549 IN_PROC_BROWSER_TEST_F(KioskTest, LaunchAppUserCancel) {
550   StartAppLaunchFromLoginScreen(false);
551   OobeScreenWaiter splash_waiter(OobeDisplay::SCREEN_APP_LAUNCH_SPLASH);
552   splash_waiter.Wait();
553
554   CrosSettings::Get()->SetBoolean(
555       kAccountsPrefDeviceLocalAccountAutoLoginBailoutEnabled, true);
556   content::WindowedNotificationObserver signal(
557       chrome::NOTIFICATION_APP_TERMINATING,
558       content::NotificationService::AllSources());
559   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
560                                        base::StringValue("app_launch_bailout"));
561   signal.Wait();
562   EXPECT_EQ(chromeos::KioskAppLaunchError::USER_CANCEL,
563             chromeos::KioskAppLaunchError::Get());
564 }
565
566 IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningCancel) {
567   EnableConsumerKioskMode();
568   // Start UI, find menu entry for this app and launch it.
569   chromeos::WizardController::SkipPostLoginScreensForTesting();
570   chromeos::WizardController* wizard_controller =
571       chromeos::WizardController::default_controller();
572   CHECK(wizard_controller);
573   ReloadAutolaunchKioskApps();
574   wizard_controller->SkipToLoginForTesting();
575
576   EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
577   EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
578
579   // Wait for the auto launch warning come up.
580   content::WindowedNotificationObserver(
581       chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
582       content::NotificationService::AllSources()).Wait();
583   GetLoginUI()->CallJavascriptFunction(
584       "login.AutolaunchScreen.confirmAutoLaunchForTesting",
585       base::FundamentalValue(false));
586
587   // Wait for the auto launch warning to go away.
588   content::WindowedNotificationObserver(
589       chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED,
590       content::NotificationService::AllSources()).Wait();
591
592   EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
593 }
594
595 IN_PROC_BROWSER_TEST_F(KioskTest, AutolaunchWarningConfirm) {
596   EnableConsumerKioskMode();
597   // Start UI, find menu entry for this app and launch it.
598   chromeos::WizardController::SkipPostLoginScreensForTesting();
599   chromeos::WizardController* wizard_controller =
600       chromeos::WizardController::default_controller();
601   CHECK(wizard_controller);
602   wizard_controller->SkipToLoginForTesting();
603
604   ReloadAutolaunchKioskApps();
605   EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
606   EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
607
608   // Wait for the auto launch warning come up.
609   content::WindowedNotificationObserver(
610       chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
611       content::NotificationService::AllSources()).Wait();
612   GetLoginUI()->CallJavascriptFunction(
613       "login.AutolaunchScreen.confirmAutoLaunchForTesting",
614       base::FundamentalValue(true));
615
616   // Wait for the auto launch warning to go away.
617   content::WindowedNotificationObserver(
618       chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED,
619       content::NotificationService::AllSources()).Wait();
620
621   EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
622   EXPECT_TRUE(KioskAppManager::Get()->IsAutoLaunchEnabled());
623
624   WaitForAppLaunchSuccess();
625 }
626
627 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableCancel) {
628   chromeos::WizardController::SkipPostLoginScreensForTesting();
629   chromeos::WizardController* wizard_controller =
630       chromeos::WizardController::default_controller();
631   CHECK(wizard_controller);
632
633   // Check Kiosk mode status.
634   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE,
635             GetConsumerKioskModeStatus());
636
637   // Wait for the login UI to come up and switch to the kiosk_enable screen.
638   wizard_controller->SkipToLoginForTesting();
639   content::WindowedNotificationObserver(
640       chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
641       content::NotificationService::AllSources()).Wait();
642   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
643                                        base::StringValue("kiosk_enable"));
644
645   // Wait for the kiosk_enable screen to show and cancel the screen.
646   content::WindowedNotificationObserver(
647       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
648       content::NotificationService::AllSources()).Wait();
649   GetLoginUI()->CallJavascriptFunction(
650       "login.KioskEnableScreen.enableKioskForTesting",
651       base::FundamentalValue(false));
652
653   // Wait for the kiosk_enable screen to disappear.
654   content::WindowedNotificationObserver(
655       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED,
656       content::NotificationService::AllSources()).Wait();
657
658   // Check that the status still says configurable.
659   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE,
660             GetConsumerKioskModeStatus());
661 }
662
663 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableConfirmed) {
664   // Start UI, find menu entry for this app and launch it.
665   chromeos::WizardController::SkipPostLoginScreensForTesting();
666   chromeos::WizardController* wizard_controller =
667       chromeos::WizardController::default_controller();
668   CHECK(wizard_controller);
669
670   // Check Kiosk mode status.
671   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE,
672             GetConsumerKioskModeStatus());
673   wizard_controller->SkipToLoginForTesting();
674
675   // Wait for the login UI to come up and switch to the kiosk_enable screen.
676   wizard_controller->SkipToLoginForTesting();
677   content::WindowedNotificationObserver(
678       chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
679       content::NotificationService::AllSources()).Wait();
680   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
681                                        base::StringValue("kiosk_enable"));
682
683   // Wait for the kiosk_enable screen to show and cancel the screen.
684   content::WindowedNotificationObserver(
685       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
686       content::NotificationService::AllSources()).Wait();
687   GetLoginUI()->CallJavascriptFunction(
688       "login.KioskEnableScreen.enableKioskForTesting",
689       base::FundamentalValue(true));
690
691   // Wait for the signal that indicates Kiosk Mode is enabled.
692   content::WindowedNotificationObserver(
693       chrome::NOTIFICATION_KIOSK_ENABLED,
694       content::NotificationService::AllSources()).Wait();
695   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_ENABLED,
696             GetConsumerKioskModeStatus());
697 }
698
699 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableAbortedWithAutoEnrollment) {
700   // Fake an auto enrollment is going to be enforced.
701   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
702       switches::kEnterpriseEnrollmentInitialModulus, "1");
703   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
704       switches::kEnterpriseEnrollmentModulusLimit, "2");
705   g_browser_process->local_state()->SetBoolean(prefs::kShouldAutoEnroll, true);
706   g_browser_process->local_state()->SetInteger(
707       prefs::kAutoEnrollmentPowerLimit, 3);
708
709   // Start UI, find menu entry for this app and launch it.
710   chromeos::WizardController::SkipPostLoginScreensForTesting();
711   chromeos::WizardController* wizard_controller =
712       chromeos::WizardController::default_controller();
713   CHECK(wizard_controller);
714
715   // Check Kiosk mode status.
716   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE,
717             GetConsumerKioskModeStatus());
718   wizard_controller->SkipToLoginForTesting();
719
720   // Wait for the login UI to come up and switch to the kiosk_enable screen.
721   wizard_controller->SkipToLoginForTesting();
722   content::WindowedNotificationObserver(
723       chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
724       content::NotificationService::AllSources()).Wait();
725   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
726                                        base::StringValue("kiosk_enable"));
727
728   // The flow should be aborted due to auto enrollment enforcement.
729   scoped_refptr<content::MessageLoopRunner> runner =
730       new content::MessageLoopRunner;
731   GetSigninScreenHandler()->set_kiosk_enable_flow_aborted_callback_for_test(
732       runner->QuitClosure());
733   runner->Run();
734 }
735
736 IN_PROC_BROWSER_TEST_F(KioskTest, KioskEnableAfter2ndSigninScreen) {
737   // Fake an auto enrollment is not going to be enforced.
738   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
739       switches::kEnterpriseEnrollmentInitialModulus, "1");
740   CommandLine::ForCurrentProcess()->AppendSwitchASCII(
741       switches::kEnterpriseEnrollmentModulusLimit, "2");
742   g_browser_process->local_state()->SetBoolean(prefs::kShouldAutoEnroll, false);
743   g_browser_process->local_state()->SetInteger(
744       prefs::kAutoEnrollmentPowerLimit, -1);
745
746   chromeos::WizardController::SkipPostLoginScreensForTesting();
747   chromeos::WizardController* wizard_controller =
748       chromeos::WizardController::default_controller();
749   CHECK(wizard_controller);
750
751   // Check Kiosk mode status.
752   EXPECT_EQ(KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE,
753             GetConsumerKioskModeStatus());
754
755   // Wait for the login UI to come up and switch to the kiosk_enable screen.
756   wizard_controller->SkipToLoginForTesting();
757   content::WindowedNotificationObserver(
758       chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE,
759       content::NotificationService::AllSources()).Wait();
760   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
761                                        base::StringValue("kiosk_enable"));
762
763   // Wait for the kiosk_enable screen to show and cancel the screen.
764   content::WindowedNotificationObserver(
765       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
766       content::NotificationService::AllSources()).Wait();
767   GetLoginUI()->CallJavascriptFunction(
768       "login.KioskEnableScreen.enableKioskForTesting",
769       base::FundamentalValue(false));
770
771   // Wait for the kiosk_enable screen to disappear.
772   content::WindowedNotificationObserver(
773       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED,
774       content::NotificationService::AllSources()).Wait();
775
776   // Show signin screen again.
777   chromeos::LoginDisplayHostImpl::default_host()->StartSignInScreen();
778   OobeScreenWaiter(OobeDisplay::SCREEN_GAIA_SIGNIN).Wait();
779
780   // Show kiosk enable screen again.
781   GetLoginUI()->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator",
782                                        base::StringValue("kiosk_enable"));
783
784   // And it should show up.
785   content::WindowedNotificationObserver(
786       chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE,
787       content::NotificationService::AllSources()).Wait();
788 }
789
790 class KioskEnterpriseTest : public KioskTest {
791  protected:
792   KioskEnterpriseTest() {}
793
794   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
795     device_policy_test_helper_.MarkAsEnterpriseOwned();
796     device_policy_test_helper_.InstallOwnerKey();
797
798     KioskTest::SetUpInProcessBrowserTestFixture();
799   }
800
801   virtual void SetUpOnMainThread() OVERRIDE {
802     // Configure kTestEnterpriseKioskApp in device policy.
803     em::DeviceLocalAccountsProto* accounts =
804         device_policy_test_helper_.device_policy()->payload()
805             .mutable_device_local_accounts();
806     em::DeviceLocalAccountInfoProto* account = accounts->add_account();
807     account->set_account_id(kTestEnterpriseAccountId);
808     account->set_type(
809         em::DeviceLocalAccountInfoProto::ACCOUNT_TYPE_KIOSK_APP);
810     account->mutable_kiosk_app()->set_app_id(kTestEnterpriseKioskApp);
811     accounts->set_auto_login_id(kTestEnterpriseAccountId);
812     em::PolicyData& policy_data =
813         device_policy_test_helper_.device_policy()->policy_data();
814     policy_data.set_service_account_identity(kTestEnterpriseServiceAccountId);
815     device_policy_test_helper_.device_policy()->Build();
816     DBusThreadManager::Get()->GetSessionManagerClient()->StoreDevicePolicy(
817         device_policy_test_helper_.device_policy()->GetBlob(),
818         base::Bind(&KioskEnterpriseTest::StorePolicyCallback));
819
820     DeviceSettingsService::Get()->Load();
821
822     // Configure OAuth authentication.
823     FakeGaia::AccessTokenInfo token_info;
824     token_info.token = kTestAccessToken;
825     token_info.email = kTestEnterpriseServiceAccountId;
826     fake_gaia_.IssueOAuthToken(kTestRefreshToken, token_info);
827     DeviceOAuth2TokenService* token_service = NULL;
828     DeviceOAuth2TokenServiceFactory::Get(
829         base::Bind(&CopyTokenService, &token_service));
830     base::RunLoop().RunUntilIdle();
831     ASSERT_TRUE(token_service);
832     token_service->SetAndSaveRefreshToken(kTestRefreshToken);
833
834     KioskTest::SetUpOnMainThread();
835   }
836
837   static void StorePolicyCallback(bool result) {
838     ASSERT_TRUE(result);
839   }
840
841   policy::DevicePolicyCrosTestHelper device_policy_test_helper_;
842
843  private:
844   DISALLOW_COPY_AND_ASSIGN(KioskEnterpriseTest);
845 };
846
847 // Disabled due to failures; http://crbug.com/306611.
848 IN_PROC_BROWSER_TEST_F(KioskEnterpriseTest, DISABLED_EnterpriseKioskApp) {
849   chromeos::WizardController::SkipPostLoginScreensForTesting();
850   chromeos::WizardController* wizard_controller =
851       chromeos::WizardController::default_controller();
852   wizard_controller->SkipToLoginForTesting();
853
854   // Wait for the Kiosk App configuration to reload, then launch the app.
855   KioskAppManager::App app;
856   content::WindowedNotificationObserver(
857       chrome::NOTIFICATION_KIOSK_APPS_LOADED,
858       base::Bind(&KioskAppManager::GetApp,
859                  base::Unretained(KioskAppManager::Get()),
860                  kTestEnterpriseKioskApp, &app)).Wait();
861
862   GetLoginUI()->CallJavascriptFunction(
863       "login.AppsMenuButton.runAppForTesting",
864       base::StringValue(kTestEnterpriseKioskApp));
865
866   // Wait for the Kiosk App to launch.
867   content::WindowedNotificationObserver(
868       chrome::NOTIFICATION_KIOSK_APP_LAUNCHED,
869       content::NotificationService::AllSources()).Wait();
870
871   // Check installer status.
872   EXPECT_EQ(chromeos::KioskAppLaunchError::NONE,
873             chromeos::KioskAppLaunchError::Get());
874
875   // Wait for the window to appear.
876   apps::ShellWindow* window = ShellWindowObserver(
877       apps::ShellWindowRegistry::Get(ProfileManager::GetDefaultProfile()),
878       kTestEnterpriseKioskApp).Wait();
879   ASSERT_TRUE(window);
880
881   // Check whether the app can retrieve an OAuth2 access token.
882   std::string result;
883   EXPECT_TRUE(content::ExecuteScriptAndExtractString(
884       window->web_contents(),
885       "chrome.identity.getAuthToken({ 'interactive': false }, function(token) {"
886       "    window.domAutomationController.send(token);"
887       "});",
888       &result));
889   EXPECT_EQ(kTestAccessToken, result);
890
891   // Terminate the app.
892   window->GetBaseWindow()->Close();
893   content::RunAllPendingInMessageLoop();
894 }
895
896 // Specialized test fixture for testing kiosk mode on the
897 // hidden WebUI initialization flow for slow hardware.
898 class KioskHiddenWebUITest : public KioskTest,
899                              public ash::DesktopBackgroundControllerObserver {
900  public:
901   KioskHiddenWebUITest() : wallpaper_loaded_(false) {}
902
903   // KioskTest overrides:
904   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
905     KioskTest::SetUpCommandLine(command_line);
906     command_line->AppendSwitchASCII(switches::kDeviceRegistered, "1");
907     command_line->AppendSwitch(switches::kDisableBootAnimation);
908     command_line->AppendSwitch(switches::kDisableOobeAnimation);
909   }
910
911   virtual void SetUpOnMainThread() OVERRIDE {
912     KioskTest::SetUpOnMainThread();
913     ash::Shell::GetInstance()->desktop_background_controller()
914         ->AddObserver(this);
915   }
916
917   virtual void TearDownOnMainThread() OVERRIDE {
918     ash::Shell::GetInstance()->desktop_background_controller()
919         ->RemoveObserver(this);
920     KioskTest::TearDownOnMainThread();
921   }
922
923   void WaitForWallpaper() {
924     if (!wallpaper_loaded_) {
925       runner_ = new content::MessageLoopRunner;
926       runner_->Run();
927     }
928   }
929
930   bool wallpaper_loaded() const { return wallpaper_loaded_; }
931
932   // ash::DesktopBackgroundControllerObserver overrides:
933   virtual void OnWallpaperDataChanged() OVERRIDE {
934     wallpaper_loaded_ = true;
935     if (runner_.get())
936       runner_->Quit();
937   }
938
939   bool wallpaper_loaded_;
940   scoped_refptr<content::MessageLoopRunner> runner_;
941
942   DISALLOW_COPY_AND_ASSIGN(KioskHiddenWebUITest);
943 };
944
945 IN_PROC_BROWSER_TEST_F(KioskHiddenWebUITest, AutolaunchWarning) {
946   // Add a device owner.
947   FakeUserManager* user_manager = new FakeUserManager();
948   user_manager->AddUser(kTestOwnerEmail);
949   ScopedUserManagerEnabler enabler(user_manager);
950
951   // Set kiosk app to autolaunch.
952   EnableConsumerKioskMode();
953   chromeos::WizardController::SkipPostLoginScreensForTesting();
954   chromeos::WizardController* wizard_controller =
955       chromeos::WizardController::default_controller();
956   CHECK(wizard_controller);
957   ReloadAutolaunchKioskApps();
958   wizard_controller->SkipToLoginForTesting();
959
960   EXPECT_FALSE(KioskAppManager::Get()->GetAutoLaunchApp().empty());
961   EXPECT_FALSE(KioskAppManager::Get()->IsAutoLaunchEnabled());
962
963   // Wait for the auto launch warning come up.
964   content::WindowedNotificationObserver(
965       chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE,
966       content::NotificationService::AllSources()).Wait();
967
968   // Wait for the wallpaper to load.
969   WaitForWallpaper();
970   EXPECT_TRUE(wallpaper_loaded());
971 }
972
973 }  // namespace chromeos