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