Home | History | Annotate | Download | only in app_mode
      1 // Copyright 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 "chrome/browser/chromeos/app_mode/kiosk_app_manager.h"
      6 
      7 #include "base/command_line.h"
      8 #include "base/files/file_util.h"
      9 #include "base/files/scoped_temp_dir.h"
     10 #include "base/message_loop/message_loop.h"
     11 #include "base/path_service.h"
     12 #include "base/prefs/scoped_user_pref_update.h"
     13 #include "base/strings/stringprintf.h"
     14 #include "base/values.h"
     15 #include "chrome/browser/browser_process.h"
     16 #include "chrome/browser/chromeos/app_mode/fake_cws.h"
     17 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h"
     18 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
     19 #include "chrome/browser/chromeos/policy/device_local_account.h"
     20 #include "chrome/browser/chromeos/settings/cros_settings.h"
     21 #include "chrome/browser/ui/browser.h"
     22 #include "chrome/common/chrome_paths.h"
     23 #include "chrome/common/chrome_switches.h"
     24 #include "chrome/test/base/in_process_browser_test.h"
     25 #include "chromeos/settings/cros_settings_names.h"
     26 #include "content/public/test/test_utils.h"
     27 #include "extensions/common/extension.h"
     28 #include "net/base/host_port_pair.h"
     29 #include "net/dns/mock_host_resolver.h"
     30 #include "net/test/embedded_test_server/embedded_test_server.h"
     31 
     32 using content::BrowserThread;
     33 
     34 namespace chromeos {
     35 
     36 namespace {
     37 
     38 // An app to test local fs data persistence across app update. V1 app writes
     39 // data into local fs. V2 app reads and verifies the data.
     40 // Webstore data json is in
     41 //   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/
     42 //       detail/bmbpicmpniaclbbpdkfglgipkkebnbjf
     43 // The version 1.0.0 installed is in
     44 //   chrome/test/data/chromeos/app_mode/webstore/downloads/
     45 //       bmbpicmpniaclbbpdkfglgipkkebnbjf.crx
     46 // The version 2.0.0 crx is in
     47 //   chrome/test/data/chromeos/app_mode/webstore/downloads/
     48 //       bmbpicmpniaclbbpdkfglgipkkebnbjf_v2_read_and_verify_data.crx
     49 const char kTestLocalFsKioskApp[] = "bmbpicmpniaclbbpdkfglgipkkebnbjf";
     50 const char kTestLocalFsKioskAppName[] = "Kiosk App With Local Data";
     51 
     52 // Helper KioskAppManager::GetConsumerKioskAutoLaunchStatusCallback
     53 // implementation.
     54 void ConsumerKioskAutoLaunchStatusCheck(
     55     KioskAppManager::ConsumerKioskAutoLaunchStatus* out_status,
     56     const base::Closure& runner_quit_task,
     57     KioskAppManager::ConsumerKioskAutoLaunchStatus in_status) {
     58   LOG(INFO) << "ConsumerKioskAutoLaunchStatus = " << in_status;
     59   *out_status = in_status;
     60   runner_quit_task.Run();
     61 }
     62 
     63 // Helper KioskAppManager::EnableKioskModeCallback implementation.
     64 void ConsumerKioskModeLockCheck(
     65     bool* out_locked,
     66     const base::Closure& runner_quit_task,
     67     bool in_locked) {
     68   LOG(INFO) << "kiosk locked  = " << in_locked;
     69   *out_locked = in_locked;
     70   runner_quit_task.Run();
     71 }
     72 
     73 // Helper EnterpriseInstallAttributes::LockResultCallback implementation.
     74 void OnEnterpriseDeviceLock(
     75     policy::EnterpriseInstallAttributes::LockResult* out_locked,
     76     const base::Closure& runner_quit_task,
     77     policy::EnterpriseInstallAttributes::LockResult in_locked) {
     78   LOG(INFO) << "Enterprise lock  = " << in_locked;
     79   *out_locked = in_locked;
     80   runner_quit_task.Run();
     81 }
     82 
     83 scoped_refptr<extensions::Extension> MakeApp(const std::string& name,
     84                                              const std::string& version,
     85                                              const std::string& url,
     86                                              const std::string& id) {
     87   std::string err;
     88   base::DictionaryValue value;
     89   value.SetString("name", name);
     90   value.SetString("version", version);
     91   value.SetString("app.launch.web_url", url);
     92   scoped_refptr<extensions::Extension> app =
     93       extensions::Extension::Create(
     94           base::FilePath(),
     95           extensions::Manifest::INTERNAL,
     96           value,
     97           extensions::Extension::WAS_INSTALLED_BY_DEFAULT,
     98           id,
     99           &err);
    100   EXPECT_EQ(err, "");
    101   return app;
    102 }
    103 
    104 class AppDataLoadWaiter : public KioskAppManagerObserver {
    105  public:
    106   AppDataLoadWaiter(KioskAppManager* manager, int data_loaded_threshold)
    107       : runner_(NULL),
    108         manager_(manager),
    109         loaded_(false),
    110         quit_(false),
    111         data_change_count_(0),
    112         data_loaded_threshold_(data_loaded_threshold) {
    113     manager_->AddObserver(this);
    114   }
    115 
    116   virtual ~AppDataLoadWaiter() { manager_->RemoveObserver(this); }
    117 
    118   void Wait() {
    119     if (quit_)
    120       return;
    121     runner_ = new content::MessageLoopRunner;
    122     runner_->Run();
    123   }
    124 
    125   bool loaded() const { return loaded_; }
    126 
    127  private:
    128   // KioskAppManagerObserver overrides:
    129   virtual void OnKioskAppDataChanged(const std::string& app_id) OVERRIDE {
    130     ++data_change_count_;
    131     if (data_change_count_ < data_loaded_threshold_)
    132       return;
    133     loaded_ = true;
    134     quit_ = true;
    135     if (runner_.get())
    136       runner_->Quit();
    137   }
    138 
    139   virtual void OnKioskAppDataLoadFailure(const std::string& app_id) OVERRIDE {
    140     loaded_ = false;
    141     quit_ = true;
    142     if (runner_.get())
    143       runner_->Quit();
    144   }
    145 
    146   virtual void OnKioskExtensionLoadedInCache(
    147       const std::string& app_id) OVERRIDE {
    148     OnKioskAppDataChanged(app_id);
    149   }
    150 
    151   virtual void OnKioskExtensionDownloadFailed(
    152       const std::string& app_id) OVERRIDE {
    153     OnKioskAppDataLoadFailure(app_id);
    154   }
    155 
    156   scoped_refptr<content::MessageLoopRunner> runner_;
    157   KioskAppManager* manager_;
    158   bool loaded_;
    159   bool quit_;
    160   int data_change_count_;
    161   int data_loaded_threshold_;
    162 
    163   DISALLOW_COPY_AND_ASSIGN(AppDataLoadWaiter);
    164 };
    165 
    166 }  // namespace
    167 
    168 class KioskAppManagerTest : public InProcessBrowserTest {
    169  public:
    170   KioskAppManagerTest() : fake_cws_(new FakeCWS()) {}
    171   virtual ~KioskAppManagerTest() {}
    172 
    173   // InProcessBrowserTest overrides:
    174   virtual void SetUp() OVERRIDE {
    175     base::FilePath test_data_dir;
    176     PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
    177     embedded_test_server()->ServeFilesFromDirectory(test_data_dir);
    178     ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady());
    179     // Stop IO thread here because no threads are allowed while
    180     // spawning sandbox host process. See crbug.com/322732.
    181     embedded_test_server()->StopThread();
    182 
    183     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    184 
    185     InProcessBrowserTest::SetUp();
    186   }
    187 
    188   virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE {
    189     InProcessBrowserTest::SetUpCommandLine(command_line);
    190 
    191     // Initialize fake_cws_ to setup web store gallery.
    192     fake_cws_->Init(embedded_test_server());
    193   }
    194 
    195   virtual void SetUpOnMainThread() OVERRIDE {
    196     InProcessBrowserTest::SetUpOnMainThread();
    197 
    198     // Restart the thread as the sandbox host process has already been spawned.
    199     embedded_test_server()->RestartThreadAndListen();
    200   }
    201 
    202   virtual void SetUpInProcessBrowserTestFixture() OVERRIDE {
    203     InProcessBrowserTest::SetUpInProcessBrowserTestFixture();
    204 
    205     host_resolver()->AddRule("*", "127.0.0.1");
    206   }
    207 
    208   std::string GetAppIds() const {
    209     KioskAppManager::Apps apps;
    210     manager()->GetApps(&apps);
    211 
    212     std::string str;
    213     for (size_t i = 0; i < apps.size(); ++i) {
    214       if (i > 0)
    215         str += ',';
    216       str += apps[i].app_id;
    217     }
    218 
    219     return str;
    220   }
    221 
    222   // Locks device for enterprise.
    223   policy::EnterpriseInstallAttributes::LockResult LockDeviceForEnterprise() {
    224     scoped_ptr<policy::EnterpriseInstallAttributes::LockResult> lock_result(
    225         new policy::EnterpriseInstallAttributes::LockResult(
    226             policy::EnterpriseInstallAttributes::LOCK_NOT_READY));
    227     scoped_refptr<content::MessageLoopRunner> runner =
    228         new content::MessageLoopRunner;
    229     policy::BrowserPolicyConnectorChromeOS* connector =
    230         g_browser_process->platform_part()->browser_policy_connector_chromeos();
    231     connector->GetInstallAttributes()->LockDevice(
    232         "user (at) domain.com",
    233         policy::DEVICE_MODE_ENTERPRISE,
    234         "device-id",
    235         base::Bind(
    236             &OnEnterpriseDeviceLock, lock_result.get(), runner->QuitClosure()));
    237     runner->Run();
    238     return *lock_result.get();
    239   }
    240 
    241   void SetExistingApp(const std::string& app_id,
    242                       const std::string& app_name,
    243                       const std::string& icon_file_name) {
    244     base::FilePath test_dir;
    245     ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir));
    246     base::FilePath data_dir = test_dir.AppendASCII("chromeos/app_mode/");
    247 
    248     // Copy the icon file to temp dir for using because ClearAppData test
    249     // deletes it.
    250     base::FilePath icon_path = temp_dir_.path().AppendASCII(icon_file_name);
    251     base::CopyFile(data_dir.AppendASCII(icon_file_name), icon_path);
    252 
    253     scoped_ptr<base::DictionaryValue> apps_dict(new base::DictionaryValue);
    254     apps_dict->SetString(app_id + ".name", app_name);
    255     apps_dict->SetString(app_id + ".icon", icon_path.MaybeAsASCII());
    256 
    257     PrefService* local_state = g_browser_process->local_state();
    258     DictionaryPrefUpdate dict_update(local_state,
    259                                      KioskAppManager::kKioskDictionaryName);
    260     dict_update->Set(KioskAppManager::kKeyApps, apps_dict.release());
    261 
    262     // Make the app appear in device settings.
    263     base::ListValue device_local_accounts;
    264     scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue);
    265     entry->SetStringWithoutPathExpansion(
    266         kAccountsPrefDeviceLocalAccountsKeyId,
    267         app_id + "_id");
    268     entry->SetIntegerWithoutPathExpansion(
    269         kAccountsPrefDeviceLocalAccountsKeyType,
    270         policy::DeviceLocalAccount::TYPE_KIOSK_APP);
    271     entry->SetStringWithoutPathExpansion(
    272         kAccountsPrefDeviceLocalAccountsKeyKioskAppId,
    273         app_id);
    274     device_local_accounts.Append(entry.release());
    275     CrosSettings::Get()->Set(kAccountsPrefDeviceLocalAccounts,
    276                              device_local_accounts);
    277   }
    278 
    279   bool GetCachedCrx(const std::string& app_id,
    280                     base::FilePath* file_path,
    281                     std::string* version) {
    282     return manager()->GetCachedCrx(app_id, file_path, version);
    283   }
    284 
    285   void UpdateAppData() { manager()->UpdateAppData(); }
    286 
    287   void RunAddNewAppTest(const std::string& id,
    288                         const std::string& version,
    289                         const std::string& app_name) {
    290     std::string crx_file_name = id + ".crx";
    291     fake_cws_->SetUpdateCrx(id, crx_file_name, version);
    292 
    293     AppDataLoadWaiter waiter(manager(), 3);
    294     manager()->AddApp(id);
    295     waiter.Wait();
    296     EXPECT_TRUE(waiter.loaded());
    297 
    298     // Check CRX file is cached.
    299     base::FilePath crx_path;
    300     std::string crx_version;
    301     EXPECT_TRUE(GetCachedCrx(id, &crx_path, &crx_version));
    302     EXPECT_TRUE(base::PathExists(crx_path));
    303     EXPECT_EQ(version, crx_version);
    304     // Verify the original crx file is identical to the cached file.
    305     base::FilePath test_data_dir;
    306     PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
    307     std::string src_file_path_str =
    308         std::string("chromeos/app_mode/webstore/downloads/") + crx_file_name;
    309     base::FilePath src_file_path = test_data_dir.Append(src_file_path_str);
    310     EXPECT_TRUE(base::PathExists(src_file_path));
    311     EXPECT_TRUE(base::ContentsEqual(src_file_path, crx_path));
    312 
    313     // Check manifest data is cached correctly.
    314     KioskAppManager::Apps apps;
    315     manager()->GetApps(&apps);
    316     ASSERT_EQ(1u, apps.size());
    317     EXPECT_EQ(id, apps[0].app_id);
    318     EXPECT_EQ(app_name, apps[0].name);
    319     EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size());
    320 
    321     // Check data is cached in local state.
    322     PrefService* local_state = g_browser_process->local_state();
    323     const base::DictionaryValue* dict =
    324         local_state->GetDictionary(KioskAppManager::kKioskDictionaryName);
    325 
    326     std::string name;
    327     std::string name_key = "apps." + id + ".name";
    328     EXPECT_TRUE(dict->GetString(name_key, &name));
    329     EXPECT_EQ(apps[0].name, name);
    330 
    331     std::string icon_path_string;
    332     std::string icon_path_key = "apps." + id + ".icon";
    333     EXPECT_TRUE(dict->GetString(icon_path_key, &icon_path_string));
    334 
    335     base::FilePath expected_icon_path;
    336     ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &expected_icon_path));
    337     expected_icon_path =
    338         expected_icon_path.AppendASCII(KioskAppManager::kIconCacheDir)
    339             .AppendASCII(apps[0].app_id)
    340             .AddExtension(".png");
    341     EXPECT_EQ(expected_icon_path.value(), icon_path_string);
    342   }
    343 
    344   KioskAppManager* manager() const { return KioskAppManager::Get(); }
    345   FakeCWS* fake_cws() { return fake_cws_.get(); }
    346 
    347  private:
    348   base::ScopedTempDir temp_dir_;
    349   scoped_ptr<FakeCWS> fake_cws_;
    350 
    351   DISALLOW_COPY_AND_ASSIGN(KioskAppManagerTest);
    352 };
    353 
    354 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, Basic) {
    355   // Add a couple of apps. Use "fake_app_x" that do not have data on the test
    356   // server to avoid pending data loads that could be lingering on tear down and
    357   // cause DCHECK failure in utility_process_host_impl.cc.
    358   manager()->AddApp("fake_app_1");
    359   manager()->AddApp("fake_app_2");
    360   EXPECT_EQ("fake_app_1,fake_app_2", GetAppIds());
    361 
    362   // Set an auto launch app.
    363   manager()->SetAutoLaunchApp("fake_app_1");
    364   EXPECT_EQ("fake_app_1", manager()->GetAutoLaunchApp());
    365 
    366   // Clear the auto launch app.
    367   manager()->SetAutoLaunchApp("");
    368   EXPECT_EQ("", manager()->GetAutoLaunchApp());
    369   EXPECT_FALSE(manager()->IsAutoLaunchEnabled());
    370 
    371   // Set another auto launch app.
    372   manager()->SetAutoLaunchApp("fake_app_2");
    373   EXPECT_EQ("fake_app_2", manager()->GetAutoLaunchApp());
    374 
    375   // Check auto launch permissions.
    376   EXPECT_FALSE(manager()->IsAutoLaunchEnabled());
    377   manager()->SetEnableAutoLaunch(true);
    378   EXPECT_TRUE(manager()->IsAutoLaunchEnabled());
    379 
    380   // Remove the auto launch app.
    381   manager()->RemoveApp("fake_app_2");
    382   EXPECT_EQ("fake_app_1", GetAppIds());
    383   EXPECT_EQ("", manager()->GetAutoLaunchApp());
    384 
    385   // Add the just removed auto launch app again and it should no longer be
    386   // the auto launch app.
    387   manager()->AddApp("fake_app_2");
    388   EXPECT_EQ("", manager()->GetAutoLaunchApp());
    389   manager()->RemoveApp("fake_app_2");
    390   EXPECT_EQ("fake_app_1", GetAppIds());
    391 
    392   // Set a none exist app as auto launch.
    393   manager()->SetAutoLaunchApp("none_exist_app");
    394   EXPECT_EQ("", manager()->GetAutoLaunchApp());
    395   EXPECT_FALSE(manager()->IsAutoLaunchEnabled());
    396 
    397   // Add an existing app again.
    398   manager()->AddApp("fake_app_1");
    399   EXPECT_EQ("fake_app_1", GetAppIds());
    400 }
    401 
    402 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, LoadCached) {
    403   SetExistingApp("app_1", "Cached App1 Name", "red16x16.png");
    404 
    405   fake_cws()->SetNoUpdate("app_1");
    406   AppDataLoadWaiter waiter(manager(), 1);
    407   waiter.Wait();
    408   EXPECT_TRUE(waiter.loaded());
    409 
    410   KioskAppManager::Apps apps;
    411   manager()->GetApps(&apps);
    412   EXPECT_EQ(1u, apps.size());
    413   EXPECT_EQ("app_1", apps[0].app_id);
    414   EXPECT_EQ("Cached App1 Name", apps[0].name);
    415   EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size());
    416 }
    417 
    418 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, ClearAppData) {
    419   SetExistingApp("app_1", "Cached App1 Name", "red16x16.png");
    420 
    421   PrefService* local_state = g_browser_process->local_state();
    422   const base::DictionaryValue* dict =
    423       local_state->GetDictionary(KioskAppManager::kKioskDictionaryName);
    424   const base::DictionaryValue* apps_dict;
    425   EXPECT_TRUE(dict->GetDictionary(KioskAppManager::kKeyApps, &apps_dict));
    426   EXPECT_TRUE(apps_dict->HasKey("app_1"));
    427 
    428   manager()->ClearAppData("app_1");
    429 
    430   EXPECT_FALSE(apps_dict->HasKey("app_1"));
    431 }
    432 
    433 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateAppDataFromProfile) {
    434   SetExistingApp("app_1", "Cached App1 Name", "red16x16.png");
    435 
    436   fake_cws()->SetNoUpdate("app_1");
    437   AppDataLoadWaiter waiter(manager(), 1);
    438   waiter.Wait();
    439   EXPECT_TRUE(waiter.loaded());
    440 
    441   KioskAppManager::Apps apps;
    442   manager()->GetApps(&apps);
    443   EXPECT_EQ(1u, apps.size());
    444   EXPECT_EQ("app_1", apps[0].app_id);
    445   EXPECT_EQ("Cached App1 Name", apps[0].name);
    446 
    447   scoped_refptr<extensions::Extension> updated_app =
    448       MakeApp("Updated App1 Name", "2.0", "http://localhost/", "app_1");
    449   manager()->UpdateAppDataFromProfile(
    450       "app_1", browser()->profile(), updated_app.get());
    451 
    452   waiter.Wait();
    453   EXPECT_TRUE(waiter.loaded());
    454 
    455   manager()->GetApps(&apps);
    456   EXPECT_EQ(1u, apps.size());
    457   EXPECT_EQ("app_1", apps[0].app_id);
    458   EXPECT_EQ("Updated App1 Name", apps[0].name);
    459 }
    460 
    461 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, BadApp) {
    462   AppDataLoadWaiter waiter(manager(), 2);
    463   manager()->AddApp("unknown_app");
    464   waiter.Wait();
    465   EXPECT_FALSE(waiter.loaded());
    466   EXPECT_EQ("", GetAppIds());
    467 }
    468 
    469 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, GoodApp) {
    470   // Webstore data json is in
    471   //   chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_1
    472   fake_cws()->SetNoUpdate("app_1");
    473   AppDataLoadWaiter waiter(manager(), 2);
    474   manager()->AddApp("app_1");
    475   waiter.Wait();
    476   EXPECT_TRUE(waiter.loaded());
    477 
    478   // Check data is correct.
    479   KioskAppManager::Apps apps;
    480   manager()->GetApps(&apps);
    481   ASSERT_EQ(1u, apps.size());
    482   EXPECT_EQ("app_1", apps[0].app_id);
    483   EXPECT_EQ("Name of App 1", apps[0].name);
    484   EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size());
    485 
    486   // Check data is cached in local state.
    487   PrefService* local_state = g_browser_process->local_state();
    488   const base::DictionaryValue* dict =
    489       local_state->GetDictionary(KioskAppManager::kKioskDictionaryName);
    490 
    491   std::string name;
    492   EXPECT_TRUE(dict->GetString("apps.app_1.name", &name));
    493   EXPECT_EQ(apps[0].name, name);
    494 
    495   std::string icon_path_string;
    496   EXPECT_TRUE(dict->GetString("apps.app_1.icon", &icon_path_string));
    497 
    498   base::FilePath expected_icon_path;
    499   ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &expected_icon_path));
    500   expected_icon_path = expected_icon_path.
    501       AppendASCII(KioskAppManager::kIconCacheDir).
    502       AppendASCII(apps[0].app_id).AddExtension(".png");
    503   EXPECT_EQ(expected_icon_path.value(), icon_path_string);
    504 }
    505 
    506 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, DownloadNewApp) {
    507   RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName);
    508 }
    509 
    510 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, RemoveApp) {
    511   // Add a new app.
    512   RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName);
    513   KioskAppManager::Apps apps;
    514   manager()->GetApps(&apps);
    515   ASSERT_EQ(1u, apps.size());
    516   base::FilePath crx_path;
    517   std::string version;
    518   EXPECT_TRUE(GetCachedCrx(kTestLocalFsKioskApp, &crx_path, &version));
    519   EXPECT_TRUE(base::PathExists(crx_path));
    520   EXPECT_EQ("1.0.0", version);
    521 
    522   // Remove the app now.
    523   manager()->RemoveApp(kTestLocalFsKioskApp);
    524   content::RunAllBlockingPoolTasksUntilIdle();
    525   manager()->GetApps(&apps);
    526   ASSERT_EQ(0u, apps.size());
    527   EXPECT_FALSE(base::PathExists(crx_path));
    528   EXPECT_FALSE(GetCachedCrx(kTestLocalFsKioskApp, &crx_path, &version));
    529 }
    530 
    531 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateApp) {
    532   // Add a version 1 app first.
    533   RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName);
    534   KioskAppManager::Apps apps;
    535   manager()->GetApps(&apps);
    536   ASSERT_EQ(1u, apps.size());
    537   base::FilePath crx_path;
    538   std::string version;
    539   EXPECT_TRUE(GetCachedCrx(kTestLocalFsKioskApp, &crx_path, &version));
    540   EXPECT_TRUE(base::PathExists(crx_path));
    541   EXPECT_EQ("1.0.0", version);
    542 
    543   // Update to version 2.
    544   fake_cws()->SetUpdateCrx(
    545       kTestLocalFsKioskApp,
    546       "bmbpicmpniaclbbpdkfglgipkkebnbjf_v2_read_and_verify_data.crx",
    547       "2.0.0");
    548   AppDataLoadWaiter waiter(manager(), 1);
    549   UpdateAppData();
    550   waiter.Wait();
    551   EXPECT_TRUE(waiter.loaded());
    552 
    553   // Verify the app has been updated to v2.
    554   manager()->GetApps(&apps);
    555   ASSERT_EQ(1u, apps.size());
    556   base::FilePath new_crx_path;
    557   std::string new_version;
    558   EXPECT_TRUE(GetCachedCrx(kTestLocalFsKioskApp, &new_crx_path, &new_version));
    559   EXPECT_EQ("2.0.0", new_version);
    560   EXPECT_TRUE(base::PathExists(new_crx_path));
    561   // Get original version 2 source download crx file path.
    562   base::FilePath test_data_dir;
    563   PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
    564   base::FilePath v2_file_path = test_data_dir.Append(FILE_PATH_LITERAL(
    565       "chromeos/app_mode/webstore/downloads/"
    566       "bmbpicmpniaclbbpdkfglgipkkebnbjf_v2_read_and_verify_data.crx"));
    567   EXPECT_TRUE(base::PathExists(v2_file_path));
    568   EXPECT_TRUE(base::ContentsEqual(v2_file_path, new_crx_path));
    569 }
    570 
    571 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateAndRemoveApp) {
    572   // Add a version 1 app first.
    573   RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName);
    574   KioskAppManager::Apps apps;
    575   manager()->GetApps(&apps);
    576   ASSERT_EQ(1u, apps.size());
    577   base::FilePath v1_crx_path;
    578   std::string version;
    579   EXPECT_TRUE(GetCachedCrx(kTestLocalFsKioskApp, &v1_crx_path, &version));
    580   EXPECT_TRUE(base::PathExists(v1_crx_path));
    581   EXPECT_EQ("1.0.0", version);
    582 
    583   // Update to version 2.
    584   fake_cws()->SetUpdateCrx(
    585       kTestLocalFsKioskApp,
    586       "bmbpicmpniaclbbpdkfglgipkkebnbjf_v2_read_and_verify_data.crx",
    587       "2.0.0");
    588   AppDataLoadWaiter waiter(manager(), 1);
    589   UpdateAppData();
    590   waiter.Wait();
    591   EXPECT_TRUE(waiter.loaded());
    592 
    593   // Verify the app has been updated to v2.
    594   manager()->GetApps(&apps);
    595   ASSERT_EQ(1u, apps.size());
    596   base::FilePath v2_crx_path;
    597   std::string new_version;
    598   EXPECT_TRUE(GetCachedCrx(kTestLocalFsKioskApp, &v2_crx_path, &new_version));
    599   EXPECT_EQ("2.0.0", new_version);
    600   // Verify both v1 and v2 crx files exist.
    601   EXPECT_TRUE(base::PathExists(v1_crx_path));
    602   EXPECT_TRUE(base::PathExists(v2_crx_path));
    603 
    604   // Remove the app now.
    605   manager()->RemoveApp(kTestLocalFsKioskApp);
    606   content::RunAllBlockingPoolTasksUntilIdle();
    607   manager()->GetApps(&apps);
    608   ASSERT_EQ(0u, apps.size());
    609   // Verify both v1 and v2 crx files are removed.
    610   EXPECT_FALSE(base::PathExists(v1_crx_path));
    611   EXPECT_FALSE(base::PathExists(v2_crx_path));
    612   EXPECT_FALSE(GetCachedCrx(kTestLocalFsKioskApp, &v2_crx_path, &version));
    613 }
    614 
    615 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, EnableConsumerKiosk) {
    616   scoped_ptr<KioskAppManager::ConsumerKioskAutoLaunchStatus> status(
    617       new KioskAppManager::ConsumerKioskAutoLaunchStatus(
    618           KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED));
    619   scoped_ptr<bool> locked(new bool(false));
    620 
    621   scoped_refptr<content::MessageLoopRunner> runner =
    622       new content::MessageLoopRunner;
    623   manager()->GetConsumerKioskAutoLaunchStatus(
    624       base::Bind(&ConsumerKioskAutoLaunchStatusCheck,
    625                  status.get(),
    626                  runner->QuitClosure()));
    627   runner->Run();
    628   EXPECT_EQ(*status.get(),
    629             KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE);
    630 
    631   scoped_refptr<content::MessageLoopRunner> runner2 =
    632       new content::MessageLoopRunner;
    633   manager()->EnableConsumerKioskAutoLaunch(
    634       base::Bind(&ConsumerKioskModeLockCheck,
    635                  locked.get(),
    636                  runner2->QuitClosure()));
    637   runner2->Run();
    638   EXPECT_TRUE(*locked.get());
    639 
    640   scoped_refptr<content::MessageLoopRunner> runner3 =
    641       new content::MessageLoopRunner;
    642   manager()->GetConsumerKioskAutoLaunchStatus(
    643       base::Bind(&ConsumerKioskAutoLaunchStatusCheck,
    644                  status.get(),
    645                  runner3->QuitClosure()));
    646   runner3->Run();
    647   EXPECT_EQ(*status.get(),
    648             KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_ENABLED);
    649 }
    650 
    651 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest,
    652                        PreventEnableConsumerKioskForEnterprise) {
    653   // First, lock the device as enterprise.
    654   EXPECT_EQ(LockDeviceForEnterprise(),
    655             policy::EnterpriseInstallAttributes::LOCK_SUCCESS);
    656 
    657   scoped_ptr<KioskAppManager::ConsumerKioskAutoLaunchStatus> status(
    658       new KioskAppManager::ConsumerKioskAutoLaunchStatus(
    659           KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED));
    660   scoped_ptr<bool> locked(new bool(true));
    661 
    662   scoped_refptr<content::MessageLoopRunner> runner =
    663       new content::MessageLoopRunner;
    664   manager()->GetConsumerKioskAutoLaunchStatus(
    665       base::Bind(&ConsumerKioskAutoLaunchStatusCheck,
    666                  status.get(),
    667                  runner->QuitClosure()));
    668   runner->Run();
    669   EXPECT_EQ(*status.get(),
    670             KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED);
    671 
    672   scoped_refptr<content::MessageLoopRunner> runner2 =
    673       new content::MessageLoopRunner;
    674   manager()->EnableConsumerKioskAutoLaunch(
    675       base::Bind(&ConsumerKioskModeLockCheck,
    676                  locked.get(),
    677                  runner2->QuitClosure()));
    678   runner2->Run();
    679   EXPECT_FALSE(*locked.get());
    680 
    681   scoped_refptr<content::MessageLoopRunner> runner3 =
    682       new content::MessageLoopRunner;
    683   manager()->GetConsumerKioskAutoLaunchStatus(
    684       base::Bind(&ConsumerKioskAutoLaunchStatusCheck,
    685                  status.get(),
    686                  runner3->QuitClosure()));
    687   runner3->Run();
    688   EXPECT_EQ(*status.get(),
    689             KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED);
    690 }
    691 
    692 }  // namespace chromeos
    693