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.
6 #include "base/bind_helpers.h"
7 #include "base/memory/ref_counted.h"
8 #include "base/prefs/scoped_user_pref_update.h"
9 #include "base/run_loop.h"
10 #include "base/stl_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "chrome/browser/extensions/extension_browsertest.h"
13 #include "chrome/browser/extensions/extension_management.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/updater/extension_updater.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/browser.h"
18 #include "chrome/common/url_constants.h"
19 #include "components/policy/core/browser/browser_policy_connector.h"
20 #include "components/policy/core/common/mock_configuration_policy_provider.h"
21 #include "components/policy/core/common/policy_map.h"
22 #include "content/public/browser/browser_thread.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 "extensions/browser/extension_host.h"
27 #include "extensions/browser/extension_prefs.h"
28 #include "extensions/browser/extension_registry.h"
29 #include "extensions/browser/extension_system.h"
30 #include "extensions/browser/notification_types.h"
31 #include "extensions/browser/updater/extension_downloader.h"
32 #include "extensions/test/extension_test_message_listener.h"
33 #include "net/url_request/test_url_request_interceptor.h"
34 #include "policy/policy_constants.h"
35 #include "testing/gmock/include/gmock/gmock.h"
37 using content::BrowserThread
;
38 using extensions::Extension
;
39 using extensions::ExtensionRegistry
;
40 using extensions::Manifest
;
41 using policy::PolicyMap
;
42 using testing::Return
;
47 std::string
BuildForceInstallPolicyValue(const char* extension_id
,
48 const char* update_url
) {
49 return base::StringPrintf("%s;%s", extension_id
, update_url
);
54 class ExtensionManagementTest
: public ExtensionBrowserTest
{
56 void SetUpInProcessBrowserTestFixture() override
{
57 EXPECT_CALL(policy_provider_
, IsInitializationComplete(_
))
58 .WillRepeatedly(Return(true));
59 policy::BrowserPolicyConnector::SetPolicyProviderForTesting(
64 void UpdateProviderPolicy(const PolicyMap
& policy
) {
65 policy_provider_
.UpdateChromePolicy(policy
);
66 base::RunLoop().RunUntilIdle();
69 // Helper method that returns whether the extension is at the given version.
70 // This calls version(), which must be defined in the extension's bg page,
71 // as well as asking the extension itself.
73 // Note that 'version' here means something different than the version field
74 // in the extension's manifest. We use the version as reported by the
75 // background page to test how overinstalling crx files with the same
76 // manifest version works.
77 bool IsExtensionAtVersion(const Extension
* extension
,
78 const std::string
& expected_version
) {
79 // Test that the extension's version from the manifest and reported by the
80 // background page is correct. This is to ensure that the processes are in
81 // sync with the Extension.
82 extensions::ProcessManager
* manager
=
83 extensions::ProcessManager::Get(browser()->profile());
84 extensions::ExtensionHost
* ext_host
=
85 manager
->GetBackgroundHostForExtension(extension
->id());
86 EXPECT_TRUE(ext_host
);
90 std::string version_from_bg
;
91 bool exec
= content::ExecuteScriptAndExtractString(
92 ext_host
->render_view_host(), "version()", &version_from_bg
);
97 if (version_from_bg
!= expected_version
||
98 extension
->VersionString() != expected_version
)
104 policy::MockConfigurationPolicyProvider policy_provider_
;
107 #if defined(OS_LINUX) || defined(OS_WIN)
108 // Times out sometimes on Linux and Win XP. http://crbug.com/89727
109 #define MAYBE_InstallSameVersion DISABLED_InstallSameVersion
111 #define MAYBE_InstallSameVersion InstallSameVersion
114 // Tests that installing the same version overwrites.
115 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest
, MAYBE_InstallSameVersion
) {
116 const Extension
* extension
= InstallExtension(
117 test_data_dir_
.AppendASCII("install/install.crx"), 1);
118 ASSERT_TRUE(extension
);
119 base::FilePath old_path
= extension
->path();
121 // Install an extension with the same version. The previous install should be
123 extension
= InstallExtension(
124 test_data_dir_
.AppendASCII("install/install_same_version.crx"), 0);
125 ASSERT_TRUE(extension
);
126 base::FilePath new_path
= extension
->path();
128 EXPECT_FALSE(IsExtensionAtVersion(extension
, "1.0"));
129 EXPECT_NE(old_path
.value(), new_path
.value());
132 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest
, InstallOlderVersion
) {
133 const Extension
* extension
= InstallExtension(
134 test_data_dir_
.AppendASCII("install/install.crx"), 1);
135 ASSERT_TRUE(extension
);
136 ASSERT_FALSE(InstallExtension(
137 test_data_dir_
.AppendASCII("install/install_older_version.crx"), 0));
138 EXPECT_TRUE(IsExtensionAtVersion(extension
, "1.0"));
141 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest
, InstallThenCancel
) {
142 const Extension
* extension
= InstallExtension(
143 test_data_dir_
.AppendASCII("install/install.crx"), 1);
144 ASSERT_TRUE(extension
);
146 // Cancel this install.
147 ASSERT_FALSE(StartInstallButCancel(
148 test_data_dir_
.AppendASCII("install/install_v2.crx")));
149 EXPECT_TRUE(IsExtensionAtVersion(extension
, "1.0"));
153 // http://crbug.com/141913
154 #define MAYBE_InstallRequiresConfirm DISABLED_InstallRequiresConfirm
156 #define MAYBE_InstallRequiresConfirm InstallRequiresConfirm
158 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest
, MAYBE_InstallRequiresConfirm
) {
159 // Installing the extension without an auto confirming UI should result in
160 // it being disabled, since good.crx has permissions that require approval.
161 ExtensionService
* service
= extensions::ExtensionSystem::Get(
162 browser()->profile())->extension_service();
163 std::string id
= "ldnnhddmnhbkjipkidpdiheffobcpfmf";
164 ASSERT_FALSE(InstallExtension(test_data_dir_
.AppendASCII("good.crx"), 0));
165 ASSERT_TRUE(service
->GetExtensionById(id
, true));
166 UninstallExtension(id
);
168 // And the install should succeed when the permissions are accepted.
169 ASSERT_TRUE(InstallExtensionWithUIAutoConfirm(
170 test_data_dir_
.AppendASCII("good.crx"), 1, browser()));
171 UninstallExtension(id
);
174 // Tests that disabling and re-enabling an extension works.
175 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest
, DisableEnable
) {
176 extensions::ProcessManager
* manager
=
177 extensions::ProcessManager::Get(browser()->profile());
178 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
179 const size_t size_before
= registry
->enabled_extensions().size();
181 // Load an extension, expect the background page to be available.
182 std::string extension_id
= "bjafgdebaacbbbecmhlhpofkepfkgcpa";
183 ASSERT_TRUE(LoadExtension(
184 test_data_dir_
.AppendASCII("good").AppendASCII("Extensions")
185 .AppendASCII(extension_id
)
186 .AppendASCII("1.0")));
187 ASSERT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
188 EXPECT_EQ(0u, registry
->disabled_extensions().size());
189 EXPECT_TRUE(manager
->GetBackgroundHostForExtension(extension_id
));
191 // After disabling, the background page should go away.
192 DisableExtension(extension_id
);
193 EXPECT_EQ(size_before
, registry
->enabled_extensions().size());
194 EXPECT_EQ(1u, registry
->disabled_extensions().size());
195 EXPECT_FALSE(manager
->GetBackgroundHostForExtension(extension_id
));
197 // And bring it back.
198 EnableExtension(extension_id
);
199 EXPECT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
200 EXPECT_EQ(0u, registry
->disabled_extensions().size());
201 EXPECT_TRUE(manager
->GetBackgroundHostForExtension(extension_id
));
204 // Used for testing notifications sent during extension updates.
205 class NotificationListener
: public content::NotificationObserver
{
207 NotificationListener() : started_(false), finished_(false) {
208 int types
[] = {extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED
,
209 extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND
};
210 for (size_t i
= 0; i
< arraysize(types
); i
++) {
212 this, types
[i
], content::NotificationService::AllSources());
215 ~NotificationListener() override
{}
217 bool started() { return started_
; }
219 bool finished() { return finished_
; }
221 const std::set
<std::string
>& updates() { return updates_
; }
229 // Implements content::NotificationObserver interface.
230 void Observe(int type
,
231 const content::NotificationSource
& source
,
232 const content::NotificationDetails
& details
) override
{
234 case extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED
: {
235 EXPECT_FALSE(started_
);
239 case extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND
: {
240 const std::string
& id
=
241 content::Details
<extensions::UpdateDetails
>(details
)->id
;
251 EXPECT_FALSE(finished_
);
256 content::NotificationRegistrar registrar_
;
258 // Did we see EXTENSION_UPDATING_STARTED?
261 // Did we see EXTENSION_UPDATING_FINISHED?
264 // The set of extension id's we've seen via EXTENSION_UPDATE_FOUND.
265 std::set
<std::string
> updates_
;
269 // Fails consistently on Windows XP, see: http://crbug.com/120640.
270 #define MAYBE_AutoUpdate DISABLED_AutoUpdate
272 // See http://crbug.com/103371 and http://crbug.com/120640.
273 #if defined(ADDRESS_SANITIZER)
274 #define MAYBE_AutoUpdate DISABLED_AutoUpdate
276 #define MAYBE_AutoUpdate AutoUpdate
280 // Tests extension autoupdate.
281 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest
, MAYBE_AutoUpdate
) {
282 NotificationListener notification_listener
;
283 base::FilePath basedir
= test_data_dir_
.AppendASCII("autoupdate");
285 // Note: This interceptor gets requests on the IO thread.
286 net::LocalHostTestURLRequestInterceptor
interceptor(
287 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
),
288 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
289 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
));
291 interceptor
.SetResponseIgnoreQuery(
292 GURL("http://localhost/autoupdate/manifest"),
293 basedir
.AppendASCII("manifest_v2.xml"));
294 interceptor
.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
295 basedir
.AppendASCII("v2.crx"));
297 // Install version 1 of the extension.
298 ExtensionTestMessageListener
listener1("v1 installed", false);
299 ExtensionService
* service
= extensions::ExtensionSystem::Get(
300 browser()->profile())->extension_service();
301 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
302 const size_t size_before
= registry
->enabled_extensions().size();
303 ASSERT_TRUE(registry
->disabled_extensions().is_empty());
304 const Extension
* extension
=
305 InstallExtension(basedir
.AppendASCII("v1.crx"), 1);
306 ASSERT_TRUE(extension
);
307 listener1
.WaitUntilSatisfied();
308 ASSERT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
309 ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension
->id());
310 ASSERT_EQ("1.0", extension
->VersionString());
312 extensions::ExtensionUpdater::CheckParams params
;
314 base::Bind(&NotificationListener::OnFinished
,
315 base::Unretained(¬ification_listener
));
317 // Run autoupdate and make sure version 2 of the extension was installed.
318 ExtensionTestMessageListener
listener2("v2 installed", false);
319 service
->updater()->CheckNow(params
);
320 ASSERT_TRUE(WaitForExtensionInstall());
321 listener2
.WaitUntilSatisfied();
322 ASSERT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
323 extension
= service
->GetExtensionById(
324 "ogjcoiohnmldgjemafoockdghcjciccf", false);
325 ASSERT_TRUE(extension
);
326 ASSERT_EQ("2.0", extension
->VersionString());
327 ASSERT_TRUE(notification_listener
.started());
328 ASSERT_TRUE(notification_listener
.finished());
329 ASSERT_TRUE(ContainsKey(notification_listener
.updates(),
330 "ogjcoiohnmldgjemafoockdghcjciccf"));
331 notification_listener
.Reset();
333 // Now try doing an update to version 3, which has been incorrectly
334 // signed. This should fail.
335 interceptor
.SetResponseIgnoreQuery(
336 GURL("http://localhost/autoupdate/manifest"),
337 basedir
.AppendASCII("manifest_v3.xml"));
338 interceptor
.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v3.crx"),
339 basedir
.AppendASCII("v3.crx"));
341 service
->updater()->CheckNow(params
);
342 ASSERT_TRUE(WaitForExtensionInstallError());
343 ASSERT_TRUE(notification_listener
.started());
344 ASSERT_TRUE(notification_listener
.finished());
345 ASSERT_TRUE(ContainsKey(notification_listener
.updates(),
346 "ogjcoiohnmldgjemafoockdghcjciccf"));
348 // Make sure the extension state is the same as before.
349 ASSERT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
350 extension
= service
->GetExtensionById(
351 "ogjcoiohnmldgjemafoockdghcjciccf", false);
352 ASSERT_TRUE(extension
);
353 ASSERT_EQ("2.0", extension
->VersionString());
357 // Fails consistently on Windows XP, see: http://crbug.com/120640.
358 #define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions
360 #if defined(ADDRESS_SANITIZER)
361 #define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions
363 #define MAYBE_AutoUpdateDisabledExtensions AutoUpdateDisabledExtensions
367 // Tests extension autoupdate.
368 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest
,
369 MAYBE_AutoUpdateDisabledExtensions
) {
370 NotificationListener notification_listener
;
371 base::FilePath basedir
= test_data_dir_
.AppendASCII("autoupdate");
373 // Note: This interceptor gets requests on the IO thread.
374 net::LocalHostTestURLRequestInterceptor
interceptor(
375 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
),
376 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
377 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
));
379 interceptor
.SetResponseIgnoreQuery(
380 GURL("http://localhost/autoupdate/manifest"),
381 basedir
.AppendASCII("manifest_v2.xml"));
382 interceptor
.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
383 basedir
.AppendASCII("v2.crx"));
385 // Install version 1 of the extension.
386 ExtensionTestMessageListener
listener1("v1 installed", false);
387 ExtensionService
* service
= extensions::ExtensionSystem::Get(
388 browser()->profile())->extension_service();
389 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
390 const size_t enabled_size_before
= registry
->enabled_extensions().size();
391 const size_t disabled_size_before
= registry
->disabled_extensions().size();
392 const Extension
* extension
=
393 InstallExtension(basedir
.AppendASCII("v1.crx"), 1);
394 ASSERT_TRUE(extension
);
395 listener1
.WaitUntilSatisfied();
396 DisableExtension(extension
->id());
397 ASSERT_EQ(disabled_size_before
+ 1, registry
->disabled_extensions().size());
398 ASSERT_EQ(enabled_size_before
, registry
->enabled_extensions().size());
399 ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension
->id());
400 ASSERT_EQ("1.0", extension
->VersionString());
402 extensions::ExtensionUpdater::CheckParams params
;
404 base::Bind(&NotificationListener::OnFinished
,
405 base::Unretained(¬ification_listener
));
407 ExtensionTestMessageListener
listener2("v2 installed", false);
408 // Run autoupdate and make sure version 2 of the extension was installed but
409 // is still disabled.
410 service
->updater()->CheckNow(params
);
411 ASSERT_TRUE(WaitForExtensionInstall());
412 ASSERT_EQ(disabled_size_before
+ 1, registry
->disabled_extensions().size());
413 ASSERT_EQ(enabled_size_before
, registry
->enabled_extensions().size());
414 extension
= service
->GetExtensionById(
415 "ogjcoiohnmldgjemafoockdghcjciccf", true);
416 ASSERT_TRUE(extension
);
417 ASSERT_FALSE(service
->GetExtensionById(
418 "ogjcoiohnmldgjemafoockdghcjciccf", false));
419 ASSERT_EQ("2.0", extension
->VersionString());
421 // The extension should have not made the callback because it is disabled.
422 // When we enabled it, it should then make the callback.
423 ASSERT_FALSE(listener2
.was_satisfied());
424 EnableExtension(extension
->id());
425 listener2
.WaitUntilSatisfied();
426 ASSERT_TRUE(notification_listener
.started());
427 ASSERT_TRUE(notification_listener
.finished());
428 ASSERT_TRUE(ContainsKey(notification_listener
.updates(),
429 "ogjcoiohnmldgjemafoockdghcjciccf"));
430 notification_listener
.Reset();
433 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest
, ExternalUrlUpdate
) {
434 ExtensionService
* service
= extensions::ExtensionSystem::Get(
435 browser()->profile())->extension_service();
436 const char kExtensionId
[] = "ogjcoiohnmldgjemafoockdghcjciccf";
437 extensions::ExtensionUpdater::CheckParams params
;
439 base::FilePath basedir
= test_data_dir_
.AppendASCII("autoupdate");
441 // Note: This interceptor gets requests on the IO thread.
442 net::LocalHostTestURLRequestInterceptor
interceptor(
443 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
),
444 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
445 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
));
447 interceptor
.SetResponseIgnoreQuery(
448 GURL("http://localhost/autoupdate/manifest"),
449 basedir
.AppendASCII("manifest_v2.xml"));
450 interceptor
.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
451 basedir
.AppendASCII("v2.crx"));
453 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
454 const size_t size_before
= registry
->enabled_extensions().size();
455 ASSERT_TRUE(registry
->disabled_extensions().is_empty());
457 extensions::PendingExtensionManager
* pending_extension_manager
=
458 service
->pending_extension_manager();
460 // The code that reads external_extensions.json uses this method to inform
461 // the ExtensionService of an extension to download. Using the real code
462 // is race-prone, because instantating the ExtensionService starts a read
463 // of external_extensions.json before this test function starts.
465 EXPECT_TRUE(pending_extension_manager
->AddFromExternalUpdateUrl(
468 GURL("http://localhost/autoupdate/manifest"),
469 Manifest::EXTERNAL_PREF_DOWNLOAD
,
473 // Run autoupdate and make sure version 2 of the extension was installed.
474 service
->updater()->CheckNow(params
);
475 ASSERT_TRUE(WaitForExtensionInstall());
476 ASSERT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
477 const Extension
* extension
= service
->GetExtensionById(kExtensionId
, false);
478 ASSERT_TRUE(extension
);
479 ASSERT_EQ("2.0", extension
->VersionString());
481 // Uninstalling the extension should set a pref that keeps the extension from
482 // being installed again the next time external_extensions.json is read.
484 UninstallExtension(kExtensionId
);
486 extensions::ExtensionPrefs
* extension_prefs
=
487 extensions::ExtensionPrefs::Get(browser()->profile());
488 EXPECT_TRUE(extension_prefs
->IsExternalExtensionUninstalled(kExtensionId
))
489 << "Uninstalling should set kill bit on externaly installed extension.";
491 // Try to install the extension again from an external source. It should fail
492 // because of the killbit.
493 EXPECT_FALSE(pending_extension_manager
->AddFromExternalUpdateUrl(
496 GURL("http://localhost/autoupdate/manifest"),
497 Manifest::EXTERNAL_PREF_DOWNLOAD
,
500 EXPECT_FALSE(pending_extension_manager
->IsIdPending(kExtensionId
))
501 << "External reinstall of a killed extension shouldn't work.";
502 EXPECT_TRUE(extension_prefs
->IsExternalExtensionUninstalled(kExtensionId
))
503 << "External reinstall of a killed extension should leave it killed.";
505 // Installing from non-external source.
506 ASSERT_TRUE(InstallExtension(basedir
.AppendASCII("v2.crx"), 1));
508 EXPECT_FALSE(extension_prefs
->IsExternalExtensionUninstalled(kExtensionId
))
509 << "Reinstalling should clear the kill bit.";
511 // Uninstalling from a non-external source should not set the kill bit.
512 UninstallExtension(kExtensionId
);
514 EXPECT_FALSE(extension_prefs
->IsExternalExtensionUninstalled(kExtensionId
))
515 << "Uninstalling non-external extension should not set kill bit.";
520 const char kForceInstallNotEmptyHelp
[] =
521 "A policy may already be controlling the list of force-installed "
522 "extensions. Please remove all policy settings from your computer "
523 "before running tests. E.g. from /etc/chromium/policies Linux or "
524 "from the registry on Windows, etc.";
528 // See http://crbug.com/57378 for flakiness details.
529 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest
, ExternalPolicyRefresh
) {
530 ExtensionService
* service
= extensions::ExtensionSystem::Get(
531 browser()->profile())->extension_service();
532 const char kExtensionId
[] = "ogjcoiohnmldgjemafoockdghcjciccf";
534 base::FilePath basedir
= test_data_dir_
.AppendASCII("autoupdate");
536 // Note: This interceptor gets requests on the IO thread.
537 net::LocalHostTestURLRequestInterceptor
interceptor(
538 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
),
539 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
540 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
));
542 interceptor
.SetResponseIgnoreQuery(
543 GURL("http://localhost/autoupdate/manifest"),
544 basedir
.AppendASCII("manifest_v2.xml"));
545 interceptor
.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
546 basedir
.AppendASCII("v2.crx"));
548 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
549 const size_t size_before
= registry
->enabled_extensions().size();
550 ASSERT_TRUE(registry
->disabled_extensions().is_empty());
552 ASSERT_TRUE(extensions::ExtensionManagementFactory::GetForBrowserContext(
553 browser()->profile())
554 ->GetForceInstallList()
556 << kForceInstallNotEmptyHelp
;
558 base::ListValue forcelist
;
559 forcelist
.AppendString(BuildForceInstallPolicyValue(
560 kExtensionId
, "http://localhost/autoupdate/manifest"));
562 policies
.Set(policy::key::kExtensionInstallForcelist
,
563 policy::POLICY_LEVEL_MANDATORY
,
564 policy::POLICY_SCOPE_USER
,
565 forcelist
.DeepCopy(),
567 UpdateProviderPolicy(policies
);
569 // Check if the extension got installed.
570 ASSERT_TRUE(WaitForExtensionInstall());
571 ASSERT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
572 const Extension
* extension
= service
->GetExtensionById(kExtensionId
, false);
573 ASSERT_TRUE(extension
);
574 ASSERT_EQ("2.0", extension
->VersionString());
575 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD
, extension
->location());
577 // Try to disable and uninstall the extension which should fail.
578 DisableExtension(kExtensionId
);
579 EXPECT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
580 EXPECT_EQ(0u, registry
->disabled_extensions().size());
581 UninstallExtension(kExtensionId
);
582 EXPECT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
583 EXPECT_EQ(0u, registry
->disabled_extensions().size());
585 // Now try to disable it through the management api, again failing.
586 ExtensionTestMessageListener
listener1("ready", false);
587 ASSERT_TRUE(LoadExtension(
588 test_data_dir_
.AppendASCII("management/uninstall_extension")));
589 ASSERT_TRUE(listener1
.WaitUntilSatisfied());
590 EXPECT_EQ(size_before
+ 2, registry
->enabled_extensions().size());
591 EXPECT_EQ(0u, registry
->disabled_extensions().size());
593 // Check that emptying the list triggers uninstall.
594 policies
.Erase(policy::key::kExtensionInstallForcelist
);
595 UpdateProviderPolicy(policies
);
596 EXPECT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
597 EXPECT_FALSE(service
->GetExtensionById(kExtensionId
, true));
600 // See http://crbug.com/103371 and http://crbug.com/120640.
601 #if defined(ADDRESS_SANITIZER) || defined(OS_WIN)
602 #define MAYBE_PolicyOverridesUserInstall DISABLED_PolicyOverridesUserInstall
604 #define MAYBE_PolicyOverridesUserInstall PolicyOverridesUserInstall
607 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest
,
608 MAYBE_PolicyOverridesUserInstall
) {
609 ExtensionService
* service
= extensions::ExtensionSystem::Get(
610 browser()->profile())->extension_service();
611 ExtensionRegistry
* registry
= ExtensionRegistry::Get(browser()->profile());
612 const char kExtensionId
[] = "ogjcoiohnmldgjemafoockdghcjciccf";
613 extensions::ExtensionUpdater::CheckParams params
;
614 service
->updater()->set_default_check_params(params
);
615 const size_t size_before
= registry
->enabled_extensions().size();
616 base::FilePath basedir
= test_data_dir_
.AppendASCII("autoupdate");
617 ASSERT_TRUE(registry
->disabled_extensions().is_empty());
619 // Note: This interceptor gets requests on the IO thread.
620 net::LocalHostTestURLRequestInterceptor
interceptor(
621 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
),
622 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
623 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN
));
625 interceptor
.SetResponseIgnoreQuery(
626 GURL("http://localhost/autoupdate/manifest"),
627 basedir
.AppendASCII("manifest_v2.xml"));
628 interceptor
.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
629 basedir
.AppendASCII("v2.crx"));
631 // Check that the policy is initially empty.
632 ASSERT_TRUE(extensions::ExtensionManagementFactory::GetForBrowserContext(
633 browser()->profile())
634 ->GetForceInstallList()
636 << kForceInstallNotEmptyHelp
;
638 // User install of the extension.
639 ASSERT_TRUE(InstallExtension(basedir
.AppendASCII("v2.crx"), 1));
640 ASSERT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
641 const Extension
* extension
= service
->GetExtensionById(kExtensionId
, false);
642 ASSERT_TRUE(extension
);
643 EXPECT_EQ(Manifest::INTERNAL
, extension
->location());
644 EXPECT_TRUE(service
->IsExtensionEnabled(kExtensionId
));
646 // Setup the force install policy. It should override the location.
647 base::ListValue forcelist
;
648 forcelist
.AppendString(BuildForceInstallPolicyValue(
649 kExtensionId
, "http://localhost/autoupdate/manifest"));
651 policies
.Set(policy::key::kExtensionInstallForcelist
,
652 policy::POLICY_LEVEL_MANDATORY
,
653 policy::POLICY_SCOPE_USER
,
654 forcelist
.DeepCopy(),
656 UpdateProviderPolicy(policies
);
658 ASSERT_TRUE(WaitForExtensionInstall());
659 ASSERT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
660 extension
= service
->GetExtensionById(kExtensionId
, false);
661 ASSERT_TRUE(extension
);
662 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD
, extension
->location());
663 EXPECT_TRUE(service
->IsExtensionEnabled(kExtensionId
));
665 // Remove the policy, and verify that the extension was uninstalled.
666 // TODO(joaodasilva): it would be nicer if the extension was kept instead,
667 // and reverted location to INTERNAL or whatever it was before the policy
669 policies
.Erase(policy::key::kExtensionInstallForcelist
);
670 UpdateProviderPolicy(policies
);
671 ASSERT_EQ(size_before
, registry
->enabled_extensions().size());
672 extension
= service
->GetExtensionById(kExtensionId
, true);
673 EXPECT_FALSE(extension
);
675 // User install again, but have it disabled too before setting the policy.
676 ASSERT_TRUE(InstallExtension(basedir
.AppendASCII("v2.crx"), 1));
677 ASSERT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
678 extension
= service
->GetExtensionById(kExtensionId
, false);
679 ASSERT_TRUE(extension
);
680 EXPECT_EQ(Manifest::INTERNAL
, extension
->location());
681 EXPECT_TRUE(service
->IsExtensionEnabled(kExtensionId
));
682 EXPECT_TRUE(registry
->disabled_extensions().is_empty());
684 DisableExtension(kExtensionId
);
685 EXPECT_EQ(1u, registry
->disabled_extensions().size());
686 extension
= service
->GetExtensionById(kExtensionId
, true);
687 EXPECT_TRUE(extension
);
688 EXPECT_FALSE(service
->IsExtensionEnabled(kExtensionId
));
690 // Install the policy again. It should overwrite the extension's location,
691 // and force enable it too.
692 policies
.Set(policy::key::kExtensionInstallForcelist
,
693 policy::POLICY_LEVEL_MANDATORY
,
694 policy::POLICY_SCOPE_USER
,
695 forcelist
.DeepCopy(),
697 UpdateProviderPolicy(policies
);
699 ASSERT_TRUE(WaitForExtensionInstall());
700 ASSERT_EQ(size_before
+ 1, registry
->enabled_extensions().size());
701 extension
= service
->GetExtensionById(kExtensionId
, false);
702 ASSERT_TRUE(extension
);
703 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD
, extension
->location());
704 EXPECT_TRUE(service
->IsExtensionEnabled(kExtensionId
));
705 EXPECT_TRUE(registry
->disabled_extensions().is_empty());