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