OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" | 5 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/file_util.h" |
| 9 #include "base/files/scoped_temp_dir.h" |
8 #include "base/message_loop/message_loop.h" | 10 #include "base/message_loop/message_loop.h" |
9 #include "base/path_service.h" | 11 #include "base/path_service.h" |
10 #include "base/prefs/scoped_user_pref_update.h" | 12 #include "base/prefs/scoped_user_pref_update.h" |
11 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
12 #include "base/values.h" | 14 #include "base/values.h" |
13 #include "chrome/browser/browser_process.h" | 15 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h" | 16 #include "chrome/browser/chromeos/app_mode/kiosk_app_manager_observer.h" |
15 #include "chrome/browser/chromeos/policy/device_local_account.h" | 17 #include "chrome/browser/chromeos/policy/device_local_account.h" |
16 #include "chrome/browser/chromeos/settings/cros_settings.h" | 18 #include "chrome/browser/chromeos/settings/cros_settings.h" |
17 #include "chrome/browser/policy/browser_policy_connector.h" | 19 #include "chrome/browser/policy/browser_policy_connector.h" |
| 20 #include "chrome/browser/ui/browser.h" |
18 #include "chrome/common/chrome_paths.h" | 21 #include "chrome/common/chrome_paths.h" |
19 #include "chrome/common/chrome_switches.h" | 22 #include "chrome/common/chrome_switches.h" |
20 #include "chrome/test/base/in_process_browser_test.h" | 23 #include "chrome/test/base/in_process_browser_test.h" |
21 #include "chromeos/settings/cros_settings_names.h" | 24 #include "chromeos/settings/cros_settings_names.h" |
22 #include "content/public/test/test_utils.h" | 25 #include "content/public/test/test_utils.h" |
| 26 #include "extensions/common/extension.h" |
23 #include "net/base/host_port_pair.h" | 27 #include "net/base/host_port_pair.h" |
24 #include "net/dns/mock_host_resolver.h" | 28 #include "net/dns/mock_host_resolver.h" |
25 #include "net/test/embedded_test_server/embedded_test_server.h" | 29 #include "net/test/embedded_test_server/embedded_test_server.h" |
26 | 30 |
27 namespace chromeos { | 31 namespace chromeos { |
28 | 32 |
29 namespace { | 33 namespace { |
30 | 34 |
31 const char kWebstoreDomain[] = "cws.com"; | 35 const char kWebstoreDomain[] = "cws.com"; |
32 | 36 |
(...skipping 20 matching lines...) Expand all Loading... |
53 // Helper EnterpriseInstallAttributes::LockResultCallback implementation. | 57 // Helper EnterpriseInstallAttributes::LockResultCallback implementation. |
54 void OnEnterpriseDeviceLock( | 58 void OnEnterpriseDeviceLock( |
55 policy::EnterpriseInstallAttributes::LockResult* out_locked, | 59 policy::EnterpriseInstallAttributes::LockResult* out_locked, |
56 const base::Closure& runner_quit_task, | 60 const base::Closure& runner_quit_task, |
57 policy::EnterpriseInstallAttributes::LockResult in_locked) { | 61 policy::EnterpriseInstallAttributes::LockResult in_locked) { |
58 LOG(INFO) << "Enterprise lock = " << in_locked; | 62 LOG(INFO) << "Enterprise lock = " << in_locked; |
59 *out_locked = in_locked; | 63 *out_locked = in_locked; |
60 runner_quit_task.Run(); | 64 runner_quit_task.Run(); |
61 } | 65 } |
62 | 66 |
| 67 scoped_refptr<extensions::Extension> MakeApp(const std::string& name, |
| 68 const std::string& version, |
| 69 const std::string& url, |
| 70 const std::string& id) { |
| 71 std::string err; |
| 72 base::DictionaryValue value; |
| 73 value.SetString("name", name); |
| 74 value.SetString("version", version); |
| 75 value.SetString("app.launch.web_url", url); |
| 76 scoped_refptr<extensions::Extension> app = |
| 77 extensions::Extension::Create( |
| 78 base::FilePath(), |
| 79 extensions::Manifest::INTERNAL, |
| 80 value, |
| 81 extensions::Extension::WAS_INSTALLED_BY_DEFAULT, |
| 82 id, |
| 83 &err); |
| 84 EXPECT_EQ(err, ""); |
| 85 return app; |
| 86 } |
| 87 |
63 class TestKioskAppManagerObserver : public KioskAppManagerObserver { | 88 class TestKioskAppManagerObserver : public KioskAppManagerObserver { |
64 public: | 89 public: |
65 explicit TestKioskAppManagerObserver(KioskAppManager* manager) | 90 explicit TestKioskAppManagerObserver(KioskAppManager* manager) |
66 : manager_(manager), | 91 : manager_(manager), |
67 data_changed_count_(0), | 92 data_changed_count_(0), |
68 load_failure_count_(0) { | 93 load_failure_count_(0) { |
69 manager_->AddObserver(this); | 94 manager_->AddObserver(this); |
70 } | 95 } |
71 virtual ~TestKioskAppManagerObserver() { | 96 virtual ~TestKioskAppManagerObserver() { |
72 manager_->RemoveObserver(this); | 97 manager_->RemoveObserver(this); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
146 base::FilePath test_data_dir; | 171 base::FilePath test_data_dir; |
147 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); | 172 PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir); |
148 base::FilePath webstore_dir = | 173 base::FilePath webstore_dir = |
149 test_data_dir.Append(FILE_PATH_LITERAL("chromeos/app_mode/")); | 174 test_data_dir.Append(FILE_PATH_LITERAL("chromeos/app_mode/")); |
150 embedded_test_server()->ServeFilesFromDirectory(webstore_dir); | 175 embedded_test_server()->ServeFilesFromDirectory(webstore_dir); |
151 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); | 176 ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); |
152 // Stop IO thread here because no threads are allowed while | 177 // Stop IO thread here because no threads are allowed while |
153 // spawning sandbox host process. See crbug.com/322732. | 178 // spawning sandbox host process. See crbug.com/322732. |
154 embedded_test_server()->StopThread(); | 179 embedded_test_server()->StopThread(); |
155 | 180 |
| 181 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); |
| 182 |
156 InProcessBrowserTest::SetUp(); | 183 InProcessBrowserTest::SetUp(); |
157 } | 184 } |
158 | 185 |
159 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { | 186 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { |
160 InProcessBrowserTest::SetUpCommandLine(command_line); | 187 InProcessBrowserTest::SetUpCommandLine(command_line); |
161 | 188 |
162 // Get fake webstore gallery URL. At the end, it should look something like | 189 // Get fake webstore gallery URL. At the end, it should look something like |
163 // http://cws.com:<test_server_port>/webstore. | 190 // http://cws.com:<test_server_port>/webstore. |
164 const GURL& server_url = embedded_test_server()->base_url(); | 191 const GURL& server_url = embedded_test_server()->base_url(); |
165 std::string google_host(kWebstoreDomain); | 192 std::string google_host(kWebstoreDomain); |
(...skipping 25 matching lines...) Expand all Loading... |
191 std::string str; | 218 std::string str; |
192 for (size_t i = 0; i < apps.size(); ++i) { | 219 for (size_t i = 0; i < apps.size(); ++i) { |
193 if (i > 0) | 220 if (i > 0) |
194 str += ','; | 221 str += ','; |
195 str += apps[i].app_id; | 222 str += apps[i].app_id; |
196 } | 223 } |
197 | 224 |
198 return str; | 225 return str; |
199 } | 226 } |
200 | 227 |
201 KioskAppManager* manager() const { return KioskAppManager::Get(); } | |
202 | |
203 // Locks device for enterprise. | 228 // Locks device for enterprise. |
204 policy::EnterpriseInstallAttributes::LockResult LockDeviceForEnterprise() { | 229 policy::EnterpriseInstallAttributes::LockResult LockDeviceForEnterprise() { |
205 scoped_ptr<policy::EnterpriseInstallAttributes::LockResult> lock_result( | 230 scoped_ptr<policy::EnterpriseInstallAttributes::LockResult> lock_result( |
206 new policy::EnterpriseInstallAttributes::LockResult( | 231 new policy::EnterpriseInstallAttributes::LockResult( |
207 policy::EnterpriseInstallAttributes::LOCK_NOT_READY)); | 232 policy::EnterpriseInstallAttributes::LOCK_NOT_READY)); |
208 scoped_refptr<content::MessageLoopRunner> runner = | 233 scoped_refptr<content::MessageLoopRunner> runner = |
209 new content::MessageLoopRunner; | 234 new content::MessageLoopRunner; |
210 g_browser_process->browser_policy_connector()->GetInstallAttributes()-> | 235 g_browser_process->browser_policy_connector()->GetInstallAttributes()-> |
211 LockDevice( | 236 LockDevice( |
212 "user@domain.com", | 237 "user@domain.com", |
213 policy::DEVICE_MODE_ENTERPRISE, | 238 policy::DEVICE_MODE_ENTERPRISE, |
214 "device-id", | 239 "device-id", |
215 base::Bind(&OnEnterpriseDeviceLock, | 240 base::Bind(&OnEnterpriseDeviceLock, |
216 lock_result.get(), | 241 lock_result.get(), |
217 runner->QuitClosure())); | 242 runner->QuitClosure())); |
218 runner->Run(); | 243 runner->Run(); |
219 return *lock_result.get(); | 244 return *lock_result.get(); |
220 } | 245 } |
221 | 246 |
| 247 void SetExistingApp(const std::string& app_id, |
| 248 const std::string& app_name, |
| 249 const std::string& icon_file_name) { |
| 250 base::FilePath test_dir; |
| 251 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); |
| 252 base::FilePath data_dir = test_dir.AppendASCII("chromeos/app_mode/"); |
| 253 |
| 254 // Copy the icon file to temp dir for using because ClearAppData test |
| 255 // deletes it. |
| 256 base::FilePath icon_path = temp_dir_.path().AppendASCII(icon_file_name); |
| 257 base::CopyFile(data_dir.AppendASCII(icon_file_name), icon_path); |
| 258 |
| 259 scoped_ptr<base::DictionaryValue> apps_dict(new base::DictionaryValue); |
| 260 apps_dict->SetString(app_id + ".name", app_name); |
| 261 apps_dict->SetString(app_id + ".icon", icon_path.MaybeAsASCII()); |
| 262 |
| 263 PrefService* local_state = g_browser_process->local_state(); |
| 264 DictionaryPrefUpdate dict_update(local_state, |
| 265 KioskAppManager::kKioskDictionaryName); |
| 266 dict_update->Set(KioskAppManager::kKeyApps, apps_dict.release()); |
| 267 |
| 268 // Make the app appear in device settings. |
| 269 base::ListValue device_local_accounts; |
| 270 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); |
| 271 entry->SetStringWithoutPathExpansion( |
| 272 kAccountsPrefDeviceLocalAccountsKeyId, |
| 273 app_id + "_id"); |
| 274 entry->SetIntegerWithoutPathExpansion( |
| 275 kAccountsPrefDeviceLocalAccountsKeyType, |
| 276 policy::DeviceLocalAccount::TYPE_KIOSK_APP); |
| 277 entry->SetStringWithoutPathExpansion( |
| 278 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, |
| 279 app_id); |
| 280 device_local_accounts.Append(entry.release()); |
| 281 CrosSettings::Get()->Set(kAccountsPrefDeviceLocalAccounts, |
| 282 device_local_accounts); |
| 283 } |
| 284 |
| 285 KioskAppManager* manager() const { return KioskAppManager::Get(); } |
| 286 |
222 private: | 287 private: |
| 288 base::ScopedTempDir temp_dir_; |
| 289 |
223 DISALLOW_COPY_AND_ASSIGN(KioskAppManagerTest); | 290 DISALLOW_COPY_AND_ASSIGN(KioskAppManagerTest); |
224 }; | 291 }; |
225 | 292 |
226 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, Basic) { | 293 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, Basic) { |
227 // Add a couple of apps. Use "fake_app_x" that do not have data on the test | 294 // Add a couple of apps. Use "fake_app_x" that do not have data on the test |
228 // server to avoid pending data loads that could be lingering on tear down and | 295 // server to avoid pending data loads that could be lingering on tear down and |
229 // cause DCHECK failure in utility_process_host_impl.cc. | 296 // cause DCHECK failure in utility_process_host_impl.cc. |
230 manager()->AddApp("fake_app_1"); | 297 manager()->AddApp("fake_app_1"); |
231 manager()->AddApp("fake_app_2"); | 298 manager()->AddApp("fake_app_2"); |
232 EXPECT_EQ("fake_app_1,fake_app_2", GetAppIds()); | 299 EXPECT_EQ("fake_app_1,fake_app_2", GetAppIds()); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
265 manager()->SetAutoLaunchApp("none_exist_app"); | 332 manager()->SetAutoLaunchApp("none_exist_app"); |
266 EXPECT_EQ("", manager()->GetAutoLaunchApp()); | 333 EXPECT_EQ("", manager()->GetAutoLaunchApp()); |
267 EXPECT_FALSE(manager()->IsAutoLaunchEnabled()); | 334 EXPECT_FALSE(manager()->IsAutoLaunchEnabled()); |
268 | 335 |
269 // Add an existing app again. | 336 // Add an existing app again. |
270 manager()->AddApp("fake_app_1"); | 337 manager()->AddApp("fake_app_1"); |
271 EXPECT_EQ("fake_app_1", GetAppIds()); | 338 EXPECT_EQ("fake_app_1", GetAppIds()); |
272 } | 339 } |
273 | 340 |
274 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, LoadCached) { | 341 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, LoadCached) { |
275 base::FilePath test_dir; | 342 SetExistingApp("app_1", "Cached App1 Name", "red16x16.png"); |
276 ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_dir)); | |
277 base::FilePath data_dir = test_dir.AppendASCII("chromeos/app_mode/"); | |
278 | |
279 scoped_ptr<base::DictionaryValue> apps_dict(new base::DictionaryValue); | |
280 apps_dict->SetString("app_1.name", "App1 Name"); | |
281 std::string icon_path = | |
282 base::StringPrintf("%s/red16x16.png", data_dir.value().c_str()); | |
283 apps_dict->SetString("app_1.icon", icon_path); | |
284 | |
285 PrefService* local_state = g_browser_process->local_state(); | |
286 DictionaryPrefUpdate dict_update(local_state, | |
287 KioskAppManager::kKioskDictionaryName); | |
288 dict_update->Set(KioskAppManager::kKeyApps, apps_dict.release()); | |
289 | |
290 // Make the app appear in device settings. | |
291 base::ListValue device_local_accounts; | |
292 scoped_ptr<base::DictionaryValue> entry(new base::DictionaryValue); | |
293 entry->SetStringWithoutPathExpansion( | |
294 kAccountsPrefDeviceLocalAccountsKeyId, | |
295 "app_1_id"); | |
296 entry->SetIntegerWithoutPathExpansion( | |
297 kAccountsPrefDeviceLocalAccountsKeyType, | |
298 policy::DeviceLocalAccount::TYPE_KIOSK_APP); | |
299 entry->SetStringWithoutPathExpansion( | |
300 kAccountsPrefDeviceLocalAccountsKeyKioskAppId, | |
301 "app_1"); | |
302 device_local_accounts.Append(entry.release()); | |
303 CrosSettings::Get()->Set(kAccountsPrefDeviceLocalAccounts, | |
304 device_local_accounts); | |
305 | 343 |
306 AppDataLoadWaiter waiter(manager()); | 344 AppDataLoadWaiter waiter(manager()); |
307 waiter.Wait(); | 345 waiter.Wait(); |
| 346 EXPECT_TRUE(waiter.loaded()); |
| 347 |
| 348 KioskAppManager::Apps apps; |
| 349 manager()->GetApps(&apps); |
| 350 EXPECT_EQ(1u, apps.size()); |
| 351 EXPECT_EQ("app_1", apps[0].app_id); |
| 352 EXPECT_EQ("Cached App1 Name", apps[0].name); |
| 353 EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size()); |
| 354 } |
| 355 |
| 356 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, ClearAppData) { |
| 357 SetExistingApp("app_1", "Cached App1 Name", "red16x16.png"); |
| 358 |
| 359 PrefService* local_state = g_browser_process->local_state(); |
| 360 const base::DictionaryValue* dict = |
| 361 local_state->GetDictionary(KioskAppManager::kKioskDictionaryName); |
| 362 const base::DictionaryValue* apps_dict; |
| 363 EXPECT_TRUE(dict->GetDictionary(KioskAppManager::kKeyApps, &apps_dict)); |
| 364 EXPECT_TRUE(apps_dict->HasKey("app_1")); |
| 365 |
| 366 manager()->ClearAppData("app_1"); |
| 367 |
| 368 EXPECT_FALSE(apps_dict->HasKey("app_1")); |
| 369 } |
| 370 |
| 371 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, UpdateAppDataFromProfile) { |
| 372 SetExistingApp("app_1", "Cached App1 Name", "red16x16.png"); |
| 373 |
| 374 AppDataLoadWaiter waiter(manager()); |
| 375 waiter.Wait(); |
308 EXPECT_TRUE(waiter.loaded()); | 376 EXPECT_TRUE(waiter.loaded()); |
309 | 377 |
310 KioskAppManager::Apps apps; | 378 KioskAppManager::Apps apps; |
311 manager()->GetApps(&apps); | 379 manager()->GetApps(&apps); |
312 EXPECT_EQ(1u, apps.size()); | 380 EXPECT_EQ(1u, apps.size()); |
313 EXPECT_EQ("app_1", apps[0].app_id); | 381 EXPECT_EQ("app_1", apps[0].app_id); |
314 EXPECT_EQ("App1 Name", apps[0].name); | 382 EXPECT_EQ("Cached App1 Name", apps[0].name); |
315 EXPECT_EQ(gfx::Size(16, 16), apps[0].icon.size()); | 383 |
| 384 scoped_refptr<extensions::Extension> updated_app = |
| 385 MakeApp("Updated App1 Name", "2.0", "http://localhost/", "app_1"); |
| 386 manager()->UpdateAppDataFromProfile( |
| 387 "app_1", browser()->profile(), updated_app.get()); |
| 388 |
| 389 waiter.Wait(); |
| 390 EXPECT_TRUE(waiter.loaded()); |
| 391 |
| 392 manager()->GetApps(&apps); |
| 393 EXPECT_EQ(1u, apps.size()); |
| 394 EXPECT_EQ("app_1", apps[0].app_id); |
| 395 EXPECT_EQ("Updated App1 Name", apps[0].name); |
316 } | 396 } |
317 | 397 |
318 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, BadApp) { | 398 IN_PROC_BROWSER_TEST_F(KioskAppManagerTest, BadApp) { |
319 manager()->AddApp("unknown_app"); | 399 manager()->AddApp("unknown_app"); |
320 | 400 |
321 TestKioskAppManagerObserver observer(manager()); | 401 TestKioskAppManagerObserver observer(manager()); |
322 | 402 |
323 AppDataLoadWaiter waiter(manager()); | 403 AppDataLoadWaiter waiter(manager()); |
324 waiter.Wait(); | 404 waiter.Wait(); |
325 EXPECT_FALSE(waiter.loaded()); | 405 EXPECT_FALSE(waiter.loaded()); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
432 new content::MessageLoopRunner; | 512 new content::MessageLoopRunner; |
433 manager()->GetConsumerKioskModeStatus( | 513 manager()->GetConsumerKioskModeStatus( |
434 base::Bind(&ConsumerKioskModeStatusCheck, | 514 base::Bind(&ConsumerKioskModeStatusCheck, |
435 status.get(), | 515 status.get(), |
436 runner3->QuitClosure())); | 516 runner3->QuitClosure())); |
437 runner3->Run(); | 517 runner3->Run(); |
438 EXPECT_EQ(*status.get(), KioskAppManager::CONSUMER_KIOSK_MODE_DISABLED); | 518 EXPECT_EQ(*status.get(), KioskAppManager::CONSUMER_KIOSK_MODE_DISABLED); |
439 } | 519 } |
440 | 520 |
441 } // namespace chromeos | 521 } // namespace chromeos |
OLD | NEW |