Home | History | Annotate | Download | only in management
      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     extensions::ProcessManager* 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   extensions::ProcessManager* 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 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) {
    394   ExtensionService* service = extensions::ExtensionSystem::Get(
    395       browser()->profile())->extension_service();
    396   const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
    397   extensions::ExtensionUpdater::CheckParams params;
    398 
    399   base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
    400 
    401   // Note: This interceptor gets requests on the IO thread.
    402   content::URLLocalHostRequestPrepackagedInterceptor interceptor;
    403   net::URLFetcher::SetEnableInterceptionForTests(true);
    404 
    405   interceptor.SetResponseIgnoreQuery(
    406       GURL("http://localhost/autoupdate/manifest"),
    407       basedir.AppendASCII("manifest_v2.xml"));
    408   interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
    409                                      basedir.AppendASCII("v2.crx"));
    410 
    411   const size_t size_before = service->extensions()->size();
    412   ASSERT_TRUE(service->disabled_extensions()->is_empty());
    413 
    414   extensions::PendingExtensionManager* pending_extension_manager =
    415       service->pending_extension_manager();
    416 
    417   // The code that reads external_extensions.json uses this method to inform
    418   // the ExtensionService of an extension to download.  Using the real code
    419   // is race-prone, because instantating the ExtensionService starts a read
    420   // of external_extensions.json before this test function starts.
    421 
    422   EXPECT_TRUE(pending_extension_manager->AddFromExternalUpdateUrl(
    423       kExtensionId, GURL("http://localhost/autoupdate/manifest"),
    424       Manifest::EXTERNAL_PREF_DOWNLOAD, Extension::NO_FLAGS, false));
    425 
    426   // Run autoupdate and make sure version 2 of the extension was installed.
    427   service->updater()->CheckNow(params);
    428   ASSERT_TRUE(WaitForExtensionInstall());
    429   ASSERT_EQ(size_before + 1, service->extensions()->size());
    430   const Extension* extension = service->GetExtensionById(kExtensionId, false);
    431   ASSERT_TRUE(extension);
    432   ASSERT_EQ("2.0", extension->VersionString());
    433 
    434   // Uninstalling the extension should set a pref that keeps the extension from
    435   // being installed again the next time external_extensions.json is read.
    436 
    437   UninstallExtension(kExtensionId);
    438 
    439   extensions::ExtensionPrefs* extension_prefs = service->extension_prefs();
    440   EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
    441       << "Uninstalling should set kill bit on externaly installed extension.";
    442 
    443   // Try to install the extension again from an external source. It should fail
    444   // because of the killbit.
    445   EXPECT_FALSE(pending_extension_manager->AddFromExternalUpdateUrl(
    446       kExtensionId, GURL("http://localhost/autoupdate/manifest"),
    447       Manifest::EXTERNAL_PREF_DOWNLOAD, Extension::NO_FLAGS, false));
    448   EXPECT_FALSE(pending_extension_manager->IsIdPending(kExtensionId))
    449       << "External reinstall of a killed extension shouldn't work.";
    450   EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
    451       << "External reinstall of a killed extension should leave it killed.";
    452 
    453   // Installing from non-external source.
    454   ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
    455 
    456   EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
    457       << "Reinstalling should clear the kill bit.";
    458 
    459   // Uninstalling from a non-external source should not set the kill bit.
    460   UninstallExtension(kExtensionId);
    461 
    462   EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
    463       << "Uninstalling non-external extension should not set kill bit.";
    464 }
    465 
    466 namespace {
    467 
    468 const char* kForceInstallNotEmptyHelp =
    469     "A policy may already be controlling the list of force-installed "
    470     "extensions. Please remove all policy settings from your computer "
    471     "before running tests. E.g. from /etc/chromium/policies Linux or "
    472     "from the registry on Windows, etc.";
    473 
    474 }
    475 
    476 // See http://crbug.com/57378 for flakiness details.
    477 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) {
    478   ExtensionService* service = extensions::ExtensionSystem::Get(
    479       browser()->profile())->extension_service();
    480   const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
    481 
    482   base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
    483 
    484   // Note: This interceptor gets requests on the IO thread.
    485   content::URLLocalHostRequestPrepackagedInterceptor interceptor;
    486   net::URLFetcher::SetEnableInterceptionForTests(true);
    487 
    488   interceptor.SetResponseIgnoreQuery(
    489       GURL("http://localhost/autoupdate/manifest"),
    490       basedir.AppendASCII("manifest_v2.xml"));
    491   interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
    492                                      basedir.AppendASCII("v2.crx"));
    493 
    494   const size_t size_before = service->extensions()->size();
    495   ASSERT_TRUE(service->disabled_extensions()->is_empty());
    496 
    497   PrefService* prefs = browser()->profile()->GetPrefs();
    498   const base::DictionaryValue* forcelist =
    499       prefs->GetDictionary(prefs::kExtensionInstallForceList);
    500   ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp;
    501 
    502   {
    503     // Set the policy as a user preference and fire notification observers.
    504     DictionaryPrefUpdate pref_update(prefs, prefs::kExtensionInstallForceList);
    505     base::DictionaryValue* forcelist = pref_update.Get();
    506     extensions::ExternalPolicyLoader::AddExtension(
    507         forcelist, kExtensionId, "http://localhost/autoupdate/manifest");
    508   }
    509 
    510   // Check if the extension got installed.
    511   ASSERT_TRUE(WaitForExtensionInstall());
    512   ASSERT_EQ(size_before + 1, service->extensions()->size());
    513   const Extension* extension = service->GetExtensionById(kExtensionId, false);
    514   ASSERT_TRUE(extension);
    515   ASSERT_EQ("2.0", extension->VersionString());
    516   EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
    517 
    518   // Try to disable and uninstall the extension which should fail.
    519   DisableExtension(kExtensionId);
    520   EXPECT_EQ(size_before + 1, service->extensions()->size());
    521   EXPECT_EQ(0u, service->disabled_extensions()->size());
    522   UninstallExtension(kExtensionId);
    523   EXPECT_EQ(size_before + 1, service->extensions()->size());
    524   EXPECT_EQ(0u, service->disabled_extensions()->size());
    525 
    526   // Now try to disable it through the management api, again failing.
    527   ExtensionTestMessageListener listener1("ready", false);
    528   ASSERT_TRUE(LoadExtension(
    529       test_data_dir_.AppendASCII("management/uninstall_extension")));
    530   ASSERT_TRUE(listener1.WaitUntilSatisfied());
    531   EXPECT_EQ(size_before + 2, service->extensions()->size());
    532   EXPECT_EQ(0u, service->disabled_extensions()->size());
    533 
    534   // Check that emptying the list triggers uninstall.
    535   prefs->ClearPref(prefs::kExtensionInstallForceList);
    536   EXPECT_EQ(size_before + 1, service->extensions()->size());
    537   EXPECT_FALSE(service->GetExtensionById(kExtensionId, true));
    538 }
    539 
    540 // See http://crbug.com/103371 and http://crbug.com/120640.
    541 #if defined(ADDRESS_SANITIZER) || defined(OS_WIN)
    542 #define MAYBE_PolicyOverridesUserInstall DISABLED_PolicyOverridesUserInstall
    543 #else
    544 #define MAYBE_PolicyOverridesUserInstall PolicyOverridesUserInstall
    545 #endif
    546 
    547 IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,
    548                        MAYBE_PolicyOverridesUserInstall) {
    549   ExtensionService* service = extensions::ExtensionSystem::Get(
    550       browser()->profile())->extension_service();
    551   const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
    552   extensions::ExtensionUpdater::CheckParams params;
    553   service->updater()->set_default_check_params(params);
    554   const size_t size_before = service->extensions()->size();
    555   base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
    556   ASSERT_TRUE(service->disabled_extensions()->is_empty());
    557 
    558   // Note: This interceptor gets requests on the IO thread.
    559   content::URLLocalHostRequestPrepackagedInterceptor interceptor;
    560   net::URLFetcher::SetEnableInterceptionForTests(true);
    561 
    562   interceptor.SetResponseIgnoreQuery(
    563       GURL("http://localhost/autoupdate/manifest"),
    564       basedir.AppendASCII("manifest_v2.xml"));
    565   interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
    566                                      basedir.AppendASCII("v2.crx"));
    567 
    568   // Check that the policy is initially empty.
    569   PrefService* prefs = browser()->profile()->GetPrefs();
    570   const base::DictionaryValue* forcelist =
    571       prefs->GetDictionary(prefs::kExtensionInstallForceList);
    572   ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp;
    573 
    574   // User install of the extension.
    575   ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
    576   ASSERT_EQ(size_before + 1, service->extensions()->size());
    577   const Extension* extension = service->GetExtensionById(kExtensionId, false);
    578   ASSERT_TRUE(extension);
    579   EXPECT_EQ(Manifest::INTERNAL, extension->location());
    580   EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
    581 
    582   // Setup the force install policy. It should override the location.
    583   {
    584     DictionaryPrefUpdate pref_update(prefs, prefs::kExtensionInstallForceList);
    585     extensions::ExternalPolicyLoader::AddExtension(
    586         pref_update.Get(), kExtensionId,
    587         "http://localhost/autoupdate/manifest");
    588   }
    589   ASSERT_TRUE(WaitForExtensionInstall());
    590   ASSERT_EQ(size_before + 1, service->extensions()->size());
    591   extension = service->GetExtensionById(kExtensionId, false);
    592   ASSERT_TRUE(extension);
    593   EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
    594   EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
    595 
    596   // Remove the policy, and verify that the extension was uninstalled.
    597   // TODO(joaodasilva): it would be nicer if the extension was kept instead,
    598   // and reverted location to INTERNAL or whatever it was before the policy
    599   // was applied.
    600   prefs->ClearPref(prefs::kExtensionInstallForceList);
    601   ASSERT_EQ(size_before, service->extensions()->size());
    602   extension = service->GetExtensionById(kExtensionId, true);
    603   EXPECT_FALSE(extension);
    604 
    605   // User install again, but have it disabled too before setting the policy.
    606   ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
    607   ASSERT_EQ(size_before + 1, service->extensions()->size());
    608   extension = service->GetExtensionById(kExtensionId, false);
    609   ASSERT_TRUE(extension);
    610   EXPECT_EQ(Manifest::INTERNAL, extension->location());
    611   EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
    612   EXPECT_TRUE(service->disabled_extensions()->is_empty());
    613 
    614   DisableExtension(kExtensionId);
    615   EXPECT_EQ(1u, service->disabled_extensions()->size());
    616   extension = service->GetExtensionById(kExtensionId, true);
    617   EXPECT_TRUE(extension);
    618   EXPECT_FALSE(service->IsExtensionEnabled(kExtensionId));
    619 
    620   // Install the policy again. It should overwrite the extension's location,
    621   // and force enable it too.
    622   {
    623     DictionaryPrefUpdate pref_update(prefs, prefs::kExtensionInstallForceList);
    624     base::DictionaryValue* forcelist = pref_update.Get();
    625     extensions::ExternalPolicyLoader::AddExtension(
    626         forcelist, kExtensionId, "http://localhost/autoupdate/manifest");
    627   }
    628   ASSERT_TRUE(WaitForExtensionInstall());
    629   ASSERT_EQ(size_before + 1, service->extensions()->size());
    630   extension = service->GetExtensionById(kExtensionId, false);
    631   ASSERT_TRUE(extension);
    632   EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
    633   EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
    634   EXPECT_TRUE(service->disabled_extensions()->is_empty());
    635 }
    636