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