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