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