172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h"
6ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/stl_util-inl.h"
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/autoupdate_interceptor.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_browsertest.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/extensions/extension_service.h"
113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/extensions/extension_test_message_listener.h"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_updater.h"
13201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/browser/prefs/pref_service.h"
14dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/prefs/scoped_user_pref_update.h"
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "chrome/browser/profiles/profile.h"
164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch#include "chrome/browser/ui/browser.h"
17201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch#include "chrome/common/pref_names.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/test/ui_test_utils.h"
20dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "content/browser/renderer_host/render_view_host.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass ExtensionManagementTest : public ExtensionBrowserTest {
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helper method that returns whether the extension is at the given version.
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // This calls version(), which must be defined in the extension's bg page,
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // as well as asking the extension itself.
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note that 'version' here means something different than the version field
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // in the extension's manifest. We use the version as reported by the
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // background page to test how overinstalling crx files with the same
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // manifest version works.
32513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  bool IsExtensionAtVersion(const Extension* extension,
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            const std::string& expected_version) {
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Test that the extension's version from the manifest and reported by the
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // background page is correct.  This is to ensure that the processes are in
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // sync with the Extension.
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionProcessManager* manager = browser()->profile()->
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        GetExtensionProcessManager();
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionHost* ext_host = manager->GetBackgroundHostForExtension(extension);
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(ext_host);
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!ext_host)
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string version_from_bg;
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool exec = ui_test_utils::ExecuteJavaScriptAndExtractString(
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ext_host->render_view_host(), L"", L"version()", &version_from_bg);
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(exec);
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!exec)
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (version_from_bg != expected_version ||
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        extension->VersionString() != expected_version)
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Helper method that installs a low permission extension then updates
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // to the second version requiring increased permissions. Returns whether
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // the operation was completed successfully.
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool InstallAndUpdateIncreasingPermissionsExtension() {
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ExtensionService* service = browser()->profile()->GetExtensionService();
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    size_t size_before = service->extensions()->size();
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Install the initial version, which should happen just fine.
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!InstallExtension(
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        test_data_dir_.AppendASCII("permissions-low-v1.crx"), 1))
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Upgrade to a version that wants more permissions. We should disable the
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // extension and prompt the user to reenable.
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (service->extensions()->size() != size_before + 1)
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!UpdateExtension(
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        service->extensions()->at(size_before)->id(),
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        test_data_dir_.AppendASCII("permissions-high-v2.crx"), -1))
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(size_before, service->extensions()->size());
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (service->disabled_extensions()->size() != 1u)
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return false;
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return true;
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that installing the same version overwrites.
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallSameVersion) {
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = browser()->profile()->GetExtensionService();
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const size_t size_before = service->extensions()->size();
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(InstallExtension(
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      test_data_dir_.AppendASCII("install/install.crx"), 1));
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath old_path = service->extensions()->back()->path();
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Install an extension with the same version. The previous install should be
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // overwritten.
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(InstallExtension(
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      test_data_dir_.AppendASCII("install/install_same_version.crx"), 0));
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath new_path = service->extensions()->back()->path();
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(IsExtensionAtVersion(service->extensions()->at(size_before),
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                    "1.0"));
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_NE(old_path.value(), new_path.value());
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallOlderVersion) {
10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = browser()->profile()->GetExtensionService();
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const size_t size_before = service->extensions()->size();
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(InstallExtension(
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      test_data_dir_.AppendASCII("install/install.crx"), 1));
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(InstallExtension(
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      test_data_dir_.AppendASCII("install/install_older_version.crx"), 0));
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(IsExtensionAtVersion(service->extensions()->at(size_before),
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   "1.0"));
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallThenCancel) {
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = browser()->profile()->GetExtensionService();
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const size_t size_before = service->extensions()->size();
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(InstallExtension(
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      test_data_dir_.AppendASCII("install/install.crx"), 1));
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Cancel this install.
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StartInstallButCancel(test_data_dir_.AppendASCII("install/install_v2.crx"));
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(IsExtensionAtVersion(service->extensions()->at(size_before),
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   "1.0"));
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that installing and uninstalling extensions don't crash with an
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// incognito window open.
128731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickIN_PROC_BROWSER_TEST_F(ExtensionManagementTest, Incognito) {
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Open an incognito window to the extensions management page.  We just
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // want to make sure that we don't crash while playing with extensions when
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // this guy is around.
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ui_test_utils::OpenURLOffTheRecord(browser()->profile(),
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     GURL(chrome::kChromeUIExtensionsURL));
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(InstallExtension(test_data_dir_.AppendASCII("good.crx"), 1));
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UninstallExtension("ldnnhddmnhbkjipkidpdiheffobcpfmf");
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests the process of updating an extension to one that requires higher
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// permissions.
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(ExtensionManagementTest, UpdatePermissions) {
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = browser()->profile()->GetExtensionService();
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(InstallAndUpdateIncreasingPermissionsExtension());
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const size_t size_before = service->extensions()->size();
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now try reenabling it.
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service->EnableExtension(service->disabled_extensions()->at(0)->id());
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(size_before + 1, service->extensions()->size());
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service->disabled_extensions()->size());
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that we can uninstall a disabled extension.
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(ExtensionManagementTest, UninstallDisabled) {
15421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = browser()->profile()->GetExtensionService();
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(InstallAndUpdateIncreasingPermissionsExtension());
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const size_t size_before = service->extensions()->size();
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now try uninstalling it.
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UninstallExtension(service->disabled_extensions()->at(0)->id());
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(size_before, service->extensions()->size());
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service->disabled_extensions()->size());
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests that disabling and re-enabling an extension works.
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DisableEnable) {
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionProcessManager* manager = browser()->profile()->
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetExtensionProcessManager();
16821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = browser()->profile()->GetExtensionService();
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const size_t size_before = service->extensions()->size();
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Load an extension, expect the background page to be available.
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(LoadExtension(
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      test_data_dir_.AppendASCII("good").AppendASCII("Extensions")
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    .AppendASCII("bjafgdebaacbbbecmhlhpofkepfkgcpa")
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                    .AppendASCII("1.0")));
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(size_before + 1, service->extensions()->size());
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service->disabled_extensions()->size());
178513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  const Extension* extension = service->extensions()->at(size_before);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension));
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // After disabling, the background page should go away.
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service->DisableExtension("bjafgdebaacbbbecmhlhpofkepfkgcpa");
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(size_before, service->extensions()->size());
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(1u, service->disabled_extensions()->size());
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_FALSE(manager->GetBackgroundHostForExtension(extension));
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // And bring it back.
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service->EnableExtension("bjafgdebaacbbbecmhlhpofkepfkgcpa");
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(size_before + 1, service->extensions()->size());
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_EQ(0u, service->disabled_extensions()->size());
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension));
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
194ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Used for testing notifications sent during extension updates.
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass NotificationListener : public NotificationObserver {
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public:
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NotificationListener() : started_(false), finished_(false) {
198ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    NotificationType::Type types[] = {
199ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NotificationType::EXTENSION_UPDATING_STARTED,
200ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NotificationType::EXTENSION_UPDATING_FINISHED,
201ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      NotificationType::EXTENSION_UPDATE_FOUND
202ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    };
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    for (size_t i = 0; i < arraysize(types); i++) {
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      registrar_.Add(this, types[i], NotificationService::AllSources());
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
206ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
207ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ~NotificationListener() {}
208ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
209ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool started() { return started_; }
210ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
211ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool finished() { return finished_; }
212ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
213ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  const std::set<std::string>& updates() { return updates_; }
214ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
215ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void Reset() {
216ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    started_ = false;
217ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    finished_ = false;
218ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    updates_.clear();
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
221ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Implements NotificationObserver interface.
222ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  virtual void Observe(NotificationType type,
223ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       const NotificationSource& source,
224ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       const NotificationDetails& details) {
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    switch (type.value) {
226ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case NotificationType::EXTENSION_UPDATING_STARTED: {
227ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        DCHECK(!started_);
228ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        started_ = true;
229ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
230ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
231ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case NotificationType::EXTENSION_UPDATING_FINISHED: {
232ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        DCHECK(!finished_);
233ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        finished_ = true;
234ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
235ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
236ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      case NotificationType::EXTENSION_UPDATE_FOUND: {
237ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        const std::string* id = Details<const std::string>(details).ptr();
238ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        updates_.insert(*id);
239ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        break;
240ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      }
241ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      default:
242ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        NOTREACHED();
243ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
244ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
245ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
246ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen private:
247ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NotificationRegistrar registrar_;
248ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
249ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Did we see EXTENSION_UPDATING_STARTED?
250ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool started_;
251ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
252ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Did we see EXTENSION_UPDATING_FINISHED?
253ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  bool finished_;
254ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
255ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // The set of extension id's we've seen via EXTENSION_UPDATE_FOUND.
256ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  std::set<std::string> updates_;
257ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen};
258ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Tests extension autoupdate.
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochIN_PROC_BROWSER_TEST_F(ExtensionManagementTest, AutoUpdate) {
261ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  NotificationListener notification_listener;
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Note: This interceptor gets requests on the IO thread.
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<AutoUpdateInterceptor> interceptor(new AutoUpdateInterceptor());
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  URLFetcher::enable_interception_for_tests(true);
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest",
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     basedir.AppendASCII("manifest_v2.xml"));
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v2.crx",
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     basedir.AppendASCII("v2.crx"));
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Install version 1 of the extension.
273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ExtensionTestMessageListener listener1("v1 installed", false);
27421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = browser()->profile()->GetExtensionService();
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const size_t size_before = service->extensions()->size();
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(service->disabled_extensions()->empty());
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v1.crx"), 1));
2783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  listener1.WaitUntilSatisfied();
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ExtensionList* extensions = service->extensions();
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(size_before + 1, extensions->size());
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf",
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            extensions->at(size_before)->id());
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("1.0", extensions->at(size_before)->VersionString());
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We don't want autoupdate blacklist checks.
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service->updater()->set_blacklist_checks_enabled(false);
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Run autoupdate and make sure version 2 of the extension was installed.
289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  ExtensionTestMessageListener listener2("v2 installed", false);
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service->updater()->CheckNow();
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(WaitForExtensionInstall());
2923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  listener2.WaitUntilSatisfied();
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions = service->extensions();
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(size_before + 1, extensions->size());
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf",
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            extensions->at(size_before)->id());
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("2.0", extensions->at(size_before)->VersionString());
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(notification_listener.started());
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(notification_listener.finished());
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(ContainsKey(notification_listener.updates(),
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          "ogjcoiohnmldgjemafoockdghcjciccf"));
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  notification_listener.Reset();
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Now try doing an update to version 3, which has been incorrectly
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // signed. This should fail.
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest",
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     basedir.AppendASCII("manifest_v3.xml"));
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v3.crx",
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     basedir.AppendASCII("v3.crx"));
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  service->updater()->CheckNow();
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_TRUE(WaitForExtensionInstallError());
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(notification_listener.started());
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(notification_listener.finished());
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(ContainsKey(notification_listener.updates(),
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          "ogjcoiohnmldgjemafoockdghcjciccf"));
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Make sure the extension state is the same as before.
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions = service->extensions();
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ(size_before + 1, extensions->size());
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf",
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            extensions->at(size_before)->id());
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ASSERT_EQ("2.0", extensions->at(size_before)->VersionString());
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
3253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3263345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickIN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) {
32721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = browser()->profile()->GetExtensionService();
3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
3293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // We don't want autoupdate blacklist checks.
3303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  service->updater()->set_blacklist_checks_enabled(false);
3313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
3333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Note: This interceptor gets requests on the IO thread.
3353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  scoped_refptr<AutoUpdateInterceptor> interceptor(new AutoUpdateInterceptor());
3363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  URLFetcher::enable_interception_for_tests(true);
3373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest",
3393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     basedir.AppendASCII("manifest_v2.xml"));
3403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v2.crx",
3413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                     basedir.AppendASCII("v2.crx"));
3423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const size_t size_before = service->extensions()->size();
3443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(service->disabled_extensions()->empty());
3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
346ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PendingExtensionManager* pending_extension_manager =
347ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      service->pending_extension_manager();
348ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
3493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // The code that reads external_extensions.json uses this method to inform
35021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // the ExtensionService of an extension to download.  Using the real code
3513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // is race-prone, because instantating the ExtensionService starts a read
3523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // of external_extensions.json before this test function starts.
353ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
354ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  pending_extension_manager->AddFromExternalUpdateUrl(
355513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      kExtensionId, GURL("http://localhost/autoupdate/manifest"),
356513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch      Extension::EXTERNAL_PREF_DOWNLOAD);
3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Run autoupdate and make sure version 2 of the extension was installed.
3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  service->updater()->CheckNow();
3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(WaitForExtensionInstall());
3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const ExtensionList* extensions = service->extensions();
3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(size_before + 1, extensions->size());
3633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ(kExtensionId, extensions->at(size_before)->id());
3643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_EQ("2.0", extensions->at(size_before)->VersionString());
3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Uninstalling the extension should set a pref that keeps the extension from
3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // being installed again the next time external_extensions.json is read.
3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UninstallExtension(kExtensionId);
3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
37121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionPrefs* extension_prefs = service->extension_prefs();
372ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      << "Uninstalling should set kill bit on externaly installed extension.";
3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
37521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Try to install the extension again from an external source. It should fail
37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // because of the killbit.
377ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  pending_extension_manager->AddFromExternalUpdateUrl(
37821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      kExtensionId, GURL("http://localhost/autoupdate/manifest"),
37921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      Extension::EXTERNAL_PREF_DOWNLOAD);
380ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(pending_extension_manager->IsIdPending(kExtensionId))
38121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      << "External reinstall of a killed extension shouldn't work.";
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
38321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      << "External reinstall of a killed extension should leave it killed.";
38421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Installing from non-external source.
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1));
3873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
388ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      << "Reinstalling should clear the kill bit.";
3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Uninstalling from a non-external source should not set the kill bit.
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  UninstallExtension(kExtensionId);
3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
394ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId))
3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      << "Uninstalling non-external extension should not set kill bit.";
3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
397201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
398201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch// See http://crbug.com/57378 for flakiness details.
399201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben MurdochIN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) {
40021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ExtensionService* service = browser()->profile()->GetExtensionService();
401201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf";
402201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // We don't want autoupdate blacklist checks.
403201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  service->updater()->set_blacklist_checks_enabled(false);
404201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
405201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  FilePath basedir = test_data_dir_.AppendASCII("autoupdate");
406201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
407201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Note: This interceptor gets requests on the IO thread.
408201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  scoped_refptr<AutoUpdateInterceptor> interceptor(new AutoUpdateInterceptor());
409201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  URLFetcher::enable_interception_for_tests(true);
410201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
411201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/manifest",
412201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                     basedir.AppendASCII("manifest_v2.xml"));
413201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  interceptor->SetResponseOnIOThread("http://localhost/autoupdate/v2.crx",
414201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                     basedir.AppendASCII("v2.crx"));
415201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
416201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const size_t size_before = service->extensions()->size();
417201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(service->disabled_extensions()->empty());
418201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
419201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  PrefService* prefs = browser()->profile()->GetPrefs();
42021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  {
42121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    // Set the policy as a user preference and fire notification observers.
422ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListPrefUpdate pref_update(prefs, prefs::kExtensionInstallForceList);
423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ListValue* forcelist = pref_update.Get();
42421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    ASSERT_TRUE(forcelist->empty());
42521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    forcelist->Append(Value::CreateStringValue(
42672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        std::string(kExtensionId) +
42772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen        ";http://localhost/autoupdate/manifest"));
42821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
429201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
430201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  // Check if the extension got installed.
431201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_TRUE(WaitForExtensionInstall());
432201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  const ExtensionList* extensions = service->extensions();
433201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(size_before + 1, extensions->size());
434201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  ASSERT_EQ(kExtensionId, extensions->at(size_before)->id());
435201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ("2.0", extensions->at(size_before)->VersionString());
436201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch  EXPECT_EQ(Extension::EXTERNAL_POLICY_DOWNLOAD,
437201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch            extensions->at(size_before)->location());
438201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch
439ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Try to disable and unstall the extension which should fail.
440ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  service->DisableExtension(kExtensionId);
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(size_before + 1, service->extensions()->size());
442ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0u, service->disabled_extensions()->size());
443ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  UninstallExtension(kExtensionId);
444ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(size_before + 1, service->extensions()->size());
445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0u, service->disabled_extensions()->size());
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
447ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Now try to disable it through the management api.
448ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ExtensionTestMessageListener listener1("ready", false);
449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(LoadExtension(
450ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      test_data_dir_.AppendASCII("management/uninstall_extension")));
451ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ASSERT_TRUE(listener1.WaitUntilSatisfied());
452ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(size_before + 2, service->extensions()->size());
453ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(0u, service->disabled_extensions()->size());
454ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
45572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Check that emptying the list triggers uninstall.
45672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  {
45772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    prefs->ClearPref(prefs::kExtensionInstallForceList);
45872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_EQ(size_before + 1, extensions->size());
46072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ExtensionList::const_iterator i;
46172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  for (i = extensions->begin(); i != extensions->end(); ++i)
46272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    EXPECT_NE(kExtensionId, (*i)->id());
463201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch}
464