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