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 "base/command_line.h" 6 #include "base/path_service.h" 7 #include "base/strings/stringprintf.h" 8 #include "chrome/browser/browser_process.h" 9 #include "chrome/browser/chrome_browser_main.h" 10 #include "chrome/browser/chrome_browser_main_extra_parts.h" 11 #include "chrome/browser/chrome_content_browser_client.h" 12 #include "chrome/browser/chrome_notification_types.h" 13 #include "chrome/browser/chromeos/app_mode/kiosk_app_launch_error.h" 14 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" 15 #include "chrome/browser/chromeos/cros/cros_in_process_browser_test.h" 16 #include "chrome/browser/chromeos/login/existing_user_controller.h" 17 #include "chrome/browser/chromeos/login/login_display_host_impl.h" 18 #include "chrome/browser/chromeos/login/webui_login_display.h" 19 #include "chrome/browser/chromeos/login/wizard_controller.h" 20 #include "chrome/browser/extensions/extension_service.h" 21 #include "chrome/browser/extensions/extension_system.h" 22 #include "chrome/browser/lifetime/application_lifetime.h" 23 #include "chrome/browser/prefs/scoped_user_pref_update.h" 24 #include "chrome/browser/profiles/profile_manager.h" 25 #include "chrome/browser/ui/browser.h" 26 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 27 #include "chrome/common/chrome_paths.h" 28 #include "chrome/common/chrome_switches.h" 29 #include "chrome/common/extensions/extension.h" 30 #include "chrome/test/base/in_process_browser_test.h" 31 #include "chrome/test/base/interactive_test_utils.h" 32 #include "chrome/test/base/ui_test_utils.h" 33 #include "chromeos/chromeos_switches.h" 34 #include "content/public/browser/notification_observer.h" 35 #include "content/public/browser/notification_registrar.h" 36 #include "content/public/browser/notification_service.h" 37 #include "content/public/test/test_utils.h" 38 #include "google_apis/gaia/gaia_switches.h" 39 #include "net/base/host_port_pair.h" 40 #include "net/dns/mock_host_resolver.h" 41 #include "net/test/embedded_test_server/embedded_test_server.h" 42 #include "net/test/embedded_test_server/http_request.h" 43 #include "net/test/embedded_test_server/http_response.h" 44 #include "testing/gmock/include/gmock/gmock.h" 45 #include "testing/gtest/include/gtest/gtest.h" 46 47 using namespace net::test_server; 48 49 namespace chromeos { 50 51 namespace { 52 53 const char kWebstoreDomain[] = "cws.com"; 54 const base::FilePath kServiceLogin("chromeos/service_login.html"); 55 56 // Webstore data json is in 57 // chrome/test/data/chromeos/app_mode/webstore/inlineinstall/ 58 // detail/ggbflgnkafappblpkiflbgpmkfdpnhhe 59 const char kTestKioskApp[] = "ggbflgnkafappblpkiflbgpmkfdpnhhe"; 60 61 // Helper method for GetConsumerKioskModeStatusCallback. 62 void ConsumerKioskModeStatusCheck( 63 KioskAppManager::ConsumerKioskModeStatus* out_status, 64 const base::Closure& runner_quit_task, 65 KioskAppManager::ConsumerKioskModeStatus in_status) { 66 LOG(INFO) << "KioskAppManager::ConsumerKioskModeStatus = " << in_status; 67 *out_status = in_status; 68 runner_quit_task.Run(); 69 } 70 71 // Helper KioskAppManager::EnableKioskModeCallback implementation. 72 void ConsumerKioskModeLockCheck( 73 bool* out_locked, 74 const base::Closure& runner_quit_task, 75 bool in_locked) { 76 LOG(INFO) << "kioks locked = " << in_locked; 77 *out_locked = in_locked; 78 runner_quit_task.Run(); 79 } 80 81 class TestBrowserMainExtraParts 82 : public ChromeBrowserMainExtraParts, 83 public content::NotificationObserver { 84 public: 85 TestBrowserMainExtraParts() {} 86 virtual ~TestBrowserMainExtraParts() {} 87 88 void set_quit_task(const base::Closure& quit_task) { quit_task_ = quit_task; } 89 90 void SetupSigninScreen() { 91 chromeos::ExistingUserController* controller = 92 chromeos::ExistingUserController::current_controller(); 93 CHECK(controller); 94 chromeos::WebUILoginDisplay* webui_login_display = 95 static_cast<chromeos::WebUILoginDisplay*>( 96 controller->login_display()); 97 CHECK(webui_login_display); 98 webui_login_display->ShowSigninScreenForCreds("username", "password"); 99 } 100 101 protected: 102 content::NotificationRegistrar registrar_; 103 base::Closure quit_task_; 104 105 DISALLOW_COPY_AND_ASSIGN(TestBrowserMainExtraParts); 106 }; 107 108 // Used to add an observer to NotificationService after it's created. 109 class KioskAppLaunchScenarioHandler : public TestBrowserMainExtraParts { 110 public: 111 KioskAppLaunchScenarioHandler() {} 112 113 virtual ~KioskAppLaunchScenarioHandler() {} 114 115 private: 116 // ChromeBrowserMainExtraParts implementation. 117 virtual void PreEarlyInitialization() OVERRIDE { 118 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, 119 content::NotificationService::AllSources()); 120 registrar_.Add(this, chrome::NOTIFICATION_KIOSK_APPS_LOADED, 121 content::NotificationService::AllSources()); 122 registrar_.Add(this, chrome::NOTIFICATION_KIOSK_APP_LAUNCHED, 123 content::NotificationService::AllSources()); 124 } 125 126 // Overridden from content::NotificationObserver: 127 virtual void Observe(int type, 128 const content::NotificationSource& source, 129 const content::NotificationDetails& details) OVERRIDE { 130 if (type == chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE) { 131 LOG(INFO) << "NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE"; 132 SetupSigninScreen(); 133 } else if (type == chrome::NOTIFICATION_KIOSK_APPS_LOADED) { 134 LOG(INFO) << "chrome::NOTIFICATION_KIOSK_APPS_LOADED"; 135 content::WebUI* web_ui = static_cast<chromeos::LoginDisplayHostImpl*>( 136 chromeos::LoginDisplayHostImpl::default_host())-> 137 GetOobeUI()->web_ui(); 138 web_ui->CallJavascriptFunction("login.AppsMenuButton.runAppForTesting", 139 base::StringValue(kTestKioskApp)); 140 } else if (type == chrome::NOTIFICATION_KIOSK_APP_LAUNCHED) { 141 LOG(INFO) << "chrome::NOTIFICATION_KIOSK_APP_LAUNCHED"; 142 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 143 content::NotificationService::AllSources()); 144 quit_task_.Run(); 145 } else if (type == content::NOTIFICATION_RENDERER_PROCESS_CLOSED) { 146 LOG(INFO) << "content::NOTIFICATION_RENDERER_PROCESS_CLOSED"; 147 quit_task_.Run(); 148 } else { 149 NOTREACHED(); 150 } 151 } 152 153 DISALLOW_COPY_AND_ASSIGN(KioskAppLaunchScenarioHandler); 154 }; 155 156 class AutostartWarningCancelScenarioHandler : public TestBrowserMainExtraParts { 157 public: 158 AutostartWarningCancelScenarioHandler() { 159 } 160 161 virtual ~AutostartWarningCancelScenarioHandler() {} 162 163 private: 164 // ChromeBrowserMainExtraParts implementation. 165 virtual void PreEarlyInitialization() OVERRIDE { 166 registrar_.Add(this, chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE, 167 content::NotificationService::AllSources()); 168 registrar_.Add(this, 169 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED, 170 content::NotificationService::AllSources()); 171 registrar_.Add(this, chrome::NOTIFICATION_KIOSK_APP_LAUNCHED, 172 content::NotificationService::AllSources()); 173 } 174 175 // Overridden from content::NotificationObserver: 176 virtual void Observe(int type, 177 const content::NotificationSource& source, 178 const content::NotificationDetails& details) OVERRIDE { 179 switch (type) { 180 case chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE: { 181 LOG(INFO) << "chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE"; 182 content::WebUI* web_ui = static_cast<chromeos::LoginDisplayHostImpl*>( 183 chromeos::LoginDisplayHostImpl::default_host())-> 184 GetOobeUI()->web_ui(); 185 web_ui->CallJavascriptFunction( 186 "login.AutolaunchScreen.confirmAutoLaunchForTesting", 187 base::FundamentalValue(false)); 188 break; 189 } 190 case chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED: { 191 LOG(INFO) << "chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED"; 192 quit_task_.Run(); 193 break; 194 } 195 case chrome::NOTIFICATION_KIOSK_APP_LAUNCHED: { 196 LOG(FATAL) << "chrome::NOTIFICATION_KIOSK_APP_LAUNCHED"; 197 break; 198 } 199 default: { 200 NOTREACHED(); 201 } 202 } 203 } 204 205 DISALLOW_COPY_AND_ASSIGN(AutostartWarningCancelScenarioHandler); 206 }; 207 208 class AutostartWarningConfirmScenarioHandler 209 : public TestBrowserMainExtraParts { 210 public: 211 AutostartWarningConfirmScenarioHandler() : first_pass_(true) { 212 } 213 214 virtual ~AutostartWarningConfirmScenarioHandler() {} 215 216 private: 217 // ChromeBrowserMainExtraParts implementation. 218 virtual void PreEarlyInitialization() OVERRIDE { 219 registrar_.Add(this, chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE, 220 content::NotificationService::AllSources()); 221 registrar_.Add(this, 222 chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED, 223 content::NotificationService::AllSources()); 224 registrar_.Add(this, chrome::NOTIFICATION_KIOSK_APP_LAUNCHED, 225 content::NotificationService::AllSources()); 226 } 227 228 // Overridden from content::NotificationObserver: 229 virtual void Observe(int type, 230 const content::NotificationSource& source, 231 const content::NotificationDetails& details) OVERRIDE { 232 switch (type) { 233 case chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE: { 234 LOG(INFO) << "chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE"; 235 if (!first_pass_) 236 break; 237 238 content::WebUI* web_ui = static_cast<chromeos::LoginDisplayHostImpl*>( 239 chromeos::LoginDisplayHostImpl::default_host())-> 240 GetOobeUI()->web_ui(); 241 web_ui->CallJavascriptFunction( 242 "login.AutolaunchScreen.confirmAutoLaunchForTesting", 243 base::FundamentalValue(true)); 244 } 245 case chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED: { 246 LOG(INFO) << "chrome::NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED"; 247 first_pass_ = false; 248 break; 249 } 250 case chrome::NOTIFICATION_KIOSK_APP_LAUNCHED: 251 LOG(INFO) << "chrome::NOTIFICATION_KIOSK_APP_LAUNCHED"; 252 registrar_.Add(this, content::NOTIFICATION_RENDERER_PROCESS_CLOSED, 253 content::NotificationService::AllSources()); 254 quit_task_.Run(); 255 break; 256 case content::NOTIFICATION_RENDERER_PROCESS_CLOSED: { 257 LOG(INFO) << "chrome::NOTIFICATION_RENDERER_PROCESS_CLOSED"; 258 quit_task_.Run(); 259 break; 260 } 261 default: { 262 NOTREACHED(); 263 } 264 } 265 } 266 267 bool first_pass_; 268 269 DISALLOW_COPY_AND_ASSIGN(AutostartWarningConfirmScenarioHandler); 270 }; 271 272 273 class KioskEnableScenarioHandler 274 : public TestBrowserMainExtraParts { 275 public: 276 explicit KioskEnableScenarioHandler(bool enable_kiosk) 277 : enable_kiosk_(enable_kiosk) { 278 } 279 280 virtual ~KioskEnableScenarioHandler() {} 281 282 private: 283 // ChromeBrowserMainExtraParts implementation. 284 virtual void PreEarlyInitialization() OVERRIDE { 285 registrar_.Add(this, chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE, 286 content::NotificationService::AllSources()); 287 registrar_.Add(this, chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE, 288 content::NotificationService::AllSources()); 289 registrar_.Add(this, 290 chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED, 291 content::NotificationService::AllSources()); 292 registrar_.Add(this, chrome::NOTIFICATION_KIOSK_ENABLED, 293 content::NotificationService::AllSources()); 294 } 295 296 // Overridden from content::NotificationObserver: 297 virtual void Observe(int type, 298 const content::NotificationSource& source, 299 const content::NotificationDetails& details) OVERRIDE { 300 switch (type) { 301 case chrome::NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE: { 302 LOG(INFO) << "NOTIFICATION_LOGIN_OR_LOCK_WEBUI_VISIBLE"; 303 SetupSigninScreen(); 304 content::WebUI* web_ui = static_cast<chromeos::LoginDisplayHostImpl*>( 305 chromeos::LoginDisplayHostImpl::default_host())-> 306 GetOobeUI()->web_ui(); 307 web_ui->CallJavascriptFunction("cr.ui.Oobe.handleAccelerator", 308 base::StringValue("kiosk_enable")); 309 break; 310 } 311 case chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE: { 312 LOG(INFO) << "chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE"; 313 content::WebUI* web_ui = static_cast<chromeos::LoginDisplayHostImpl*>( 314 chromeos::LoginDisplayHostImpl::default_host())-> 315 GetOobeUI()->web_ui(); 316 web_ui->CallJavascriptFunction( 317 "login.KioskEnableScreen.enableKioskForTesting", 318 base::FundamentalValue(enable_kiosk_)); 319 break; 320 } 321 case chrome::NOTIFICATION_KIOSK_ENABLED: { 322 LOG(INFO) << "chrome::NOTIFICATION_KIOSK_ENABLED"; 323 ASSERT_TRUE(enable_kiosk_); 324 quit_task_.Run(); 325 break; 326 } 327 case chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED: { 328 LOG(INFO) << "chrome::NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED"; 329 quit_task_.Run(); 330 break; 331 } 332 default: { 333 NOTREACHED(); 334 break; 335 } 336 } 337 } 338 339 bool enable_kiosk_; 340 DISALLOW_COPY_AND_ASSIGN(KioskEnableScenarioHandler); 341 }; 342 343 class TestContentBrowserClient : public chrome::ChromeContentBrowserClient { 344 public: 345 enum LaunchEventSequence { 346 KioskAppLaunch, 347 AutostartWarningCanceled, 348 AutostartWarningConfirmed, 349 KioskEnableRejected, 350 KioskEnableConfirmed, 351 }; 352 353 explicit TestContentBrowserClient(LaunchEventSequence sequence) 354 : browser_main_extra_parts_(NULL), sequence_(sequence) { 355 } 356 357 virtual ~TestContentBrowserClient() {} 358 359 virtual content::BrowserMainParts* CreateBrowserMainParts( 360 const content::MainFunctionParams& parameters) OVERRIDE { 361 ChromeBrowserMainParts* main_parts = static_cast<ChromeBrowserMainParts*>( 362 ChromeContentBrowserClient::CreateBrowserMainParts(parameters)); 363 364 switch (sequence_) { 365 case KioskAppLaunch: 366 browser_main_extra_parts_ = new KioskAppLaunchScenarioHandler(); 367 break; 368 case AutostartWarningCanceled: 369 browser_main_extra_parts_ = new AutostartWarningCancelScenarioHandler(); 370 break; 371 case AutostartWarningConfirmed: 372 browser_main_extra_parts_ = 373 new AutostartWarningConfirmScenarioHandler(); 374 break; 375 case KioskEnableRejected: 376 browser_main_extra_parts_ = 377 new KioskEnableScenarioHandler(false); 378 break; 379 case KioskEnableConfirmed: 380 browser_main_extra_parts_ = 381 new KioskEnableScenarioHandler(true); 382 break; 383 } 384 385 main_parts->AddParts(browser_main_extra_parts_); 386 return main_parts; 387 } 388 389 TestBrowserMainExtraParts* browser_main_extra_parts_; 390 391 private: 392 LaunchEventSequence sequence_; 393 394 DISALLOW_COPY_AND_ASSIGN(TestContentBrowserClient); 395 }; 396 397 } // namespace 398 399 400 class KioskTest : public chromeos::CrosInProcessBrowserTest, 401 // Param defining is multi-profiles enabled. 402 public testing::WithParamInterface<bool> { 403 public: 404 KioskTest() 405 : chromeos::CrosInProcessBrowserTest(), 406 original_content_browser_client_(NULL), 407 test_server_(NULL) { 408 set_exit_when_last_browser_closes(false); 409 } 410 411 virtual ~KioskTest() {} 412 413 protected: 414 virtual void InitializeKioskTest() = 0; 415 416 virtual void SetUpOnMainThread() OVERRIDE { 417 test_server_ = new EmbeddedTestServer( 418 content::BrowserThread::GetMessageLoopProxyForThread( 419 content::BrowserThread::IO)); 420 CHECK(test_server_->InitializeAndWaitUntilReady()); 421 test_server_->RegisterRequestHandler( 422 base::Bind(&KioskTest::HandleRequest, base::Unretained(this))); 423 LOG(INFO) << "Set up http server at " << test_server_->base_url(); 424 425 const GURL gaia_url("http://localhost:" + test_server_->base_url().port()); 426 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 427 ::switches::kGaiaUrl, gaia_url.spec()); 428 } 429 430 virtual void CleanUpOnMainThread() OVERRIDE { 431 // Clean up while main thread still runs. 432 // See http://crbug.com/176659. 433 KioskAppManager::Get()->CleanUp(); 434 435 LOG(INFO) << "Stopping the http server."; 436 EXPECT_TRUE(test_server_->ShutdownAndWaitUntilComplete()); 437 delete test_server_; // Destructor wants UI thread. 438 } 439 440 scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) { 441 GURL url = test_server_->GetURL(request.relative_url); 442 LOG(INFO) << "Http request: " << url.spec(); 443 444 scoped_ptr<BasicHttpResponse> http_response(new BasicHttpResponse()); 445 if (url.path() == "/ServiceLogin") { 446 http_response->set_code(net::HTTP_OK); 447 http_response->set_content(service_login_response_); 448 http_response->set_content_type("text/html"); 449 } else if (url.path() == "/ServiceLoginAuth") { 450 LOG(INFO) << "Params: " << request.content; 451 static const char kContinueParam[] = "continue="; 452 int continue_arg_begin = request.content.find(kContinueParam) + 453 arraysize(kContinueParam) - 1; 454 int continue_arg_end = request.content.find("&", continue_arg_begin); 455 const std::string continue_url = request.content.substr( 456 continue_arg_begin, continue_arg_end - continue_arg_begin); 457 http_response->set_code(net::HTTP_OK); 458 const std::string redirect_js = 459 "document.location.href = unescape('" + continue_url + "');"; 460 http_response->set_content( 461 "<HTML><HEAD><SCRIPT>\n" + redirect_js + "\n</SCRIPT></HEAD></HTML>"); 462 http_response->set_content_type("text/html"); 463 } else { 464 LOG(ERROR) << "Unsupported url: " << url.path(); 465 } 466 return http_response.PassAs<HttpResponse>(); 467 } 468 469 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 470 if (GetParam()) { 471 command_line->AppendSwitch(::switches::kMultiProfiles); 472 } 473 command_line->AppendSwitch(chromeos::switches::kLoginManager); 474 command_line->AppendSwitch(chromeos::switches::kForceLoginManagerInTests); 475 command_line->AppendSwitch( 476 chromeos::switches::kDisableChromeCaptivePortalDetector); 477 command_line->AppendSwitch(::switches::kDisableBackgroundNetworking); 478 command_line->AppendSwitchASCII(chromeos::switches::kLoginProfile, "user"); 479 480 ASSERT_TRUE(test_server()->Start()); 481 net::HostPortPair host_port = test_server()->host_port_pair(); 482 std::string test_gallery_url = base::StringPrintf( 483 "http://%s:%d/files/chromeos/app_mode/webstore", 484 kWebstoreDomain, host_port.port()); 485 command_line->AppendSwitchASCII( 486 ::switches::kAppsGalleryURL, test_gallery_url); 487 488 std::string test_gallery_download_url = test_gallery_url; 489 test_gallery_download_url.append("/downloads/%s.crx"); 490 command_line->AppendSwitchASCII( 491 ::switches::kAppsGalleryDownloadURL, test_gallery_download_url); 492 } 493 494 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE { 495 InitializeKioskTest(); 496 original_content_browser_client_ = content::SetBrowserClientForTesting( 497 content_browser_client_.get()); 498 499 base::FilePath test_data_dir; 500 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); 501 CHECK(file_util::ReadFileToString(test_data_dir.Append(kServiceLogin), 502 &service_login_response_)); 503 504 host_resolver()->AddRule(kWebstoreDomain, "127.0.0.1"); 505 } 506 507 void ReloadKioskApps() { 508 KioskAppManager::Get()->AddApp(kTestKioskApp); 509 } 510 511 void ReloadAutolaunchKioskApps() { 512 KioskAppManager::Get()->AddApp(kTestKioskApp); 513 KioskAppManager::Get()->SetAutoLaunchApp(kTestKioskApp); 514 } 515 516 void EnableConsumerKioskMode() { 517 scoped_ptr<bool> locked(new bool(false)); 518 scoped_refptr<content::MessageLoopRunner> runner = 519 new content::MessageLoopRunner; 520 KioskAppManager::Get()->EnableConsumerModeKiosk( 521 base::Bind(&ConsumerKioskModeLockCheck, 522 locked.get(), 523 runner->QuitClosure())); 524 runner->Run(); 525 EXPECT_TRUE(*locked.get()); 526 } 527 528 scoped_ptr<TestContentBrowserClient> content_browser_client_; 529 content::ContentBrowserClient* original_content_browser_client_; 530 std::string service_login_response_; 531 EmbeddedTestServer* test_server_; // cant use scoped_ptr because destructor 532 // needs UI thread. 533 }; 534 535 class KioskLaunchTest : public KioskTest { 536 public: 537 KioskLaunchTest() : KioskTest() {} 538 virtual ~KioskLaunchTest() {} 539 540 // KioskTest overrides. 541 virtual void InitializeKioskTest() OVERRIDE { 542 content_browser_client_.reset( 543 new TestContentBrowserClient(TestContentBrowserClient::KioskAppLaunch)); 544 } 545 }; 546 547 IN_PROC_BROWSER_TEST_P(KioskLaunchTest, InstallAndLaunchApp) { 548 EnableConsumerKioskMode(); 549 // Start UI, find menu entry for this app and launch it. 550 chromeos::WizardController::SkipPostLoginScreensForTesting(); 551 chromeos::WizardController* wizard_controller = 552 chromeos::WizardController::default_controller(); 553 CHECK(wizard_controller); 554 wizard_controller->SkipToLoginForTesting(); 555 556 ReloadKioskApps(); 557 558 // The first loop exits after we receive NOTIFICATION_KIOSK_APP_LAUNCHED 559 // notification - right at app launch. 560 scoped_refptr<content::MessageLoopRunner> runner = 561 new content::MessageLoopRunner; 562 content_browser_client_->browser_main_extra_parts_->set_quit_task( 563 runner->QuitClosure()); 564 runner->Run(); 565 566 // Check installer status. 567 EXPECT_EQ(chromeos::KioskAppLaunchError::NONE, 568 chromeos::KioskAppLaunchError::Get()); 569 570 // Check if the kiosk webapp is really installed for the default profile. 571 ASSERT_TRUE(ProfileManager::GetDefaultProfile()); 572 const extensions::Extension* app = 573 extensions::ExtensionSystem::Get(ProfileManager::GetDefaultProfile())-> 574 extension_service()->GetInstalledExtension(kTestKioskApp); 575 EXPECT_TRUE(app); 576 577 // The second loop exits when kiosk app terminates and we receive 578 // NOTIFICATION_RENDERER_PROCESS_CLOSED. 579 scoped_refptr<content::MessageLoopRunner> runner2 = 580 new content::MessageLoopRunner; 581 content_browser_client_->browser_main_extra_parts_->set_quit_task( 582 runner2->QuitClosure()); 583 runner2->Run(); 584 } 585 586 class KioskAutolaunchCancelTest : public KioskTest { 587 public: 588 KioskAutolaunchCancelTest() : KioskTest(), login_display_host_(NULL) {} 589 virtual ~KioskAutolaunchCancelTest() {} 590 591 private: 592 // Overrides from KioskTest. 593 virtual void InitializeKioskTest() OVERRIDE { 594 content_browser_client_.reset(new TestContentBrowserClient( 595 TestContentBrowserClient::AutostartWarningCanceled)); 596 } 597 598 virtual void SetUpOnMainThread() OVERRIDE { 599 login_display_host_ = LoginDisplayHostImpl::default_host(); 600 KioskTest::SetUpOnMainThread(); 601 } 602 603 virtual void CleanUpOnMainThread() OVERRIDE { 604 // LoginDisplayHost owns controllers and all windows. 605 base::MessageLoopForUI::current()->DeleteSoon(FROM_HERE, 606 login_display_host_); 607 KioskTest::CleanUpOnMainThread(); 608 } 609 610 LoginDisplayHost* login_display_host_; 611 }; 612 613 IN_PROC_BROWSER_TEST_P(KioskAutolaunchCancelTest, AutolaunchWarningCancel) { 614 EnableConsumerKioskMode(); 615 // Start UI, find menu entry for this app and launch it. 616 chromeos::WizardController::SkipPostLoginScreensForTesting(); 617 chromeos::WizardController* wizard_controller = 618 chromeos::WizardController::default_controller(); 619 CHECK(wizard_controller); 620 ReloadAutolaunchKioskApps(); 621 wizard_controller->SkipToLoginForTesting(); 622 623 EXPECT_FALSE( 624 KioskAppManager::Get()->GetAutoLaunchApp().empty()); 625 EXPECT_FALSE( 626 KioskAppManager::Get()->IsAutoLaunchEnabled()); 627 628 // The loop exits after we receive 629 // NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_COMPLETED after 630 // NOTIFICATION_KIOSK_AUTOLAUNCH_WARNING_VISIBLE notification - right after 631 // auto launch is canceled. 632 scoped_refptr<content::MessageLoopRunner> runner = 633 new content::MessageLoopRunner; 634 content_browser_client_->browser_main_extra_parts_->set_quit_task( 635 runner->QuitClosure()); 636 runner->Run(); 637 638 EXPECT_FALSE( 639 KioskAppManager::Get()->IsAutoLaunchEnabled()); 640 } 641 642 class KioskAutolaunchConfirmTest : public KioskTest { 643 public: 644 KioskAutolaunchConfirmTest() : KioskTest() {} 645 virtual ~KioskAutolaunchConfirmTest() {} 646 647 private: 648 // Overrides from KioskTest. 649 virtual void InitializeKioskTest() OVERRIDE { 650 content_browser_client_.reset(new TestContentBrowserClient( 651 TestContentBrowserClient::AutostartWarningConfirmed)); 652 } 653 }; 654 655 IN_PROC_BROWSER_TEST_P(KioskAutolaunchConfirmTest, AutolaunchWarningConfirm) { 656 EnableConsumerKioskMode(); 657 // Start UI, find menu entry for this app and launch it. 658 chromeos::WizardController::SkipPostLoginScreensForTesting(); 659 chromeos::WizardController* wizard_controller = 660 chromeos::WizardController::default_controller(); 661 CHECK(wizard_controller); 662 wizard_controller->SkipToLoginForTesting(); 663 664 ReloadAutolaunchKioskApps(); 665 EXPECT_FALSE( 666 KioskAppManager::Get()->GetAutoLaunchApp().empty()); 667 EXPECT_FALSE( 668 KioskAppManager::Get()->IsAutoLaunchEnabled()); 669 670 // The loop exits after we receive NOTIFICATION_KIOSK_APP_LAUNCHED 671 // notification - right at app launch. 672 scoped_refptr<content::MessageLoopRunner> runner = 673 new content::MessageLoopRunner; 674 content_browser_client_->browser_main_extra_parts_->set_quit_task( 675 runner->QuitClosure()); 676 runner->Run(); 677 678 EXPECT_FALSE( 679 KioskAppManager::Get()->GetAutoLaunchApp().empty()); 680 EXPECT_TRUE( 681 KioskAppManager::Get()->IsAutoLaunchEnabled()); 682 683 // Check installer status. 684 EXPECT_EQ(chromeos::KioskAppLaunchError::NONE, 685 chromeos::KioskAppLaunchError::Get()); 686 687 // Check if the kiosk webapp is really installed for the default profile. 688 ASSERT_TRUE(ProfileManager::GetDefaultProfile()); 689 const extensions::Extension* app = 690 extensions::ExtensionSystem::Get(ProfileManager::GetDefaultProfile())-> 691 extension_service()->GetInstalledExtension(kTestKioskApp); 692 EXPECT_TRUE(app); 693 694 // The second loop exits when kiosk app terminates and we receive 695 // NOTIFICATION_RENDERER_PROCESS_CLOSED. 696 scoped_refptr<content::MessageLoopRunner> runner2 = 697 new content::MessageLoopRunner; 698 content_browser_client_->browser_main_extra_parts_->set_quit_task( 699 runner2->QuitClosure()); 700 runner2->Run(); 701 } 702 703 class KioskEnableTest : public KioskTest { 704 public: 705 KioskEnableTest() : login_display_host_(NULL) {} 706 virtual ~KioskEnableTest() {} 707 708 private: 709 // Overrides from KioskTest. 710 virtual void SetUpOnMainThread() OVERRIDE { 711 login_display_host_ = LoginDisplayHostImpl::default_host(); 712 KioskTest::SetUpOnMainThread(); 713 } 714 715 virtual void CleanUpOnMainThread() OVERRIDE { 716 // LoginDisplayHost owns controllers and all windows. 717 base::MessageLoopForUI::current()->DeleteSoon(FROM_HERE, 718 login_display_host_); 719 KioskTest::CleanUpOnMainThread(); 720 } 721 722 LoginDisplayHost* login_display_host_; 723 }; 724 725 class KioskEnableCancelTest : public KioskEnableTest { 726 public: 727 KioskEnableCancelTest() {} 728 virtual ~KioskEnableCancelTest() {} 729 730 private: 731 // Overrides from KioskTest. 732 virtual void InitializeKioskTest() OVERRIDE { 733 content_browser_client_.reset(new TestContentBrowserClient( 734 TestContentBrowserClient::KioskEnableRejected)); 735 } 736 }; 737 738 IN_PROC_BROWSER_TEST_P(KioskEnableCancelTest, KioskEnableCancel) { 739 // Start UI, find menu entry for this app and launch it. 740 chromeos::WizardController::SkipPostLoginScreensForTesting(); 741 chromeos::WizardController* wizard_controller = 742 chromeos::WizardController::default_controller(); 743 CHECK(wizard_controller); 744 745 scoped_refptr<content::MessageLoopRunner> runner = 746 new content::MessageLoopRunner; 747 // Check the intial state of the consumer kiosk. 748 scoped_ptr<KioskAppManager::ConsumerKioskModeStatus> status( 749 new KioskAppManager::ConsumerKioskModeStatus( 750 KioskAppManager::CONSUMER_KIOSK_MODE_DISABLED)); 751 KioskAppManager::Get()->GetConsumerKioskModeStatus( 752 base::Bind(&ConsumerKioskModeStatusCheck, 753 status.get(), 754 runner->QuitClosure())); 755 runner->Run(); 756 EXPECT_EQ(*status.get(), KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE); 757 758 wizard_controller->SkipToLoginForTesting(); 759 // The loop exits after we receive 760 // NOTIFICATION_KIOSK_ENABLE_WARNING_COMPLETED after 761 // NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE notification - right after 762 // enable consumer kiosk screen is canceled. 763 scoped_refptr<content::MessageLoopRunner> runner2 = 764 new content::MessageLoopRunner; 765 content_browser_client_->browser_main_extra_parts_->set_quit_task( 766 runner2->QuitClosure()); 767 runner2->Run(); 768 769 scoped_refptr<content::MessageLoopRunner> runner3 = 770 new content::MessageLoopRunner; 771 // Check the end state of the consumer kiosk after disabling the feature. 772 KioskAppManager::Get()->GetConsumerKioskModeStatus( 773 base::Bind(&ConsumerKioskModeStatusCheck, 774 status.get(), 775 runner3->QuitClosure())); 776 runner3->Run(); 777 EXPECT_EQ(*status.get(), KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE); 778 } 779 780 781 class KioskEnableConfirmedTest : public KioskEnableTest { 782 public: 783 KioskEnableConfirmedTest() {} 784 virtual ~KioskEnableConfirmedTest() {} 785 786 private: 787 // Overrides from KioskTest. 788 virtual void InitializeKioskTest() OVERRIDE { 789 content_browser_client_.reset(new TestContentBrowserClient( 790 TestContentBrowserClient::KioskEnableConfirmed)); 791 } 792 }; 793 794 IN_PROC_BROWSER_TEST_P(KioskEnableConfirmedTest, KioskEnableConfirmed) { 795 // Start UI, find menu entry for this app and launch it. 796 chromeos::WizardController::SkipPostLoginScreensForTesting(); 797 chromeos::WizardController* wizard_controller = 798 chromeos::WizardController::default_controller(); 799 CHECK(wizard_controller); 800 801 scoped_refptr<content::MessageLoopRunner> runner = 802 new content::MessageLoopRunner; 803 // Check the intial state of the consumer kiosk. 804 scoped_ptr<KioskAppManager::ConsumerKioskModeStatus> status( 805 new KioskAppManager::ConsumerKioskModeStatus( 806 KioskAppManager::CONSUMER_KIOSK_MODE_DISABLED)); 807 KioskAppManager::Get()->GetConsumerKioskModeStatus( 808 base::Bind(&ConsumerKioskModeStatusCheck, 809 status.get(), 810 runner->QuitClosure())); 811 runner->Run(); 812 EXPECT_EQ(*status.get(), KioskAppManager::CONSUMER_KIOSK_MODE_CONFIGURABLE); 813 814 wizard_controller->SkipToLoginForTesting(); 815 // The loop exits after we receive 816 // NOTIFICATION_KIOSK_ENABLED after 817 // NOTIFICATION_KIOSK_ENABLE_WARNING_VISIBLE notification - right after 818 // enable consumer kiosk screen is canceled. 819 scoped_refptr<content::MessageLoopRunner> runner2 = 820 new content::MessageLoopRunner; 821 content_browser_client_->browser_main_extra_parts_->set_quit_task( 822 runner2->QuitClosure()); 823 runner2->Run(); 824 825 scoped_refptr<content::MessageLoopRunner> runner3 = 826 new content::MessageLoopRunner; 827 // Check the end state of the consumer kiosk after disabling the feature. 828 KioskAppManager::Get()->GetConsumerKioskModeStatus( 829 base::Bind(&ConsumerKioskModeStatusCheck, 830 status.get(), 831 runner3->QuitClosure())); 832 runner3->Run(); 833 EXPECT_EQ(*status.get(), KioskAppManager::CONSUMER_KIOSK_MODE_ENABLED); 834 } 835 836 INSTANTIATE_TEST_CASE_P(KioskLaunchTestInstantiation, 837 KioskLaunchTest, 838 testing::Bool()); 839 840 INSTANTIATE_TEST_CASE_P(KioskAutolaunchCancelTestInstantiation, 841 KioskAutolaunchCancelTest, 842 testing::Bool()); 843 844 INSTANTIATE_TEST_CASE_P(KioskAutolaunchConfirmTestInstantiation, 845 KioskAutolaunchConfirmTest, 846 testing::Bool()); 847 848 INSTANTIATE_TEST_CASE_P(KioskEnableCancelTestInstantiation, 849 KioskEnableCancelTest, 850 testing::Bool()); 851 852 INSTANTIATE_TEST_CASE_P(KioskEnableConfirmedTestInstantiation, 853 KioskEnableConfirmedTest, 854 testing::Bool()); 855 856 } // namespace chromeos 857