Home | History | Annotate | Download | only in login
      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