management_browsertest.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
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/extensions/extension_browsertest.h"
12#include "chrome/browser/extensions/extension_service.h"
13#include "chrome/browser/extensions/extension_test_message_listener.h"
14#include "chrome/browser/extensions/external_policy_loader.h"
15#include "chrome/browser/extensions/updater/extension_downloader.h"
16#include "chrome/browser/extensions/updater/extension_updater.h"
17#include "chrome/browser/profiles/profile.h"
18#include "chrome/browser/ui/browser.h"
19#include "chrome/common/pref_names.h"
20#include "chrome/common/url_constants.h"
21#include "chrome/test/base/ui_test_utils.h"
22#include "content/public/browser/notification_service.h"
23#include "content/public/browser/render_view_host.h"
24#include "content/public/test/browser_test_utils.h"
25#include "content/test/net/url_request_prepackaged_interceptor.h"
26#include "extensions/browser/extension_host.h"
27#include "extensions/browser/extension_prefs.h"
28#include "extensions/browser/extension_registry.h"
29#include "extensions/browser/extension_system.h"
30#include "extensions/browser/notification_types.h"
31#include "extensions/browser/pref_names.h"
32#include "net/url_request/url_fetcher.h"
33
34using extensions::Extension;
35using extensions::ExtensionRegistry;
36using extensions::Manifest;
37
38class 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.
84IN_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
101IN_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
110IN_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
127IN_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.
144IN_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.
174class NotificationListener : public content::NotificationObserver {
175 public:
176  NotificationListener() : started_(false), finished_(false) {
177    int types[] = {extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED,
178                   extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND};
179    for (size_t i = 0; i < arraysize(types); i++) {
180      registrar_.Add(
181          this, types[i], content::NotificationService::AllSources());
182    }
183  }
184  virtual ~NotificationListener() {}
185
186  bool started() { return started_; }
187
188  bool finished() { return finished_; }
189
190  const std::set<std::string>& updates() { return updates_; }
191
192  void Reset() {
193    started_ = false;
194    finished_ = false;
195    updates_.clear();
196  }
197
198  // Implements content::NotificationObserver interface.
199  virtual void Observe(int type,
200                       const content::NotificationSource& source,
201                       const content::NotificationDetails& details) OVERRIDE {
202    switch (type) {
203      case extensions::NOTIFICATION_EXTENSION_UPDATING_STARTED: {
204        EXPECT_FALSE(started_);
205        started_ = true;
206        break;
207      }
208      case extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND: {
209        const std::string& id =
210            content::Details<extensions::UpdateDetails>(details)->id;
211        updates_.insert(id);
212        break;
213      }
214      default:
215        NOTREACHED();
216    }
217  }
218
219  void OnFinished() {
220    EXPECT_FALSE(finished_);
221    finished_ = true;
222  }
223
224 private:
225  content::NotificationRegistrar registrar_;
226
227  // Did we see EXTENSION_UPDATING_STARTED?
228  bool started_;
229
230  // Did we see EXTENSION_UPDATING_FINISHED?
231  bool finished_;
232
233  // The set of extension id's we've seen via EXTENSION_UPDATE_FOUND.
234  std::set<std::string> updates_;
235};
236
237#if defined(OS_WIN)
238// Fails consistently on Windows XP, see: http://crbug.com/120640.
239#define MAYBE_AutoUpdate DISABLED_AutoUpdate
240#else
241// See http://crbug.com/103371 and http://crbug.com/120640.
242#if defined(ADDRESS_SANITIZER)
243#define MAYBE_AutoUpdate DISABLED_AutoUpdate
244#else
245#define MAYBE_AutoUpdate AutoUpdate
246#endif
247#endif
248
249// Tests extension autoupdate.
250IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_AutoUpdate) {
251  NotificationListener notification_listener;
252  base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
253  // Note: This interceptor gets requests on the IO thread.
254  content::URLLocalHostRequestPrepackagedInterceptor interceptor;
255  net::URLFetcher::SetEnableInterceptionForTests(true);
256
257  interceptor.SetResponseIgnoreQuery(
258      GURL("http://localhost/autoupdate/manifest"),
259      basedir.AppendASCII("manifest_v2.xml"));
260  interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
261                                          basedir.AppendASCII("v2.crx"));
262
263  // Install version 1 of the extension.
264  ExtensionTestMessageListener listener1("v1 installed", false);
265  ExtensionService* service = extensions::ExtensionSystem::Get(
266      browser()->profile())->extension_service();
267  ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
268  const size_t size_before = registry->enabled_extensions().size();
269  ASSERT_TRUE(registry->disabled_extensions().is_empty());
270  const Extension* extension =
271      InstallExtension(basedir.AppendASCII("v1.crx"), 1);
272  ASSERT_TRUE(extension);
273  listener1.WaitUntilSatisfied();
274  ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
275  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id());
276  ASSERT_EQ("1.0", extension->VersionString());
277
278  extensions::ExtensionUpdater::CheckParams params;
279  params.callback =
280      base::Bind(&NotificationListener::OnFinished,
281                 base::Unretained(&notification_listener));
282
283  // Run autoupdate and make sure version 2 of the extension was installed.
284  ExtensionTestMessageListener listener2("v2 installed", false);
285  service->updater()->CheckNow(params);
286  ASSERT_TRUE(WaitForExtensionInstall());
287  listener2.WaitUntilSatisfied();
288  ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
289  extension = service->GetExtensionById(
290      "ogjcoiohnmldgjemafoockdghcjciccf", false);
291  ASSERT_TRUE(extension);
292  ASSERT_EQ("2.0", extension->VersionString());
293  ASSERT_TRUE(notification_listener.started());
294  ASSERT_TRUE(notification_listener.finished());
295  ASSERT_TRUE(ContainsKey(notification_listener.updates(),
296                          "ogjcoiohnmldgjemafoockdghcjciccf"));
297  notification_listener.Reset();
298
299  // Now try doing an update to version 3, which has been incorrectly
300  // signed. This should fail.
301  interceptor.SetResponseIgnoreQuery(
302      GURL("http://localhost/autoupdate/manifest"),
303      basedir.AppendASCII("manifest_v3.xml"));
304  interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v3.crx"),
305                                     basedir.AppendASCII("v3.crx"));
306
307  service->updater()->CheckNow(params);
308  ASSERT_TRUE(WaitForExtensionInstallError());
309  ASSERT_TRUE(notification_listener.started());
310  ASSERT_TRUE(notification_listener.finished());
311  ASSERT_TRUE(ContainsKey(notification_listener.updates(),
312                          "ogjcoiohnmldgjemafoockdghcjciccf"));
313
314  // Make sure the extension state is the same as before.
315  ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
316  extension = service->GetExtensionById(
317      "ogjcoiohnmldgjemafoockdghcjciccf", false);
318  ASSERT_TRUE(extension);
319  ASSERT_EQ("2.0", extension->VersionString());
320}
321
322#if defined(OS_WIN)
323// Fails consistently on Windows XP, see: http://crbug.com/120640.
324#define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions
325#else
326#if defined(ADDRESS_SANITIZER)
327#define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions
328#else
329#define MAYBE_AutoUpdateDisabledExtensions AutoUpdateDisabledExtensions
330#endif
331#endif
332
333// Tests extension autoupdate.
334IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,
335                       MAYBE_AutoUpdateDisabledExtensions) {
336  NotificationListener notification_listener;
337  base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
338  // Note: This interceptor gets requests on the IO thread.
339  content::URLLocalHostRequestPrepackagedInterceptor interceptor;
340  net::URLFetcher::SetEnableInterceptionForTests(true);
341
342  interceptor.SetResponseIgnoreQuery(
343      GURL("http://localhost/autoupdate/manifest"),
344      basedir.AppendASCII("manifest_v2.xml"));
345  interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
346                                     basedir.AppendASCII("v2.crx"));
347
348  // Install version 1 of the extension.
349  ExtensionTestMessageListener listener1("v1 installed", false);
350  ExtensionService* service = extensions::ExtensionSystem::Get(
351      browser()->profile())->extension_service();
352  ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
353  const size_t enabled_size_before = registry->enabled_extensions().size();
354  const size_t disabled_size_before = registry->disabled_extensions().size();
355  const Extension* extension =
356      InstallExtension(basedir.AppendASCII("v1.crx"), 1);
357  ASSERT_TRUE(extension);
358  listener1.WaitUntilSatisfied();
359  DisableExtension(extension->id());
360  ASSERT_EQ(disabled_size_before + 1, registry->disabled_extensions().size());
361  ASSERT_EQ(enabled_size_before, registry->enabled_extensions().size());
362  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id());
363  ASSERT_EQ("1.0", extension->VersionString());
364
365  extensions::ExtensionUpdater::CheckParams params;
366  params.callback =
367      base::Bind(&NotificationListener::OnFinished,
368                 base::Unretained(&notification_listener));
369
370  ExtensionTestMessageListener listener2("v2 installed", false);
371  // Run autoupdate and make sure version 2 of the extension was installed but
372  // is still disabled.
373  service->updater()->CheckNow(params);
374  ASSERT_TRUE(WaitForExtensionInstall());
375  ASSERT_EQ(disabled_size_before + 1, registry->disabled_extensions().size());
376  ASSERT_EQ(enabled_size_before, registry->enabled_extensions().size());
377  extension = service->GetExtensionById(
378      "ogjcoiohnmldgjemafoockdghcjciccf", true);
379  ASSERT_TRUE(extension);
380  ASSERT_FALSE(service->GetExtensionById(
381      "ogjcoiohnmldgjemafoockdghcjciccf", false));
382  ASSERT_EQ("2.0", extension->VersionString());
383
384  // The extension should have not made the callback because it is disabled.
385  // When we enabled it, it should then make the callback.
386  ASSERT_FALSE(listener2.was_satisfied());
387  EnableExtension(extension->id());
388  listener2.WaitUntilSatisfied();
389  ASSERT_TRUE(notification_listener.started());
390  ASSERT_TRUE(notification_listener.finished());
391  ASSERT_TRUE(ContainsKey(notification_listener.updates(),
392                          "ogjcoiohnmldgjemafoockdghcjciccf"));
393  notification_listener.Reset();
394}
395
396IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) {
397  ExtensionService* service = extensions::ExtensionSystem::Get(
398      browser()->profile())->extension_service();
399  const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
400  extensions::ExtensionUpdater::CheckParams params;
401
402  base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
403
404  // Note: This interceptor gets requests on the IO thread.
405  content::URLLocalHostRequestPrepackagedInterceptor interceptor;
406  net::URLFetcher::SetEnableInterceptionForTests(true);
407
408  interceptor.SetResponseIgnoreQuery(
409      GURL("http://localhost/autoupdate/manifest"),
410      basedir.AppendASCII("manifest_v2.xml"));
411  interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
412                                     basedir.AppendASCII("v2.crx"));
413
414  ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
415  const size_t size_before = registry->enabled_extensions().size();
416  ASSERT_TRUE(registry->disabled_extensions().is_empty());
417
418  extensions::PendingExtensionManager* pending_extension_manager =
419      service->pending_extension_manager();
420
421  // The code that reads external_extensions.json uses this method to inform
422  // the ExtensionService of an extension to download.  Using the real code
423  // is race-prone, because instantating the ExtensionService starts a read
424  // of external_extensions.json before this test function starts.
425
426  EXPECT_TRUE(pending_extension_manager->AddFromExternalUpdateUrl(
427      kExtensionId,
428      std::string(),
429      GURL("http://localhost/autoupdate/manifest"),
430      Manifest::EXTERNAL_PREF_DOWNLOAD,
431      Extension::NO_FLAGS,
432      false));
433
434  // Run autoupdate and make sure version 2 of the extension was installed.
435  service->updater()->CheckNow(params);
436  ASSERT_TRUE(WaitForExtensionInstall());
437  ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
438  const Extension* extension = service->GetExtensionById(kExtensionId, false);
439  ASSERT_TRUE(extension);
440  ASSERT_EQ("2.0", extension->VersionString());
441
442  // Uninstalling the extension should set a pref that keeps the extension from
443  // being installed again the next time external_extensions.json is read.
444
445  UninstallExtension(kExtensionId);
446
447  extensions::ExtensionPrefs* extension_prefs =
448      extensions::ExtensionPrefs::Get(browser()->profile());
449  EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
450      << "Uninstalling should set kill bit on externaly installed extension.";
451
452  // Try to install the extension again from an external source. It should fail
453  // because of the killbit.
454  EXPECT_FALSE(pending_extension_manager->AddFromExternalUpdateUrl(
455      kExtensionId,
456      std::string(),
457      GURL("http://localhost/autoupdate/manifest"),
458      Manifest::EXTERNAL_PREF_DOWNLOAD,
459      Extension::NO_FLAGS,
460      false));
461  EXPECT_FALSE(pending_extension_manager->IsIdPending(kExtensionId))
462      << "External reinstall of a killed extension shouldn't work.";
463  EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
464      << "External reinstall of a killed extension should leave it killed.";
465
466  // Installing from non-external source.
467  ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
468
469  EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
470      << "Reinstalling should clear the kill bit.";
471
472  // Uninstalling from a non-external source should not set the kill bit.
473  UninstallExtension(kExtensionId);
474
475  EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
476      << "Uninstalling non-external extension should not set kill bit.";
477}
478
479namespace {
480
481const char* kForceInstallNotEmptyHelp =
482    "A policy may already be controlling the list of force-installed "
483    "extensions. Please remove all policy settings from your computer "
484    "before running tests. E.g. from /etc/chromium/policies Linux or "
485    "from the registry on Windows, etc.";
486
487}
488
489// See http://crbug.com/57378 for flakiness details.
490IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) {
491  ExtensionService* service = extensions::ExtensionSystem::Get(
492      browser()->profile())->extension_service();
493  const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
494
495  base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
496
497  // Note: This interceptor gets requests on the IO thread.
498  content::URLLocalHostRequestPrepackagedInterceptor interceptor;
499  net::URLFetcher::SetEnableInterceptionForTests(true);
500
501  interceptor.SetResponseIgnoreQuery(
502      GURL("http://localhost/autoupdate/manifest"),
503      basedir.AppendASCII("manifest_v2.xml"));
504  interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
505                                     basedir.AppendASCII("v2.crx"));
506
507  ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
508  const size_t size_before = registry->enabled_extensions().size();
509  ASSERT_TRUE(registry->disabled_extensions().is_empty());
510
511  PrefService* prefs = browser()->profile()->GetPrefs();
512  const base::DictionaryValue* forcelist =
513      prefs->GetDictionary(extensions::pref_names::kInstallForceList);
514  ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp;
515
516  {
517    // Set the policy as a user preference and fire notification observers.
518    DictionaryPrefUpdate pref_update(prefs,
519                                     extensions::pref_names::kInstallForceList);
520    base::DictionaryValue* forcelist = pref_update.Get();
521    extensions::ExternalPolicyLoader::AddExtension(
522        forcelist, kExtensionId, "http://localhost/autoupdate/manifest");
523  }
524
525  // Check if the extension got installed.
526  ASSERT_TRUE(WaitForExtensionInstall());
527  ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
528  const Extension* extension = service->GetExtensionById(kExtensionId, false);
529  ASSERT_TRUE(extension);
530  ASSERT_EQ("2.0", extension->VersionString());
531  EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
532
533  // Try to disable and uninstall the extension which should fail.
534  DisableExtension(kExtensionId);
535  EXPECT_EQ(size_before + 1, registry->enabled_extensions().size());
536  EXPECT_EQ(0u, registry->disabled_extensions().size());
537  UninstallExtension(kExtensionId);
538  EXPECT_EQ(size_before + 1, registry->enabled_extensions().size());
539  EXPECT_EQ(0u, registry->disabled_extensions().size());
540
541  // Now try to disable it through the management api, again failing.
542  ExtensionTestMessageListener listener1("ready", false);
543  ASSERT_TRUE(LoadExtension(
544      test_data_dir_.AppendASCII("management/uninstall_extension")));
545  ASSERT_TRUE(listener1.WaitUntilSatisfied());
546  EXPECT_EQ(size_before + 2, registry->enabled_extensions().size());
547  EXPECT_EQ(0u, registry->disabled_extensions().size());
548
549  // Check that emptying the list triggers uninstall.
550  prefs->ClearPref(extensions::pref_names::kInstallForceList);
551  EXPECT_EQ(size_before + 1, registry->enabled_extensions().size());
552  EXPECT_FALSE(service->GetExtensionById(kExtensionId, true));
553}
554
555// See http://crbug.com/103371 and http://crbug.com/120640.
556#if defined(ADDRESS_SANITIZER) || defined(OS_WIN)
557#define MAYBE_PolicyOverridesUserInstall DISABLED_PolicyOverridesUserInstall
558#else
559#define MAYBE_PolicyOverridesUserInstall PolicyOverridesUserInstall
560#endif
561
562IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,
563                       MAYBE_PolicyOverridesUserInstall) {
564  ExtensionService* service = extensions::ExtensionSystem::Get(
565      browser()->profile())->extension_service();
566  ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile());
567  const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
568  extensions::ExtensionUpdater::CheckParams params;
569  service->updater()->set_default_check_params(params);
570  const size_t size_before = registry->enabled_extensions().size();
571  base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
572  ASSERT_TRUE(registry->disabled_extensions().is_empty());
573
574  // Note: This interceptor gets requests on the IO thread.
575  content::URLLocalHostRequestPrepackagedInterceptor interceptor;
576  net::URLFetcher::SetEnableInterceptionForTests(true);
577
578  interceptor.SetResponseIgnoreQuery(
579      GURL("http://localhost/autoupdate/manifest"),
580      basedir.AppendASCII("manifest_v2.xml"));
581  interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
582                                     basedir.AppendASCII("v2.crx"));
583
584  // Check that the policy is initially empty.
585  PrefService* prefs = browser()->profile()->GetPrefs();
586  const base::DictionaryValue* forcelist =
587      prefs->GetDictionary(extensions::pref_names::kInstallForceList);
588  ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp;
589
590  // User install of the extension.
591  ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
592  ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
593  const Extension* extension = service->GetExtensionById(kExtensionId, false);
594  ASSERT_TRUE(extension);
595  EXPECT_EQ(Manifest::INTERNAL, extension->location());
596  EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
597
598  // Setup the force install policy. It should override the location.
599  {
600    DictionaryPrefUpdate pref_update(prefs,
601                                     extensions::pref_names::kInstallForceList);
602    extensions::ExternalPolicyLoader::AddExtension(
603        pref_update.Get(), kExtensionId,
604        "http://localhost/autoupdate/manifest");
605  }
606  ASSERT_TRUE(WaitForExtensionInstall());
607  ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
608  extension = service->GetExtensionById(kExtensionId, false);
609  ASSERT_TRUE(extension);
610  EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
611  EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
612
613  // Remove the policy, and verify that the extension was uninstalled.
614  // TODO(joaodasilva): it would be nicer if the extension was kept instead,
615  // and reverted location to INTERNAL or whatever it was before the policy
616  // was applied.
617  prefs->ClearPref(extensions::pref_names::kInstallForceList);
618  ASSERT_EQ(size_before, registry->enabled_extensions().size());
619  extension = service->GetExtensionById(kExtensionId, true);
620  EXPECT_FALSE(extension);
621
622  // User install again, but have it disabled too before setting the policy.
623  ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
624  ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
625  extension = service->GetExtensionById(kExtensionId, false);
626  ASSERT_TRUE(extension);
627  EXPECT_EQ(Manifest::INTERNAL, extension->location());
628  EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
629  EXPECT_TRUE(registry->disabled_extensions().is_empty());
630
631  DisableExtension(kExtensionId);
632  EXPECT_EQ(1u, registry->disabled_extensions().size());
633  extension = service->GetExtensionById(kExtensionId, true);
634  EXPECT_TRUE(extension);
635  EXPECT_FALSE(service->IsExtensionEnabled(kExtensionId));
636
637  // Install the policy again. It should overwrite the extension's location,
638  // and force enable it too.
639  {
640    DictionaryPrefUpdate pref_update(prefs,
641                                     extensions::pref_names::kInstallForceList);
642    base::DictionaryValue* forcelist = pref_update.Get();
643    extensions::ExternalPolicyLoader::AddExtension(
644        forcelist, kExtensionId, "http://localhost/autoupdate/manifest");
645  }
646  ASSERT_TRUE(WaitForExtensionInstall());
647  ASSERT_EQ(size_before + 1, registry->enabled_extensions().size());
648  extension = service->GetExtensionById(kExtensionId, false);
649  ASSERT_TRUE(extension);
650  EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
651  EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
652  EXPECT_TRUE(registry->disabled_extensions().is_empty());
653}
654