management_browsertest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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/stl_util.h"
10#include "chrome/browser/extensions/extension_browsertest.h"
11#include "chrome/browser/extensions/extension_host.h"
12#include "chrome/browser/extensions/extension_service.h"
13#include "chrome/browser/extensions/extension_system.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/prefs/scoped_user_pref_update.h"
19#include "chrome/browser/profiles/profile.h"
20#include "chrome/browser/ui/browser.h"
21#include "chrome/common/chrome_notification_types.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    ExtensionProcessManager* 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  ExtensionProcessManager* 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  // We don't want autoupdate blacklist checks.
277  extensions::ExtensionUpdater::CheckParams params;
278  params.check_blacklist = false;
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, service->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, service->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  const size_t enabled_size_before = service->extensions()->size();
353  const size_t disabled_size_before = service->disabled_extensions()->size();
354  const Extension* extension =
355      InstallExtension(basedir.AppendASCII("v1.crx"), 1);
356  ASSERT_TRUE(extension);
357  listener1.WaitUntilSatisfied();
358  DisableExtension(extension->id());
359  ASSERT_EQ(disabled_size_before + 1, service->disabled_extensions()->size());
360  ASSERT_EQ(enabled_size_before, service->extensions()->size());
361  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id());
362  ASSERT_EQ("1.0", extension->VersionString());
363
364  // We don't want autoupdate blacklist checks.
365  extensions::ExtensionUpdater::CheckParams params;
366  params.check_blacklist = false;
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, service->disabled_extensions()->size());
377  ASSERT_EQ(enabled_size_before, service->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
397// TODO(linux_aura) http://crbug.com/163931
398#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)
399#define MAYBE_ExternalUrlUpdate DISABLED_ExternalUrlUpdate
400#else
401#define MAYBE_ExternalUrlUpdate ExternalUrlUpdate
402#endif
403
404IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_ExternalUrlUpdate) {
405  ExtensionService* service = extensions::ExtensionSystem::Get(
406      browser()->profile())->extension_service();
407  const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
408  // We don't want autoupdate blacklist checks.
409  extensions::ExtensionUpdater::CheckParams params;
410  params.check_blacklist = false;
411
412  base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
413
414  // Note: This interceptor gets requests on the IO thread.
415  content::URLLocalHostRequestPrepackagedInterceptor interceptor;
416  net::URLFetcher::SetEnableInterceptionForTests(true);
417
418  interceptor.SetResponseIgnoreQuery(
419      GURL("http://localhost/autoupdate/manifest"),
420      basedir.AppendASCII("manifest_v2.xml"));
421  interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
422                                     basedir.AppendASCII("v2.crx"));
423
424  const size_t size_before = service->extensions()->size();
425  ASSERT_TRUE(service->disabled_extensions()->is_empty());
426
427  extensions::PendingExtensionManager* pending_extension_manager =
428      service->pending_extension_manager();
429
430  // The code that reads external_extensions.json uses this method to inform
431  // the ExtensionService of an extension to download.  Using the real code
432  // is race-prone, because instantating the ExtensionService starts a read
433  // of external_extensions.json before this test function starts.
434
435  EXPECT_TRUE(pending_extension_manager->AddFromExternalUpdateUrl(
436      kExtensionId, GURL("http://localhost/autoupdate/manifest"),
437      Manifest::EXTERNAL_PREF_DOWNLOAD));
438
439  // Run autoupdate and make sure version 2 of the extension was installed.
440  service->updater()->CheckNow(params);
441  ASSERT_TRUE(WaitForExtensionInstall());
442  ASSERT_EQ(size_before + 1, service->extensions()->size());
443  const Extension* extension = service->GetExtensionById(kExtensionId, false);
444  ASSERT_TRUE(extension);
445  ASSERT_EQ("2.0", extension->VersionString());
446
447  // Uninstalling the extension should set a pref that keeps the extension from
448  // being installed again the next time external_extensions.json is read.
449
450  UninstallExtension(kExtensionId);
451
452  extensions::ExtensionPrefs* extension_prefs = service->extension_prefs();
453  EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
454      << "Uninstalling should set kill bit on externaly installed extension.";
455
456  // Try to install the extension again from an external source. It should fail
457  // because of the killbit.
458  EXPECT_FALSE(pending_extension_manager->AddFromExternalUpdateUrl(
459      kExtensionId, GURL("http://localhost/autoupdate/manifest"),
460      Manifest::EXTERNAL_PREF_DOWNLOAD));
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  // We don't want autoupdate blacklist checks.
495  extensions::ExtensionUpdater::CheckParams params;
496  params.check_blacklist = false;
497
498  base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
499
500  // Note: This interceptor gets requests on the IO thread.
501  content::URLLocalHostRequestPrepackagedInterceptor interceptor;
502  net::URLFetcher::SetEnableInterceptionForTests(true);
503
504  interceptor.SetResponseIgnoreQuery(
505      GURL("http://localhost/autoupdate/manifest"),
506      basedir.AppendASCII("manifest_v2.xml"));
507  interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
508                                     basedir.AppendASCII("v2.crx"));
509
510  const size_t size_before = service->extensions()->size();
511  ASSERT_TRUE(service->disabled_extensions()->is_empty());
512
513  PrefService* prefs = browser()->profile()->GetPrefs();
514  const base::DictionaryValue* forcelist =
515      prefs->GetDictionary(prefs::kExtensionInstallForceList);
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, prefs::kExtensionInstallForceList);
521    base::DictionaryValue* forcelist = pref_update.Get();
522    extensions::ExternalPolicyLoader::AddExtension(
523        forcelist, kExtensionId, "http://localhost/autoupdate/manifest");
524  }
525
526  // Check if the extension got installed.
527  ASSERT_TRUE(WaitForExtensionInstall());
528  ASSERT_EQ(size_before + 1, service->extensions()->size());
529  const Extension* extension = service->GetExtensionById(kExtensionId, false);
530  ASSERT_TRUE(extension);
531  ASSERT_EQ("2.0", extension->VersionString());
532  EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
533
534  // Try to disable and uninstall the extension which should fail.
535  DisableExtension(kExtensionId);
536  EXPECT_EQ(size_before + 1, service->extensions()->size());
537  EXPECT_EQ(0u, service->disabled_extensions()->size());
538  UninstallExtension(kExtensionId);
539  EXPECT_EQ(size_before + 1, service->extensions()->size());
540  EXPECT_EQ(0u, service->disabled_extensions()->size());
541
542  // Now try to disable it through the management api, again failing.
543  ExtensionTestMessageListener listener1("ready", false);
544  ASSERT_TRUE(LoadExtension(
545      test_data_dir_.AppendASCII("management/uninstall_extension")));
546  ASSERT_TRUE(listener1.WaitUntilSatisfied());
547  EXPECT_EQ(size_before + 2, service->extensions()->size());
548  EXPECT_EQ(0u, service->disabled_extensions()->size());
549
550  // Check that emptying the list triggers uninstall.
551  prefs->ClearPref(prefs::kExtensionInstallForceList);
552  EXPECT_EQ(size_before + 1, service->extensions()->size());
553  EXPECT_FALSE(service->GetExtensionById(kExtensionId, true));
554}
555
556// See http://crbug.com/103371 and http://crbug.com/120640.
557#if defined(ADDRESS_SANITIZER) || defined(OS_WIN)
558#define MAYBE_PolicyOverridesUserInstall DISABLED_PolicyOverridesUserInstall
559#else
560#define MAYBE_PolicyOverridesUserInstall PolicyOverridesUserInstall
561#endif
562
563IN_PROC_BROWSER_TEST_F(ExtensionManagementTest,
564                       MAYBE_PolicyOverridesUserInstall) {
565  ExtensionService* service = extensions::ExtensionSystem::Get(
566      browser()->profile())->extension_service();
567  const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
568  extensions::ExtensionUpdater::CheckParams params;
569  params.check_blacklist = false;
570  service->updater()->set_default_check_params(params);
571  const size_t size_before = service->extensions()->size();
572  base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
573  ASSERT_TRUE(service->disabled_extensions()->is_empty());
574
575  // Note: This interceptor gets requests on the IO thread.
576  content::URLLocalHostRequestPrepackagedInterceptor interceptor;
577  net::URLFetcher::SetEnableInterceptionForTests(true);
578
579  interceptor.SetResponseIgnoreQuery(
580      GURL("http://localhost/autoupdate/manifest"),
581      basedir.AppendASCII("manifest_v2.xml"));
582  interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"),
583                                     basedir.AppendASCII("v2.crx"));
584
585  // Check that the policy is initially empty.
586  PrefService* prefs = browser()->profile()->GetPrefs();
587  const base::DictionaryValue* forcelist =
588      prefs->GetDictionary(prefs::kExtensionInstallForceList);
589  ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp;
590
591  // User install of the extension.
592  ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
593  ASSERT_EQ(size_before + 1, service->extensions()->size());
594  const Extension* extension = service->GetExtensionById(kExtensionId, false);
595  ASSERT_TRUE(extension);
596  EXPECT_EQ(Manifest::INTERNAL, extension->location());
597  EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
598
599  // Setup the force install policy. It should override the location.
600  {
601    DictionaryPrefUpdate pref_update(prefs, prefs::kExtensionInstallForceList);
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, service->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(prefs::kExtensionInstallForceList);
618  ASSERT_EQ(size_before, service->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, service->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(service->disabled_extensions()->is_empty());
630
631  DisableExtension(kExtensionId);
632  EXPECT_EQ(1u, service->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, prefs::kExtensionInstallForceList);
641    base::DictionaryValue* forcelist = pref_update.Get();
642    extensions::ExternalPolicyLoader::AddExtension(
643        forcelist, kExtensionId, "http://localhost/autoupdate/manifest");
644  }
645  ASSERT_TRUE(WaitForExtensionInstall());
646  ASSERT_EQ(size_before + 1, service->extensions()->size());
647  extension = service->GetExtensionById(kExtensionId, false);
648  ASSERT_TRUE(extension);
649  EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location());
650  EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId));
651  EXPECT_TRUE(service->disabled_extensions()->is_empty());
652}
653