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_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.
     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.
     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 
    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 
    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
    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.
    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:
    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   }
    186   virtual ~NotificationListener() {}
    187 
    188   bool started() { return started_; }
    189 
    190   bool finished() { return finished_; }
    191 
    192   const std::set<std::string>& updates() { return updates_; }
    193 
    194   void Reset() {
    195     started_ = false;
    196     finished_ = false;
    197     updates_.clear();
    198   }
    199 
    200   // Implements content::NotificationObserver interface.
    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 
    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.
    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(&notification_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.
    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(&notification_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 
    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.
    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 
    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