1 // Copyright (c) 2012 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 "base/bind.h"
6 #include "base/bind_helpers.h"
7 #include "base/memory/ref_counted.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/prefs/scoped_user_pref_update.h"
10 #include "base/stl_util.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/browser/extensions/extension_browsertest.h"
13 #include "chrome/browser/extensions/extension_service.h"
14 #include "chrome/browser/extensions/extension_test_message_listener.h"
15 #include "chrome/browser/extensions/external_policy_loader.h"
16 #include "chrome/browser/extensions/updater/extension_downloader.h"
17 #include "chrome/browser/extensions/updater/extension_updater.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/common/pref_names.h"
21 #include "chrome/common/url_constants.h"
22 #include "chrome/test/base/ui_test_utils.h"
23 #include "content/public/browser/notification_service.h"
24 #include "content/public/browser/render_view_host.h"
25 #include "content/public/test/browser_test_utils.h"
26 #include "content/test/net/url_request_prepackaged_interceptor.h"
27 #include "extensions/browser/extension_host.h"
28 #include "extensions/browser/extension_prefs.h"
29 #include "extensions/browser/extension_registry.h"
30 #include "extensions/browser/extension_system.h"
31 #include "extensions/browser/pref_names.h"
32 #include "net/url_request/url_fetcher.h"
33
34 using extensions::Extension;
35 using extensions::ExtensionRegistry;
36 using extensions::Manifest;
37
38 class ExtensionManagementTest : public ExtensionBrowserTest {
39 protected:
40 // Helper method that returns whether the extension is at the given version.
41 // This calls version(), which must be defined in the extension's bg page,
42 // as well as asking the extension itself.
43 //
44 // Note that 'version' here means something different than the version field
45 // in the extension's manifest. We use the version as reported by the
46 // background page to test how overinstalling crx files with the same
47 // manifest version works.
IsExtensionAtVersion(const Extension * extension,const std::string & expected_version)48 bool IsExtensionAtVersion(const Extension* extension,
49 const std::string& expected_version) {
50 // Test that the extension's version from the manifest and reported by the
51 // background page is correct. This is to ensure that the processes are in
52 // sync with the Extension.
53 extensions::ProcessManager* manager =
54 extensions::ExtensionSystem::Get(browser()->profile())->
55 process_manager();
56 extensions::ExtensionHost* ext_host =
57 manager->GetBackgroundHostForExtension(extension->id());
58 EXPECT_TRUE(ext_host);
59 if (!ext_host)
60 return false;
61
62 std::string version_from_bg;
63 bool exec = content::ExecuteScriptAndExtractString(
64 ext_host->render_view_host(), "version()", &version_from_bg);
65 EXPECT_TRUE(exec);
66 if (!exec)
67 return false;
68
69 if (version_from_bg != expected_version ||
70 extension->VersionString() != expected_version)
71 return false;
72 return true;
73 }
74 };
75
76 #if defined(OS_LINUX)
77 // Times out sometimes on Linux. http://crbug.com/89727
78 #define MAYBE_InstallSameVersion DISABLED_InstallSameVersion
79 #else
80 #define MAYBE_InstallSameVersion InstallSameVersion
81 #endif
82
83 // Tests that installing the same version overwrites.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,MAYBE_InstallSameVersion)84 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_InstallSameVersion) {
85 const Extension* extension = InstallExtension(
86 test_data_dir_.AppendASCII("install/install.crx"), 1);
87 ASSERT_TRUE(extension);
88 base::FilePath old_path = extension->path();
89
90 // Install an extension with the same version. The previous install should be
91 // overwritten.
92 extension = InstallExtension(
93 test_data_dir_.AppendASCII("install/install_same_version.crx"), 0);
94 ASSERT_TRUE(extension);
95 base::FilePath new_path = extension->path();
96
97 EXPECT_FALSE(IsExtensionAtVersion(extension, "1.0"));
98 EXPECT_NE(old_path.value(), new_path.value());
99 }
100
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,InstallOlderVersion)101 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallOlderVersion) {
102 const Extension* extension = InstallExtension(
103 test_data_dir_.AppendASCII("install/install.crx"), 1);
104 ASSERT_TRUE(extension);
105 ASSERT_FALSE(InstallExtension(
106 test_data_dir_.AppendASCII("install/install_older_version.crx"), 0));
107 EXPECT_TRUE(IsExtensionAtVersion(extension, "1.0"));
108 }
109
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,InstallThenCancel)110 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallThenCancel) {
111 const Extension* extension = InstallExtension(
112 test_data_dir_.AppendASCII("install/install.crx"), 1);
113 ASSERT_TRUE(extension);
114
115 // Cancel this install.
116 ASSERT_FALSE(StartInstallButCancel(
117 test_data_dir_.AppendASCII("install/install_v2.crx")));
118 EXPECT_TRUE(IsExtensionAtVersion(extension, "1.0"));
119 }
120
121 #if defined(OS_WIN)
122 // http://crbug.com/141913
123 #define MAYBE_InstallRequiresConfirm DISABLED_InstallRequiresConfirm
124 #else
125 #define MAYBE_InstallRequiresConfirm InstallRequiresConfirm
126 #endif
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,MAYBE_InstallRequiresConfirm)127 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_InstallRequiresConfirm) {
128 // Installing the extension without an auto confirming UI should result in
129 // it being disabled, since good.crx has permissions that require approval.
130 ExtensionService* service = extensions::ExtensionSystem::Get(
131 browser()->profile())->extension_service();
132 std::string id = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
133 ASSERT_FALSE(InstallExtension(test_data_dir_.AppendASCII("good.crx"), 0));
134 ASSERT_TRUE(service->GetExtensionById(id, true));
135 UninstallExtension(id);
136
137 // And the install should succeed when the permissions are accepted.
138 ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(
139 test_data_dir_.AppendASCII("good.crx"), 1, browser()));
140 UninstallExtension(id);
141 }
142
143 // Tests that disabling and re-enabling an extension works.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,DisableEnable)144 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DisableEnable) {
145 extensions::ProcessManager* manager =
146 extensions::ExtensionSystem::Get(browser()->profile())->process_manager();
147 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
148 const size_t size_before = registry->enabled_extensions().size();
149
150 // Load an extension, expect the background page to be available.
151 std::string extension_id = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
152 ASSERT_TRUE(LoadExtension(
153 test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
154 .AppendASCII(extension_id)
155 .AppendASCII("1.0")));
156 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
157 EXPECT_EQ(0u, registry->disabled_extensions().size());
158 EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension_id));
159
160 // After disabling, the background page should go away.
161 DisableExtension(extension_id);
162 EXPECT_EQ(size_before, registry->enabled_extensions().size());
163 EXPECT_EQ(1u, registry->disabled_extensions().size());
164 EXPECT_FALSE(manager->GetBackgroundHostForExtension(extension_id));
165
166 // And bring it back.
167 EnableExtension(extension_id);
168 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size());
169 EXPECT_EQ(0u, registry->disabled_extensions().size());
170 EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension_id));
171 }
172
173 // Used for testing notifications sent during extension updates.
174 class NotificationListener : public content::NotificationObserver {
175 public:
NotificationListener()176 NotificationListener() : started_(false), finished_(false) {
177 int types[] = {
178 chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED,
179 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND
180 };
181 for (size_t i = 0; i < arraysize(types); i++) {
182 registrar_.Add(
183 this, types[i], content::NotificationService::AllSources());
184 }
185 }
~NotificationListener()186 virtual ~NotificationListener() {}
187
started()188 bool started() { return started_; }
189
finished()190 bool finished() { return finished_; }
191
updates()192 const std::set<std::string>& updates() { return updates_; }
193
Reset()194 void Reset() {
195 started_ = false;
196 finished_ = false;
197 updates_.clear();
198 }
199
200 // Implements content::NotificationObserver interface.
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)201 virtual void Observe(int type,
202 const content::NotificationSource& source,
203 const content::NotificationDetails& details) OVERRIDE {
204 switch (type) {
205 case chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED: {
206 EXPECT_FALSE(started_);
207 started_ = true;
208 break;
209 }
210 case chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND: {
211 const std::string& id =
212 content::Details<extensions::UpdateDetails>(details)->id;
213 updates_.insert(id);
214 break;
215 }
216 default:
217 NOTREACHED();
218 }
219 }
220
OnFinished()221 void OnFinished() {
222 EXPECT_FALSE(finished_);
223 finished_ = true;
224 }
225
226 private:
227 content::NotificationRegistrar registrar_;
228
229 // Did we see EXTENSION_UPDATING_STARTED?
230 bool started_;
231
232 // Did we see EXTENSION_UPDATING_FINISHED?
233 bool finished_;
234
235 // The set of extension id's we've seen via EXTENSION_UPDATE_FOUND.
236 std::set<std::string> updates_;
237 };
238
239 #if defined(OS_WIN)
240 // Fails consistently on Windows XP, see: http://crbug.com/120640.
241 #define MAYBE_AutoUpdate DISABLED_AutoUpdate
242 #else
243 // See http://crbug.com/103371 and http://crbug.com/120640.
244 #if defined(ADDRESS_SANITIZER)
245 #define MAYBE_AutoUpdate DISABLED_AutoUpdate
246 #else
247 #define MAYBE_AutoUpdate AutoUpdate
248 #endif
249 #endif
250
251 // Tests extension autoupdate.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,MAYBE_AutoUpdate)252 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_AutoUpdate) {
253 NotificationListener notification_listener;
254 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
255 // Note: This interceptor gets requests on the IO thread.
256 content::URLLocalHostRequestPrepackagedInterceptor interceptor;
257 net::URLFetcher::SetEnableInterceptionForTests(true);
258
259 interceptor.SetResponseIgnoreQuery(
260 GURL("http://localhost/autoupdate/manifest"),
261 basedir.AppendASCII("manifest_v2.xml"));
262 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
263 basedir.AppendASCII("v2.crx"));
264
265 // Install version 1 of the extension.
266 ExtensionTestMessageListener listener1("v1 installed", false);
267 ExtensionService* service = extensions::ExtensionSystem::Get(
268 browser()->profile())->extension_service();
269 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
270 const size_t size_before = registry->enabled_extensions().size();
271 ASSERT_TRUE(registry->disabled_extensions().is_empty());
272 const Extension* extension =
273 InstallExtension(basedir.AppendASCII("v1.crx"), 1);
274 ASSERT_TRUE(extension);
275 listener1.WaitUntilSatisfied();
276 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
277 ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id());
278 ASSERT_EQ("1.0", extension->VersionString());
279
280 extensions::ExtensionUpdater::CheckParams params;
281 params.callback =
282 base::Bind(&NotificationListener::OnFinished,
283 base::Unretained(¬ification_listener));
284
285 // Run autoupdate and make sure version 2 of the extension was installed.
286 ExtensionTestMessageListener listener2("v2 installed", false);
287 service->updater()->CheckNow(params);
288 ASSERT_TRUE(WaitForExtensionInstall());
289 listener2.WaitUntilSatisfied();
290 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
291 extension = service->GetExtensionById(
292 "ogjcoiohnmldgjemafoockdghcjciccf", false);
293 ASSERT_TRUE(extension);
294 ASSERT_EQ("2.0", extension->VersionString());
295 ASSERT_TRUE(notification_listener.started());
296 ASSERT_TRUE(notification_listener.finished());
297 ASSERT_TRUE(ContainsKey(notification_listener.updates(),
298 "ogjcoiohnmldgjemafoockdghcjciccf"));
299 notification_listener.Reset();
300
301 // Now try doing an update to version 3, which has been incorrectly
302 // signed. This should fail.
303 interceptor.SetResponseIgnoreQuery(
304 GURL("http://localhost/autoupdate/manifest"),
305 basedir.AppendASCII("manifest_v3.xml"));
306 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v3.crx"),
307 basedir.AppendASCII("v3.crx"));
308
309 service->updater()->CheckNow(params);
310 ASSERT_TRUE(WaitForExtensionInstallError());
311 ASSERT_TRUE(notification_listener.started());
312 ASSERT_TRUE(notification_listener.finished());
313 ASSERT_TRUE(ContainsKey(notification_listener.updates(),
314 "ogjcoiohnmldgjemafoockdghcjciccf"));
315
316 // Make sure the extension state is the same as before.
317 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
318 extension = service->GetExtensionById(
319 "ogjcoiohnmldgjemafoockdghcjciccf", false);
320 ASSERT_TRUE(extension);
321 ASSERT_EQ("2.0", extension->VersionString());
322 }
323
324 #if defined(OS_WIN)
325 // Fails consistently on Windows XP, see: http://crbug.com/120640.
326 #define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions
327 #else
328 #if defined(ADDRESS_SANITIZER)
329 #define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions
330 #else
331 #define MAYBE_AutoUpdateDisabledExtensions AutoUpdateDisabledExtensions
332 #endif
333 #endif
334
335 // Tests extension autoupdate.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,MAYBE_AutoUpdateDisabledExtensions)336 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,
337 MAYBE_AutoUpdateDisabledExtensions) {
338 NotificationListener notification_listener;
339 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
340 // Note: This interceptor gets requests on the IO thread.
341 content::URLLocalHostRequestPrepackagedInterceptor interceptor;
342 net::URLFetcher::SetEnableInterceptionForTests(true);
343
344 interceptor.SetResponseIgnoreQuery(
345 GURL("http://localhost/autoupdate/manifest"),
346 basedir.AppendASCII("manifest_v2.xml"));
347 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
348 basedir.AppendASCII("v2.crx"));
349
350 // Install version 1 of the extension.
351 ExtensionTestMessageListener listener1("v1 installed", false);
352 ExtensionService* service = extensions::ExtensionSystem::Get(
353 browser()->profile())->extension_service();
354 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
355 const size_t enabled_size_before = registry->enabled_extensions().size();
356 const size_t disabled_size_before = registry->disabled_extensions().size();
357 const Extension* extension =
358 InstallExtension(basedir.AppendASCII("v1.crx"), 1);
359 ASSERT_TRUE(extension);
360 listener1.WaitUntilSatisfied();
361 DisableExtension(extension->id());
362 ASSERT_EQ(disabled_size_before + 1, registry->disabled_extensions().size());
363 ASSERT_EQ(enabled_size_before, registry->enabled_extensions().size());
364 ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id());
365 ASSERT_EQ("1.0", extension->VersionString());
366
367 extensions::ExtensionUpdater::CheckParams params;
368 params.callback =
369 base::Bind(&NotificationListener::OnFinished,
370 base::Unretained(¬ification_listener));
371
372 ExtensionTestMessageListener listener2("v2 installed", false);
373 // Run autoupdate and make sure version 2 of the extension was installed but
374 // is still disabled.
375 service->updater()->CheckNow(params);
376 ASSERT_TRUE(WaitForExtensionInstall());
377 ASSERT_EQ(disabled_size_before + 1, registry->disabled_extensions().size());
378 ASSERT_EQ(enabled_size_before, registry->enabled_extensions().size());
379 extension = service->GetExtensionById(
380 "ogjcoiohnmldgjemafoockdghcjciccf", true);
381 ASSERT_TRUE(extension);
382 ASSERT_FALSE(service->GetExtensionById(
383 "ogjcoiohnmldgjemafoockdghcjciccf", false));
384 ASSERT_EQ("2.0", extension->VersionString());
385
386 // The extension should have not made the callback because it is disabled.
387 // When we enabled it, it should then make the callback.
388 ASSERT_FALSE(listener2.was_satisfied());
389 EnableExtension(extension->id());
390 listener2.WaitUntilSatisfied();
391 ASSERT_TRUE(notification_listener.started());
392 ASSERT_TRUE(notification_listener.finished());
393 ASSERT_TRUE(ContainsKey(notification_listener.updates(),
394 "ogjcoiohnmldgjemafoockdghcjciccf"));
395 notification_listener.Reset();
396 }
397
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,ExternalUrlUpdate)398 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) {
399 ExtensionService* service = extensions::ExtensionSystem::Get(
400 browser()->profile())->extension_service();
401 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
402 extensions::ExtensionUpdater::CheckParams params;
403
404 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
405
406 // Note: This interceptor gets requests on the IO thread.
407 content::URLLocalHostRequestPrepackagedInterceptor interceptor;
408 net::URLFetcher::SetEnableInterceptionForTests(true);
409
410 interceptor.SetResponseIgnoreQuery(
411 GURL("http://localhost/autoupdate/manifest"),
412 basedir.AppendASCII("manifest_v2.xml"));
413 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
414 basedir.AppendASCII("v2.crx"));
415
416 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
417 const size_t size_before = registry->enabled_extensions().size();
418 ASSERT_TRUE(registry->disabled_extensions().is_empty());
419
420 extensions::PendingExtensionManager* pending_extension_manager =
421 service->pending_extension_manager();
422
423 // The code that reads external_extensions.json uses this method to inform
424 // the ExtensionService of an extension to download. Using the real code
425 // is race-prone, because instantating the ExtensionService starts a read
426 // of external_extensions.json before this test function starts.
427
428 EXPECT_TRUE(pending_extension_manager->AddFromExternalUpdateUrl(
429 kExtensionId,
430 std::string(),
431 GURL("http://localhost/autoupdate/manifest"),
432 Manifest::EXTERNAL_PREF_DOWNLOAD,
433 Extension::NO_FLAGS,
434 false));
435
436 // Run autoupdate and make sure version 2 of the extension was installed.
437 service->updater()->CheckNow(params);
438 ASSERT_TRUE(WaitForExtensionInstall());
439 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
440 const Extension* extension = service->GetExtensionById(kExtensionId, false);
441 ASSERT_TRUE(extension);
442 ASSERT_EQ("2.0", extension->VersionString());
443
444 // Uninstalling the extension should set a pref that keeps the extension from
445 // being installed again the next time external_extensions.json is read.
446
447 UninstallExtension(kExtensionId);
448
449 extensions::ExtensionPrefs* extension_prefs =
450 extensions::ExtensionPrefs::Get(browser()->profile());
451 EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
452 << "Uninstalling should set kill bit on externaly installed extension.";
453
454 // Try to install the extension again from an external source. It should fail
455 // because of the killbit.
456 EXPECT_FALSE(pending_extension_manager->AddFromExternalUpdateUrl(
457 kExtensionId,
458 std::string(),
459 GURL("http://localhost/autoupdate/manifest"),
460 Manifest::EXTERNAL_PREF_DOWNLOAD,
461 Extension::NO_FLAGS,
462 false));
463 EXPECT_FALSE(pending_extension_manager->IsIdPending(kExtensionId))
464 << "External reinstall of a killed extension shouldn't work.";
465 EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
466 << "External reinstall of a killed extension should leave it killed.";
467
468 // Installing from non-external source.
469 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
470
471 EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
472 << "Reinstalling should clear the kill bit.";
473
474 // Uninstalling from a non-external source should not set the kill bit.
475 UninstallExtension(kExtensionId);
476
477 EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
478 << "Uninstalling non-external extension should not set kill bit.";
479 }
480
481 namespace {
482
483 const char* kForceInstallNotEmptyHelp =
484 "A policy may already be controlling the list of force-installed "
485 "extensions. Please remove all policy settings from your computer "
486 "before running tests. E.g. from /etc/chromium/policies Linux or "
487 "from the registry on Windows, etc.";
488
489 }
490
491 // See http://crbug.com/57378 for flakiness details.
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,ExternalPolicyRefresh)492 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) {
493 ExtensionService* service = extensions::ExtensionSystem::Get(
494 browser()->profile())->extension_service();
495 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
496
497 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
498
499 // Note: This interceptor gets requests on the IO thread.
500 content::URLLocalHostRequestPrepackagedInterceptor interceptor;
501 net::URLFetcher::SetEnableInterceptionForTests(true);
502
503 interceptor.SetResponseIgnoreQuery(
504 GURL("http://localhost/autoupdate/manifest"),
505 basedir.AppendASCII("manifest_v2.xml"));
506 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
507 basedir.AppendASCII("v2.crx"));
508
509 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
510 const size_t size_before = registry->enabled_extensions().size();
511 ASSERT_TRUE(registry->disabled_extensions().is_empty());
512
513 PrefService* prefs = browser()->profile()->GetPrefs();
514 const base::DictionaryValue* forcelist =
515 prefs->GetDictionary(extensions::pref_names::kInstallForceList);
516 ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp;
517
518 {
519 // Set the policy as a user preference and fire notification observers.
520 DictionaryPrefUpdate pref_update(prefs,
521 extensions::pref_names::kInstallForceList);
522 base::DictionaryValue* forcelist = pref_update.Get();
523 extensions::ExternalPolicyLoader::AddExtension(
524 forcelist, kExtensionId, "http://localhost/autoupdate/manifest");
525 }
526
527 // Check if the extension got installed.
528 ASSERT_TRUE(WaitForExtensionInstall());
529 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
530 const Extension* extension = service->GetExtensionById(kExtensionId, false);
531 ASSERT_TRUE(extension);
532 ASSERT_EQ("2.0", extension->VersionString());
533 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
534
535 // Try to disable and uninstall the extension which should fail.
536 DisableExtension(kExtensionId);
537 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size());
538 EXPECT_EQ(0u, registry->disabled_extensions().size());
539 UninstallExtension(kExtensionId);
540 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size());
541 EXPECT_EQ(0u, registry->disabled_extensions().size());
542
543 // Now try to disable it through the management api, again failing.
544 ExtensionTestMessageListener listener1("ready", false);
545 ASSERT_TRUE(LoadExtension(
546 test_data_dir_.AppendASCII("management/uninstall_extension")));
547 ASSERT_TRUE(listener1.WaitUntilSatisfied());
548 EXPECT_EQ(size_before + 2, registry->enabled_extensions().size());
549 EXPECT_EQ(0u, registry->disabled_extensions().size());
550
551 // Check that emptying the list triggers uninstall.
552 prefs->ClearPref(extensions::pref_names::kInstallForceList);
553 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size());
554 EXPECT_FALSE(service->GetExtensionById(kExtensionId, true));
555 }
556
557 // See http://crbug.com/103371 and http://crbug.com/120640.
558 #if defined(ADDRESS_SANITIZER) || defined(OS_WIN)
559 #define MAYBE_PolicyOverridesUserInstall DISABLED_PolicyOverridesUserInstall
560 #else
561 #define MAYBE_PolicyOverridesUserInstall PolicyOverridesUserInstall
562 #endif
563
IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,MAYBE_PolicyOverridesUserInstall)564 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,
565 MAYBE_PolicyOverridesUserInstall) {
566 ExtensionService* service = extensions::ExtensionSystem::Get(
567 browser()->profile())->extension_service();
568 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
569 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
570 extensions::ExtensionUpdater::CheckParams params;
571 service->updater()->set_default_check_params(params);
572 const size_t size_before = registry->enabled_extensions().size();
573 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
574 ASSERT_TRUE(registry->disabled_extensions().is_empty());
575
576 // Note: This interceptor gets requests on the IO thread.
577 content::URLLocalHostRequestPrepackagedInterceptor interceptor;
578 net::URLFetcher::SetEnableInterceptionForTests(true);
579
580 interceptor.SetResponseIgnoreQuery(
581 GURL("http://localhost/autoupdate/manifest"),
582 basedir.AppendASCII("manifest_v2.xml"));
583 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
584 basedir.AppendASCII("v2.crx"));
585
586 // Check that the policy is initially empty.
587 PrefService* prefs = browser()->profile()->GetPrefs();
588 const base::DictionaryValue* forcelist =
589 prefs->GetDictionary(extensions::pref_names::kInstallForceList);
590 ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp;
591
592 // User install of the extension.
593 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
594 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
595 const Extension* extension = service->GetExtensionById(kExtensionId, false);
596 ASSERT_TRUE(extension);
597 EXPECT_EQ(Manifest::INTERNAL, extension->location());
598 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
599
600 // Setup the force install policy. It should override the location.
601 {
602 DictionaryPrefUpdate pref_update(prefs,
603 extensions::pref_names::kInstallForceList);
604 extensions::ExternalPolicyLoader::AddExtension(
605 pref_update.Get(), kExtensionId,
606 "http://localhost/autoupdate/manifest");
607 }
608 ASSERT_TRUE(WaitForExtensionInstall());
609 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
610 extension = service->GetExtensionById(kExtensionId, false);
611 ASSERT_TRUE(extension);
612 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
613 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
614
615 // Remove the policy, and verify that the extension was uninstalled.
616 // TODO(joaodasilva): it would be nicer if the extension was kept instead,
617 // and reverted location to INTERNAL or whatever it was before the policy
618 // was applied.
619 prefs->ClearPref(extensions::pref_names::kInstallForceList);
620 ASSERT_EQ(size_before, registry->enabled_extensions().size());
621 extension = service->GetExtensionById(kExtensionId, true);
622 EXPECT_FALSE(extension);
623
624 // User install again, but have it disabled too before setting the policy.
625 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
626 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
627 extension = service->GetExtensionById(kExtensionId, false);
628 ASSERT_TRUE(extension);
629 EXPECT_EQ(Manifest::INTERNAL, extension->location());
630 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
631 EXPECT_TRUE(registry->disabled_extensions().is_empty());
632
633 DisableExtension(kExtensionId);
634 EXPECT_EQ(1u, registry->disabled_extensions().size());
635 extension = service->GetExtensionById(kExtensionId, true);
636 EXPECT_TRUE(extension);
637 EXPECT_FALSE(service->IsExtensionEnabled(kExtensionId));
638
639 // Install the policy again. It should overwrite the extension's location,
640 // and force enable it too.
641 {
642 DictionaryPrefUpdate pref_update(prefs,
643 extensions::pref_names::kInstallForceList);
644 base::DictionaryValue* forcelist = pref_update.Get();
645 extensions::ExternalPolicyLoader::AddExtension(
646 forcelist, kExtensionId, "http://localhost/autoupdate/manifest");
647 }
648 ASSERT_TRUE(WaitForExtensionInstall());
649 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
650 extension = service->GetExtensionById(kExtensionId, false);
651 ASSERT_TRUE(extension);
652 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
653 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
654 EXPECT_TRUE(registry->disabled_extensions().is_empty());
655 }
656