// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" #include "base/command_line.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" #include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" #include "base/path_service.h" #include "base/prefs/scoped_user_pref_update.h" #include "base/strings/stringprintf.h" #include "base/values.h" #include "chrome/browser/browser_process.h" #include "chrome/browser/chromeos/app_mode/fake_cws.h" #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h" #include "chrome/browser/chromeos/ownership/fake_owner_settings_service.h" #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" #include "chrome/browser/chromeos/policy/device_local_account.h" #include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h" #include "chrome/browser/ui/browser.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/test/base/in_process_browser_test.h" #include "chromeos/settings/cros_settings_names.h" #include "content/public/test/test_utils.h" #include "extensions/common/extension.h" #include "net/base/host_port_pair.h" #include "net/dns/mock_host_resolver.h" #include "net/test/embedded_test_server/embedded_test_server.h" using content::BrowserThread; namespace chromeos { namespace { // An app to test local fs data persistence across app update. V1 app writes // data into local fs. V2 app reads and verifies the data. // Webstore data json is in // chrome/test/data/chromeos/app_mode/webstore/inlineinstall/ // detail/bmbpicmpniaclbbpdkfglgipkkebnbjf // The version 1.0.0 installed is in // chrome/test/data/chromeos/app_mode/webstore/downloads/ // bmbpicmpniaclbbpdkfglgipkkebnbjf.crx // The version 2.0.0 crx is in // chrome/test/data/chromeos/app_mode/webstore/downloads/ // bmbpicmpniaclbbpdkfglgipkkebnbjf_v2_read_and_verify_data.crx const char kTestLocalFsKioskApp[] = "bmbpicmpniaclbbpdkfglgipkkebnbjf"; const char kTestLocalFsKioskAppName[] = "Kiosk App With Local Data"; // Helper KioskAppManager::GetConsumerKioskAutoLaunchStatusCallback // implementation. void ConsumerKioskAutoLaunchStatusCheck( KioskAppManager::ConsumerKioskAutoLaunchStatus* out_status, const base::Closure& runner_quit_task, KioskAppManager::ConsumerKioskAutoLaunchStatus in_status) { LOG(INFO) << "ConsumerKioskAutoLaunchStatus = " << in_status; *out_status = in_status; runner_quit_task.Run(); } // Helper KioskAppManager::EnableKioskModeCallback implementation. void ConsumerKioskModeLockCheck( bool* out_locked, const base::Closure& runner_quit_task, bool in_locked) { LOG(INFO) << "kiosk locked = " << in_locked; *out_locked = in_locked; runner_quit_task.Run(); } // Helper EnterpriseInstallAttributes::LockResultCallback implementation. void OnEnterpriseDeviceLock( policy::EnterpriseInstallAttributes::LockResult* out_locked, const base::Closure& runner_quit_task, policy::EnterpriseInstallAttributes::LockResult in_locked) { LOG(INFO) << "Enterprise lock = " << in_locked; *out_locked = in_locked; runner_quit_task.Run(); } scoped_refptr MakeApp(const std::string& name, const std::string& version, const std::string& url, const std::string& id) { std::string err; base::DictionaryValue value; value.SetString("name", name); value.SetString("version", version); value.SetString("app.launch.web_url", url); scoped_refptr app = extensions::Extension::Create( base::FilePath(), extensions::Manifest::INTERNAL, value, extensions::Extension::WAS_INSTALLED_BY_DEFAULT, id, &err); EXPECT_EQ(err, ""); return app; } class AppDataLoadWaiter : public KioskAppManagerObserver { public: AppDataLoadWaiter(KioskAppManager* manager, int data_loaded_threshold) : runner_(NULL), manager_(manager), loaded_(false), quit_(false), data_change_count_(0), data_loaded_threshold_(data_loaded_threshold) { manager_->AddObserver(this); } ~AppDataLoadWaiter() override { manager_->RemoveObserver(this); } void Wait() { if (quit_) return; runner_ = new content::MessageLoopRunner; runner_->Run(); } bool loaded() const { return loaded_; } private: // KioskAppManagerObserver overrides: void OnKioskAppDataChanged(const std::string& app_id) override { ++data_change_count_; if (data_change_count_ < data_loaded_threshold_) return; loaded_ = true; quit_ = true; if (runner_.get()) runner_->Quit(); } void OnKioskAppDataLoadFailure(const std::string& app_id) override { loaded_ = false; quit_ = true; if (runner_.get()) runner_->Quit(); } void OnKioskExtensionLoadedInCache(const std::string& app_id) override { OnKioskAppDataChanged(app_id); } void OnKioskExtensionDownloadFailed(const std::string& app_id) override { OnKioskAppDataLoadFailure(app_id); } scoped_refptr runner_; KioskAppManager* manager_; bool loaded_; bool quit_; int data_change_count_; int data_loaded_threshold_; DISALLOW_COPY_AND_ASSIGN(AppDataLoadWaiter); }; } // namespace class KioskAppManagerTest : public InProcessBrowserTest { public: KioskAppManagerTest() : settings_helper_(false), fake_cws_(new FakeCWS()) {} ~KioskAppManagerTest() override {} // InProcessBrowserTest overrides: void SetUp() override { base::FilePath test_data_dir; PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); embedded_test_server()->ServeFilesFromDirectory(test_data_dir); ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); // Stop IO thread here because no threads are allowed while // spawning sandbox host process. See crbug.com/322732. embedded_test_server()->StopThread(); ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); InProcessBrowserTest::SetUp(); } void SetUpCommandLine(base::CommandLine* command_line) override { InProcessBrowserTest::SetUpCommandLine(command_line); // Initialize fake_cws_ to setup web store gallery. fake_cws_->Init(embedded_test_server()); } void SetUpOnMainThread() override { InProcessBrowserTest::SetUpOnMainThread(); // Restart the thread as the sandbox host process has already been spawned. embedded_test_server()->RestartThreadAndListen(); settings_helper_.ReplaceProvider(kAccountsPrefDeviceLocalAccounts); owner_settings_service_ = settings_helper_.CreateOwnerSettingsService(browser()->profile()); } void TearDownOnMainThread() override { settings_helper_.RestoreProvider(); } void SetUpInProcessBrowserTestFixture() override { InProcessBrowserTest::SetUpInProcessBrowserTestFixture(); host_resolver()->AddRule("*", "127.0.0.1"); } std::string GetAppIds() const { KioskAppManager::Apps apps; manager()->GetApps(&apps); std::string str; for (size_t i = 0; i < apps.size(); ++i) { if (i > 0) str += ','; str += apps[i].app_id; } return str; } // Locks device for enterprise. policy::EnterpriseInstallAttributes::LockResult LockDeviceForEnterprise() { scoped_ptr lock_result( new policy::EnterpriseInstallAttributes::LockResult( policy::EnterpriseInstallAttributes::LOCK_NOT_READY)); scoped_refptr runner = new content::MessageLoopRunner; policy::BrowserPolicyConnectorChromeOS* connector = g_browser_process->platform_part()->browser_policy_connector_chromeos(); connector->GetInstallAttributes()->LockDevice( "user@domain.com", policy::DEVICE_MODE_ENTERPRISE, "device-id", base::Bind( &OnEnterpriseDeviceLock, lock_result.get(), runner->QuitClosure())); runner->Run(); return *lock_result.get(); } void SetExistingApp(const std::string& app_id, const std::string& app_name, const std::string& icon_file_name) { base::FilePath test_dir; ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); base::FilePath data_dir = test_dir.AppendASCII("chromeos/app_mode/"); // Copy the icon file to temp dir for using because ClearAppData test // deletes it. base::FilePath icon_path = temp_dir_.path().AppendASCII(icon_file_name); base::CopyFile(data_dir.AppendASCII(icon_file_name), icon_path); scoped_ptr apps_dict(new base::DictionaryValue); apps_dict->SetString(app_id + ".name", app_name); apps_dict->SetString(app_id + ".icon", icon_path.MaybeAsASCII()); PrefService* local_state = g_browser_process->local_state(); DictionaryPrefUpdate dict_update(local_state, KioskAppManager::kKioskDictionaryName); dict_update->Set(KioskAppManager::kKeyApps, apps_dict.release()); // Make the app appear in device settings. base::ListValue device_local_accounts; scoped_ptr entry(new base::DictionaryValue); entry->SetStringWithoutPathExpansion( kAccountsPrefDeviceLocalAccountsKeyId, app_id + "_id"); entry->SetIntegerWithoutPathExpansion( kAccountsPrefDeviceLocalAccountsKeyType, policy::DeviceLocalAccount::TYPE_KIOSK_APP); entry->SetStringWithoutPathExpansion( kAccountsPrefDeviceLocalAccountsKeyKioskAppId, app_id); device_local_accounts.Append(entry.release()); owner_settings_service_->Set(kAccountsPrefDeviceLocalAccounts, device_local_accounts); } bool GetCachedCrx(const std::string& app_id, base::FilePath* file_path, std::string* version) { return manager()->GetCachedCrx(app_id, file_path, version); } void UpdateAppData() { manager()->UpdateAppData(); } void RunAddNewAppTest(const std::string& id, const std::string& version, const std::string& app_name) { std::string crx_file_name = id + ".crx"; fake_cws_->SetUpdateCrx(id, crx_file_name, version); AppDataLoadWaiter waiter(manager(), 3); manager()->AddApp(id, owner_settings_service_.get()); waiter.Wait(); EXPECT_TRUE(waiter.loaded()); // Check CRX file is cached. base::FilePath crx_path; std::string crx_version; EXPECT_TRUE(GetCachedCrx(id, &crx_path, &crx_version)); EXPECT_TRUE(base::PathExists(crx_path)); EXPECT_EQ(version, crx_version); // Verify the original crx file is identical to the cached file. base::FilePath test_data_dir; PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); std::string src_file_path_str = std::string("chromeos/app_mode/webstore/downloads/") + crx_file_name; base::FilePath src_file_path = test_data_dir.Append(src_file_path_str); EXPECT_TRUE(base::PathExists(src_file_path)); EXPECT_TRUE(base::ContentsEqual(src_file_path, crx_path)); // Check manifest data is cached correctly. KioskAppManager::Apps apps; manager()->GetApps(&apps); ASSERT_EQ(1u, apps.size()); EXPECT_EQ(id, apps[0].app_id); EXPECT_EQ(app_name, apps[0].name); EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size()); // Check data is cached in local state. PrefService* local_state = g_browser_process->local_state(); const base::DictionaryValue* dict = local_state->GetDictionary(KioskAppManager::kKioskDictionaryName); std::string name; std::string name_key = "apps." + id + ".name"; EXPECT_TRUE(dict->GetString(name_key, &name)); EXPECT_EQ(apps[0].name, name); std::string icon_path_string; std::string icon_path_key = "apps." + id + ".icon"; EXPECT_TRUE(dict->GetString(icon_path_key, &icon_path_string)); base::FilePath expected_icon_path; ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &expected_icon_path)); expected_icon_path = expected_icon_path.AppendASCII(KioskAppManager::kIconCacheDir) .AppendASCII(apps[0].app_id) .AddExtension(".png"); EXPECT_EQ(expected_icon_path.value(), icon_path_string); } KioskAppManager* manager() const { return KioskAppManager::Get(); } FakeCWS* fake_cws() { return fake_cws_.get(); } protected: ScopedCrosSettingsTestHelper settings_helper_; scoped_ptr owner_settings_service_; private: base::ScopedTempDir temp_dir_; scoped_ptr fake_cws_; DISALLOW_COPY_AND_ASSIGN(KioskAppManagerTest); }; IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, Basic) { // Add a couple of apps. Use "fake_app_x" that do not have data on the test // server to avoid pending data loads that could be lingering on tear down and // cause DCHECK failure in utility_process_host_impl.cc. manager()->AddApp("fake_app_1", owner_settings_service_.get()); manager()->AddApp("fake_app_2", owner_settings_service_.get()); EXPECT_EQ("fake_app_1,fake_app_2", GetAppIds()); // Set an auto launch app. manager()->SetAutoLaunchApp("fake_app_1", owner_settings_service_.get()); EXPECT_EQ("fake_app_1", manager()->GetAutoLaunchApp()); // Make sure that if an app was auto launched with zero delay, it is reflected // in the app data. KioskAppManager::App app; manager()->GetApp("fake_app_1", &app); EXPECT_FALSE(app.was_auto_launched_with_zero_delay); manager()->SetAppWasAutoLaunchedWithZeroDelay("fake_app_1"); manager()->GetApp("fake_app_1", &app); EXPECT_TRUE(app.was_auto_launched_with_zero_delay); // Clear the auto launch app. manager()->SetAutoLaunchApp("", owner_settings_service_.get()); EXPECT_EQ("", manager()->GetAutoLaunchApp()); EXPECT_FALSE(manager()->IsAutoLaunchEnabled()); // App should still report it was auto launched with zero delay, even though // it is no longer set to auto launch in the future. manager()->GetApp("fake_app_1", &app); EXPECT_TRUE(app.was_auto_launched_with_zero_delay); // Set another auto launch app. manager()->SetAutoLaunchApp("fake_app_2", owner_settings_service_.get()); EXPECT_EQ("fake_app_2", manager()->GetAutoLaunchApp()); // Check auto launch permissions. EXPECT_FALSE(manager()->IsAutoLaunchEnabled()); manager()->SetEnableAutoLaunch(true); EXPECT_TRUE(manager()->IsAutoLaunchEnabled()); // Remove the auto launch app. manager()->RemoveApp("fake_app_2", owner_settings_service_.get()); EXPECT_EQ("fake_app_1", GetAppIds()); EXPECT_EQ("", manager()->GetAutoLaunchApp()); // Add the just removed auto launch app again and it should no longer be // the auto launch app. manager()->AddApp("fake_app_2", owner_settings_service_.get()); EXPECT_EQ("", manager()->GetAutoLaunchApp()); manager()->RemoveApp("fake_app_2", owner_settings_service_.get()); EXPECT_EQ("fake_app_1", GetAppIds()); // Set a none exist app as auto launch. manager()->SetAutoLaunchApp("none_exist_app", owner_settings_service_.get()); EXPECT_EQ("", manager()->GetAutoLaunchApp()); EXPECT_FALSE(manager()->IsAutoLaunchEnabled()); // Add an existing app again. manager()->AddApp("fake_app_1", owner_settings_service_.get()); EXPECT_EQ("fake_app_1", GetAppIds()); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, LoadCached) { SetExistingApp("app_1", "Cached App1 Name", "red16x16.png"); fake_cws()->SetNoUpdate("app_1"); AppDataLoadWaiter waiter(manager(), 1); waiter.Wait(); EXPECT_TRUE(waiter.loaded()); KioskAppManager::Apps apps; manager()->GetApps(&apps); EXPECT_EQ(1u, apps.size()); EXPECT_EQ("app_1", apps[0].app_id); EXPECT_EQ("Cached App1 Name", apps[0].name); EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size()); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, ClearAppData) { SetExistingApp("app_1", "Cached App1 Name", "red16x16.png"); PrefService* local_state = g_browser_process->local_state(); const base::DictionaryValue* dict = local_state->GetDictionary(KioskAppManager::kKioskDictionaryName); const base::DictionaryValue* apps_dict; EXPECT_TRUE(dict->GetDictionary(KioskAppManager::kKeyApps, &apps_dict)); EXPECT_TRUE(apps_dict->HasKey("app_1")); manager()->ClearAppData("app_1"); EXPECT_FALSE(apps_dict->HasKey("app_1")); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateAppDataFromProfile) { SetExistingApp("app_1", "Cached App1 Name", "red16x16.png"); fake_cws()->SetNoUpdate("app_1"); AppDataLoadWaiter waiter(manager(), 1); waiter.Wait(); EXPECT_TRUE(waiter.loaded()); KioskAppManager::Apps apps; manager()->GetApps(&apps); EXPECT_EQ(1u, apps.size()); EXPECT_EQ("app_1", apps[0].app_id); EXPECT_EQ("Cached App1 Name", apps[0].name); scoped_refptr updated_app = MakeApp("Updated App1 Name", "2.0", "http://localhost/", "app_1"); manager()->UpdateAppDataFromProfile( "app_1", browser()->profile(), updated_app.get()); waiter.Wait(); EXPECT_TRUE(waiter.loaded()); manager()->GetApps(&apps); EXPECT_EQ(1u, apps.size()); EXPECT_EQ("app_1", apps[0].app_id); EXPECT_EQ("Updated App1 Name", apps[0].name); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, BadApp) { AppDataLoadWaiter waiter(manager(), 2); manager()->AddApp("unknown_app", owner_settings_service_.get()); waiter.Wait(); EXPECT_FALSE(waiter.loaded()); EXPECT_EQ("", GetAppIds()); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, GoodApp) { // Webstore data json is in // chrome/test/data/chromeos/app_mode/webstore/inlineinstall/detail/app_1 fake_cws()->SetNoUpdate("app_1"); AppDataLoadWaiter waiter(manager(), 2); manager()->AddApp("app_1", owner_settings_service_.get()); waiter.Wait(); EXPECT_TRUE(waiter.loaded()); // Check data is correct. KioskAppManager::Apps apps; manager()->GetApps(&apps); ASSERT_EQ(1u, apps.size()); EXPECT_EQ("app_1", apps[0].app_id); EXPECT_EQ("Name of App 1", apps[0].name); EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size()); // Check data is cached in local state. PrefService* local_state = g_browser_process->local_state(); const base::DictionaryValue* dict = local_state->GetDictionary(KioskAppManager::kKioskDictionaryName); std::string name; EXPECT_TRUE(dict->GetString("apps.app_1.name", &name)); EXPECT_EQ(apps[0].name, name); std::string icon_path_string; EXPECT_TRUE(dict->GetString("apps.app_1.icon", &icon_path_string)); base::FilePath expected_icon_path; ASSERT_TRUE(PathService::Get(chrome::DIR_USER_DATA, &expected_icon_path)); expected_icon_path = expected_icon_path. AppendASCII(KioskAppManager::kIconCacheDir). AppendASCII(apps[0].app_id).AddExtension(".png"); EXPECT_EQ(expected_icon_path.value(), icon_path_string); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, DownloadNewApp) { RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, RemoveApp) { // Add a new app. RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName); KioskAppManager::Apps apps; manager()->GetApps(&apps); ASSERT_EQ(1u, apps.size()); base::FilePath crx_path; std::string version; EXPECT_TRUE(GetCachedCrx(kTestLocalFsKioskApp, &crx_path, &version)); EXPECT_TRUE(base::PathExists(crx_path)); EXPECT_EQ("1.0.0", version); // Remove the app now. manager()->RemoveApp(kTestLocalFsKioskApp, owner_settings_service_.get()); content::RunAllBlockingPoolTasksUntilIdle(); manager()->GetApps(&apps); ASSERT_EQ(0u, apps.size()); EXPECT_FALSE(base::PathExists(crx_path)); EXPECT_FALSE(GetCachedCrx(kTestLocalFsKioskApp, &crx_path, &version)); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateApp) { // Add a version 1 app first. RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName); KioskAppManager::Apps apps; manager()->GetApps(&apps); ASSERT_EQ(1u, apps.size()); base::FilePath crx_path; std::string version; EXPECT_TRUE(GetCachedCrx(kTestLocalFsKioskApp, &crx_path, &version)); EXPECT_TRUE(base::PathExists(crx_path)); EXPECT_EQ("1.0.0", version); // Update to version 2. fake_cws()->SetUpdateCrx( kTestLocalFsKioskApp, "bmbpicmpniaclbbpdkfglgipkkebnbjf_v2_read_and_verify_data.crx", "2.0.0"); AppDataLoadWaiter waiter(manager(), 1); UpdateAppData(); waiter.Wait(); EXPECT_TRUE(waiter.loaded()); // Verify the app has been updated to v2. manager()->GetApps(&apps); ASSERT_EQ(1u, apps.size()); base::FilePath new_crx_path; std::string new_version; EXPECT_TRUE(GetCachedCrx(kTestLocalFsKioskApp, &new_crx_path, &new_version)); EXPECT_EQ("2.0.0", new_version); EXPECT_TRUE(base::PathExists(new_crx_path)); // Get original version 2 source download crx file path. base::FilePath test_data_dir; PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); base::FilePath v2_file_path = test_data_dir.Append(FILE_PATH_LITERAL( "chromeos/app_mode/webstore/downloads/" "bmbpicmpniaclbbpdkfglgipkkebnbjf_v2_read_and_verify_data.crx")); EXPECT_TRUE(base::PathExists(v2_file_path)); EXPECT_TRUE(base::ContentsEqual(v2_file_path, new_crx_path)); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateAndRemoveApp) { // Add a version 1 app first. RunAddNewAppTest(kTestLocalFsKioskApp, "1.0.0", kTestLocalFsKioskAppName); KioskAppManager::Apps apps; manager()->GetApps(&apps); ASSERT_EQ(1u, apps.size()); base::FilePath v1_crx_path; std::string version; EXPECT_TRUE(GetCachedCrx(kTestLocalFsKioskApp, &v1_crx_path, &version)); EXPECT_TRUE(base::PathExists(v1_crx_path)); EXPECT_EQ("1.0.0", version); // Update to version 2. fake_cws()->SetUpdateCrx( kTestLocalFsKioskApp, "bmbpicmpniaclbbpdkfglgipkkebnbjf_v2_read_and_verify_data.crx", "2.0.0"); AppDataLoadWaiter waiter(manager(), 1); UpdateAppData(); waiter.Wait(); EXPECT_TRUE(waiter.loaded()); // Verify the app has been updated to v2. manager()->GetApps(&apps); ASSERT_EQ(1u, apps.size()); base::FilePath v2_crx_path; std::string new_version; EXPECT_TRUE(GetCachedCrx(kTestLocalFsKioskApp, &v2_crx_path, &new_version)); EXPECT_EQ("2.0.0", new_version); // Verify both v1 and v2 crx files exist. EXPECT_TRUE(base::PathExists(v1_crx_path)); EXPECT_TRUE(base::PathExists(v2_crx_path)); // Remove the app now. manager()->RemoveApp(kTestLocalFsKioskApp, owner_settings_service_.get()); content::RunAllBlockingPoolTasksUntilIdle(); manager()->GetApps(&apps); ASSERT_EQ(0u, apps.size()); // Verify both v1 and v2 crx files are removed. EXPECT_FALSE(base::PathExists(v1_crx_path)); EXPECT_FALSE(base::PathExists(v2_crx_path)); EXPECT_FALSE(GetCachedCrx(kTestLocalFsKioskApp, &v2_crx_path, &version)); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, EnableConsumerKiosk) { scoped_ptr status( new KioskAppManager::ConsumerKioskAutoLaunchStatus( KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED)); scoped_ptr locked(new bool(false)); scoped_refptr runner = new content::MessageLoopRunner; manager()->GetConsumerKioskAutoLaunchStatus( base::Bind(&ConsumerKioskAutoLaunchStatusCheck, status.get(), runner->QuitClosure())); runner->Run(); EXPECT_EQ(*status.get(), KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_CONFIGURABLE); scoped_refptr runner2 = new content::MessageLoopRunner; manager()->EnableConsumerKioskAutoLaunch( base::Bind(&ConsumerKioskModeLockCheck, locked.get(), runner2->QuitClosure())); runner2->Run(); EXPECT_TRUE(*locked.get()); scoped_refptr runner3 = new content::MessageLoopRunner; manager()->GetConsumerKioskAutoLaunchStatus( base::Bind(&ConsumerKioskAutoLaunchStatusCheck, status.get(), runner3->QuitClosure())); runner3->Run(); EXPECT_EQ(*status.get(), KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_ENABLED); } IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, PreventEnableConsumerKioskForEnterprise) { // First, lock the device as enterprise. EXPECT_EQ(LockDeviceForEnterprise(), policy::EnterpriseInstallAttributes::LOCK_SUCCESS); scoped_ptr status( new KioskAppManager::ConsumerKioskAutoLaunchStatus( KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED)); scoped_ptr locked(new bool(true)); scoped_refptr runner = new content::MessageLoopRunner; manager()->GetConsumerKioskAutoLaunchStatus( base::Bind(&ConsumerKioskAutoLaunchStatusCheck, status.get(), runner->QuitClosure())); runner->Run(); EXPECT_EQ(*status.get(), KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED); scoped_refptr runner2 = new content::MessageLoopRunner; manager()->EnableConsumerKioskAutoLaunch( base::Bind(&ConsumerKioskModeLockCheck, locked.get(), runner2->QuitClosure())); runner2->Run(); EXPECT_FALSE(*locked.get()); scoped_refptr runner3 = new content::MessageLoopRunner; manager()->GetConsumerKioskAutoLaunchStatus( base::Bind(&ConsumerKioskAutoLaunchStatusCheck, status.get(), runner3->QuitClosure())); runner3->Run(); EXPECT_EQ(*status.get(), KioskAppManager::CONSUMER_KIOSK_AUTO_LAUNCH_DISABLED); } } // namespace chromeos