management_browsertest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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
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[] = {
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.
252IN_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.
336IN_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
398IN_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
481namespace {
482
483const 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.
492IN_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
564IN_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