blob: 105b4c686980899a738d5558821c4a46bb637ab2 [file] [log] [blame]
[email protected]35385332012-03-28 02:32:031// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]a01e00632010-11-05 16:58:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]f8636f92013-08-09 21:02:375#include "base/memory/ref_counted.h"
[email protected]bf2fcd52012-04-16 22:59:396#include "chrome/browser/download/download_crx_util.h"
[email protected]a01e00632010-11-05 16:58:147#include "chrome/browser/extensions/crx_installer.h"
8#include "chrome/browser/extensions/extension_browsertest.h"
[email protected]c82da8c42012-06-08 19:49:119#include "chrome/browser/extensions/extension_install_prompt.h"
[email protected]eaa7dd182010-12-14 11:09:0010#include "chrome/browser/extensions/extension_service.h"
[email protected]06bdd2b2012-11-30 18:47:1311#include "chrome/browser/extensions/extension_system.h"
[email protected]3f2a2fa2013-09-24 02:55:2512#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
[email protected]8ecad5e2010-12-02 21:18:3313#include "chrome/browser/profiles/profile.h"
[email protected]2ad4a902010-11-17 06:05:1314#include "chrome/browser/ui/browser.h"
[email protected]619f86182012-07-03 21:30:1815#include "chrome/browser/ui/browser_window.h"
[email protected]91e51d612012-10-21 23:03:0516#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]b70a2d92012-06-28 19:51:2117#include "chrome/common/extensions/extension.h"
[email protected]35385332012-03-28 02:32:0318#include "chrome/common/extensions/extension_file_util.h"
[email protected]544471a2012-10-13 05:27:0919#include "chrome/common/extensions/feature_switch.h"
[email protected]b70a2d92012-06-28 19:51:2120#include "chrome/common/extensions/permissions/permission_set.h"
[email protected]af44e7fb2011-07-29 18:32:3221#include "chrome/test/base/ui_test_utils.h"
[email protected]f34efa22013-03-05 19:14:2322#include "content/public/browser/download_manager.h"
[email protected]49b264f2012-08-14 17:12:2623#include "content/public/test/download_test_observer.h"
[email protected]c8d02992013-07-31 22:16:5124#include "extensions/common/switches.h"
[email protected]a9736892012-05-30 15:58:0525#include "grit/generated_resources.h"
26#include "ui/base/l10n/l10n_util.h"
[email protected]a01e00632010-11-05 16:58:1427
[email protected]7a5452f2010-12-13 23:03:1928class SkBitmap;
29
[email protected]bf3d9df2012-07-24 23:20:2730namespace extensions {
[email protected]b70a2d92012-06-28 19:51:2131
[email protected]a01e00632010-11-05 16:58:1432namespace {
33
[email protected]f8636f92013-08-09 21:02:3734class MockInstallPrompt;
35
36// This class holds information about things that happen with a
37// MockInstallPrompt. We create the MockInstallPrompt but need to pass
38// ownership of it to CrxInstaller, so it isn't safe to hang this data on
39// MockInstallPrompt itself becuase we can't guarantee it's lifetime.
40class MockPromptProxy :
41 public base::RefCountedThreadSafe<MockPromptProxy> {
42 public:
43 explicit MockPromptProxy(content::WebContents* web_contents);
44
45 bool did_succeed() const { return !extension_id_.empty(); }
46 const std::string& extension_id() { return extension_id_; }
47 bool confirmation_requested() const { return confirmation_requested_; }
48 const string16& error() const { return error_; }
49
50 // To have any effect, this should be called before CreatePrompt.
51 void set_record_oauth2_grant(bool record_oauth2_grant) {
52 record_oauth2_grant_.reset(new bool(record_oauth2_grant));
53 }
54
55 void set_extension_id(const std::string& id) { extension_id_ = id; }
56 void set_confirmation_requested() { confirmation_requested_ = true; }
57 void set_error(const string16& error) { error_ = error; }
58
59 scoped_ptr<ExtensionInstallPrompt> CreatePrompt();
60
61 private:
62 friend class base::RefCountedThreadSafe<MockPromptProxy>;
63 virtual ~MockPromptProxy();
64
65 // Data used to create a prompt.
66 content::WebContents* web_contents_;
67 scoped_ptr<bool> record_oauth2_grant_;
68
69 // Data reported back to us by the prompt we created.
70 bool confirmation_requested_;
71 std::string extension_id_;
72 string16 error_;
73};
[email protected]bf2fcd52012-04-16 22:59:3974
[email protected]c82da8c42012-06-08 19:49:1175class MockInstallPrompt : public ExtensionInstallPrompt {
[email protected]a01e00632010-11-05 16:58:1476 public:
[email protected]f8636f92013-08-09 21:02:3777 MockInstallPrompt(content::WebContents* web_contents,
78 MockPromptProxy* proxy) :
[email protected]91e51d612012-10-21 23:03:0579 ExtensionInstallPrompt(web_contents),
[email protected]f8636f92013-08-09 21:02:3780 proxy_(proxy) {}
[email protected]a01e00632010-11-05 16:58:1481
[email protected]b70a2d92012-06-28 19:51:2182 void set_record_oauth2_grant(bool record) { record_oauth2_grant_ = record; }
[email protected]a01e00632010-11-05 16:58:1483
84 // Overriding some of the ExtensionInstallUI API.
[email protected]49aeab62013-02-07 02:53:1185 virtual void ConfirmInstall(
86 Delegate* delegate,
87 const Extension* extension,
88 const ShowDialogCallback& show_dialog_callback) OVERRIDE {
[email protected]f8636f92013-08-09 21:02:3789 proxy_->set_confirmation_requested();
[email protected]a01e00632010-11-05 16:58:1490 delegate->InstallUIProceed();
91 }
[email protected]49aeab62013-02-07 02:53:1192 virtual void OnInstallSuccess(const Extension* extension,
93 SkBitmap* icon) OVERRIDE {
[email protected]f8636f92013-08-09 21:02:3794 proxy_->set_extension_id(extension->id());
[email protected]b3a25092013-05-28 22:08:1695 base::MessageLoopForUI::current()->Quit();
[email protected]a01e00632010-11-05 16:58:1496 }
[email protected]49aeab62013-02-07 02:53:1197 virtual void OnInstallFailure(const CrxInstallerError& error) OVERRIDE {
[email protected]f8636f92013-08-09 21:02:3798 proxy_->set_error(error.message());
[email protected]b3a25092013-05-28 22:08:1699 base::MessageLoopForUI::current()->Quit();
[email protected]a01e00632010-11-05 16:58:14100 }
101
102 private:
[email protected]f8636f92013-08-09 21:02:37103 scoped_refptr<MockPromptProxy> proxy_;
[email protected]a01e00632010-11-05 16:58:14104};
105
[email protected]f8636f92013-08-09 21:02:37106
107MockPromptProxy::MockPromptProxy(content::WebContents* web_contents) :
108 web_contents_(web_contents),
109 confirmation_requested_(false) {
110}
111
112MockPromptProxy::~MockPromptProxy() {}
113
114scoped_ptr<ExtensionInstallPrompt> MockPromptProxy::CreatePrompt() {
115 scoped_ptr<MockInstallPrompt> prompt(
116 new MockInstallPrompt(web_contents_, this));
117 if (record_oauth2_grant_.get())
118 prompt->set_record_oauth2_grant(*record_oauth2_grant_.get());
119 return prompt.PassAs<ExtensionInstallPrompt>();
120}
121
122
123scoped_refptr<MockPromptProxy> CreateMockPromptProxyForBrowser(
124 Browser* browser) {
125 return new MockPromptProxy(
[email protected]91e51d612012-10-21 23:03:05126 browser->tab_strip_model()->GetActiveWebContents());
[email protected]619f86182012-07-03 21:30:18127}
128
[email protected]a01e00632010-11-05 16:58:14129} // namespace
130
131class ExtensionCrxInstallerTest : public ExtensionBrowserTest {
132 public:
[email protected]85290822013-08-23 20:27:38133 scoped_ptr<WebstoreInstaller::Approval> GetApproval(
134 const char* manifest_dir,
[email protected]b70a2d92012-06-28 19:51:21135 const std::string& id,
[email protected]85290822013-08-23 20:27:38136 bool strict_manifest_checks) {
137 scoped_ptr<WebstoreInstaller::Approval> result;
138
139 base::FilePath ext_path = test_data_dir_.AppendASCII(manifest_dir);
140 std::string error;
141 scoped_ptr<base::DictionaryValue> parsed_manifest(
142 extension_file_util::LoadManifest(ext_path, &error));
143 if (!parsed_manifest.get() || !error.empty())
144 return result.Pass();
145
146 return WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
147 browser()->profile(),
148 id,
149 parsed_manifest.Pass(),
150 strict_manifest_checks);
151 }
152
153 void RunCrxInstaller(const WebstoreInstaller::Approval* approval,
154 scoped_ptr<ExtensionInstallPrompt> prompt,
155 const base::FilePath& crx_path) {
[email protected]06bdd2b2012-11-30 18:47:13156 ExtensionService* service = extensions::ExtensionSystem::Get(
157 browser()->profile())->extension_service();
[email protected]a01e00632010-11-05 16:58:14158 scoped_refptr<CrxInstaller> installer(
[email protected]85290822013-08-23 20:27:38159 CrxInstaller::Create(service, prompt.Pass(), approval));
[email protected]a01e00632010-11-05 16:58:14160 installer->set_allow_silent_install(true);
[email protected]b1f04cc2010-11-10 22:59:30161 installer->set_is_gallery_install(true);
[email protected]85290822013-08-23 20:27:38162 installer->InstallCrx(crx_path);
[email protected]729eb632012-07-26 04:45:26163 content::RunMessageLoop();
[email protected]85290822013-08-23 20:27:38164 }
165
166 // Installs a crx from |crx_relpath| (a path relative to the extension test
167 // data dir) with expected id |id|.
168 void InstallWithPrompt(const char* ext_relpath,
169 const std::string& id,
170 scoped_refptr<MockPromptProxy> mock_install_prompt) {
171 base::FilePath ext_path = test_data_dir_.AppendASCII(ext_relpath);
172
173 scoped_ptr<WebstoreInstaller::Approval> approval;
174 if (!id.empty())
175 approval = GetApproval(ext_relpath, id, true);
176
177 base::FilePath crx_path = PackExtension(ext_path);
178 EXPECT_FALSE(crx_path.empty());
179 RunCrxInstaller(approval.get(), mock_install_prompt->CreatePrompt(),
180 crx_path);
[email protected]a01e00632010-11-05 16:58:14181
[email protected]c82da8c42012-06-08 19:49:11182 EXPECT_TRUE(mock_install_prompt->did_succeed());
[email protected]b70a2d92012-06-28 19:51:21183 }
184
185 // Installs an extension and checks that it has scopes granted IFF
186 // |record_oauth2_grant| is true.
187 void CheckHasEmptyScopesAfterInstall(const std::string& ext_relpath,
188 bool record_oauth2_grant) {
189 CommandLine::ForCurrentProcess()->AppendSwitch(
190 switches::kEnableExperimentalExtensionApis);
191
[email protected]06bdd2b2012-11-30 18:47:13192 ExtensionService* service = extensions::ExtensionSystem::Get(
193 browser()->profile())->extension_service();
[email protected]b70a2d92012-06-28 19:51:21194
[email protected]f8636f92013-08-09 21:02:37195 scoped_refptr<MockPromptProxy> mock_prompt =
196 CreateMockPromptProxyForBrowser(browser());
197
[email protected]b70a2d92012-06-28 19:51:21198 mock_prompt->set_record_oauth2_grant(record_oauth2_grant);
[email protected]85290822013-08-23 20:27:38199 InstallWithPrompt("browsertest/scopes", std::string(), mock_prompt);
[email protected]b70a2d92012-06-28 19:51:21200
[email protected]bf3d9df2012-07-24 23:20:27201 scoped_refptr<PermissionSet> permissions =
[email protected]b70a2d92012-06-28 19:51:21202 service->extension_prefs()->GetGrantedPermissions(
[email protected]f8636f92013-08-09 21:02:37203 mock_prompt->extension_id());
[email protected]b70a2d92012-06-28 19:51:21204 ASSERT_TRUE(permissions.get());
[email protected]a01e00632010-11-05 16:58:14205 }
[email protected]9e9c1d12013-07-31 01:58:12206
207 // Creates and returns a popup ExtensionHost for an extension and waits
208 // for a url to load in the host's web contents.
209 // The caller is responsible for cleaning up the returned ExtensionHost.
210 ExtensionHost* OpenUrlInExtensionPopupHost(const Extension* extension,
211 const GURL& url) {
212 ExtensionSystem* extension_system = extensions::ExtensionSystem::Get(
213 browser()->profile());
214 ExtensionProcessManager* epm = extension_system->process_manager();
215 ExtensionHost* extension_host =
216 epm->CreatePopupHost(extension, url, browser());
217
218 extension_host->CreateRenderViewSoon();
219 if (!extension_host->IsRenderViewLive()) {
220 content::WindowedNotificationObserver observer(
221 content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME,
222 content::Source<content::WebContents>(
223 extension_host->host_contents()));
224 observer.Wait();
225 }
226
227 return extension_host;
228 }
[email protected]a01e00632010-11-05 16:58:14229};
230
[email protected]45dd1b4802012-06-05 23:07:59231#if defined(OS_CHROMEOS)
232#define MAYBE_Whitelisting DISABLED_Whitelisting
233#else
234#define MAYBE_Whitelisting Whitelisting
235#endif
236IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, MAYBE_Whitelisting) {
[email protected]21a5ad62012-04-03 04:48:45237 std::string id = "hdgllgikmikobbofgnabhfimcfoopgnd";
[email protected]06bdd2b2012-11-30 18:47:13238 ExtensionService* service = extensions::ExtensionSystem::Get(
239 browser()->profile())->extension_service();
[email protected]21a5ad62012-04-03 04:48:45240
241 // Even whitelisted extensions with NPAPI should not prompt.
[email protected]f8636f92013-08-09 21:02:37242 scoped_refptr<MockPromptProxy> mock_prompt =
243 CreateMockPromptProxyForBrowser(browser());
[email protected]85290822013-08-23 20:27:38244 InstallWithPrompt("uitest/plugins", id, mock_prompt);
[email protected]b70a2d92012-06-28 19:51:21245 EXPECT_FALSE(mock_prompt->confirmation_requested());
[email protected]21a5ad62012-04-03 04:48:45246 EXPECT_TRUE(service->GetExtensionById(id, false));
[email protected]a01e00632010-11-05 16:58:14247}
[email protected]fc38935a2011-10-31 23:53:28248
249IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
[email protected]240cc92a2011-12-01 01:22:24250 GalleryInstallGetsExperimental) {
251 // We must modify the command line temporarily in order to pack an extension
252 // that requests the experimental permission.
253 CommandLine* command_line = CommandLine::ForCurrentProcess();
254 CommandLine old_command_line = *command_line;
255 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
[email protected]650b2d52013-02-10 03:41:45256 base::FilePath crx_path = PackExtension(
[email protected]240cc92a2011-12-01 01:22:24257 test_data_dir_.AppendASCII("experimental"));
258 ASSERT_FALSE(crx_path.empty());
259
260 // Now reset the command line so that we are testing specifically whether
261 // installing from webstore enables experimental permissions.
262 *(CommandLine::ForCurrentProcess()) = old_command_line;
263
264 EXPECT_FALSE(InstallExtension(crx_path, 0));
265 EXPECT_TRUE(InstallExtensionFromWebstore(crx_path, 1));
[email protected]fc38935a2011-10-31 23:53:28266}
[email protected]ee14cad2012-03-29 01:59:37267
268IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, PlatformAppCrx) {
[email protected]b70a2d92012-06-28 19:51:21269 CommandLine::ForCurrentProcess()->AppendSwitch(
270 switches::kEnableExperimentalExtensionApis);
[email protected]ee14cad2012-03-29 01:59:37271 EXPECT_TRUE(InstallExtension(
[email protected]dc37b002012-04-23 23:02:26272 test_data_dir_.AppendASCII("minimal_platform_app.crx"), 1));
[email protected]ee14cad2012-03-29 01:59:37273}
[email protected]bf2fcd52012-04-16 22:59:39274
[email protected]3f3365c62012-07-09 19:13:21275// http://crbug.com/136397
276#if defined(OS_CHROMEOS)
277#define MAYBE_PackAndInstallExtension DISABLED_PackAndInstallExtension
278#else
279#define MAYBE_PackAndInstallExtension PackAndInstallExtension
280#endif
281IN_PROC_BROWSER_TEST_F(
282 ExtensionCrxInstallerTest, MAYBE_PackAndInstallExtension) {
[email protected]544471a2012-10-13 05:27:09283 if (!FeatureSwitch::easy_off_store_install()->IsEnabled())
[email protected]89019d62012-05-17 18:47:09284 return;
285
[email protected]bf2fcd52012-04-16 22:59:39286 const int kNumDownloadsExpected = 1;
[email protected]bf2fcd52012-04-16 22:59:39287
288 LOG(ERROR) << "PackAndInstallExtension: Packing extension";
[email protected]650b2d52013-02-10 03:41:45289 base::FilePath crx_path = PackExtension(
[email protected]bf2fcd52012-04-16 22:59:39290 test_data_dir_.AppendASCII("common/background_page"));
291 ASSERT_FALSE(crx_path.empty());
292 std::string crx_path_string(crx_path.value().begin(), crx_path.value().end());
293 GURL url = GURL(std::string("file:///").append(crx_path_string));
294
[email protected]f8636f92013-08-09 21:02:37295 scoped_refptr<MockPromptProxy> mock_prompt =
296 CreateMockPromptProxyForBrowser(browser());
297 download_crx_util::SetMockInstallPromptForTesting(
298 mock_prompt->CreatePrompt());
[email protected]bf2fcd52012-04-16 22:59:39299
300 LOG(ERROR) << "PackAndInstallExtension: Getting download manager";
301 content::DownloadManager* download_manager =
[email protected]b441a8492012-06-06 14:55:57302 content::BrowserContext::GetDownloadManager(browser()->profile());
[email protected]bf2fcd52012-04-16 22:59:39303
304 LOG(ERROR) << "PackAndInstallExtension: Setting observer";
[email protected]49b264f2012-08-14 17:12:26305 scoped_ptr<content::DownloadTestObserver> observer(
306 new content::DownloadTestObserverTerminal(
[email protected]47665442012-07-27 02:31:22307 download_manager, kNumDownloadsExpected,
[email protected]49b264f2012-08-14 17:12:26308 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
[email protected]bf2fcd52012-04-16 22:59:39309 LOG(ERROR) << "PackAndInstallExtension: Navigating to URL";
310 ui_test_utils::NavigateToURLWithDisposition(browser(), url, CURRENT_TAB,
311 ui_test_utils::BROWSER_TEST_NONE);
312
[email protected]8c6af5b2012-06-15 20:10:26313 EXPECT_TRUE(WaitForCrxInstallerDone());
[email protected]bf2fcd52012-04-16 22:59:39314 LOG(ERROR) << "PackAndInstallExtension: Extension install";
[email protected]c82da8c42012-06-08 19:49:11315 EXPECT_TRUE(mock_prompt->confirmation_requested());
[email protected]bf2fcd52012-04-16 22:59:39316 LOG(ERROR) << "PackAndInstallExtension: Extension install confirmed";
317}
[email protected]a9736892012-05-30 15:58:05318
[email protected]b70a2d92012-06-28 19:51:21319// Tests that scopes are only granted if |record_oauth2_grant_| on the prompt is
320// true.
[email protected]7a561912012-08-21 21:06:05321#if defined(OS_WIN)
[email protected]1e09ec82012-12-21 22:48:09322#define MAYBE_GrantScopes DISABLED_GrantScopes
[email protected]7a561912012-08-21 21:06:05323#else
324#define MAYBE_GrantScopes GrantScopes
325#endif
326IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, MAYBE_GrantScopes) {
[email protected]b70a2d92012-06-28 19:51:21327 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes",
328 true));
329}
330
331IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotGrantScopes) {
332 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes",
333 false));
334}
335
[email protected]45dd1b4802012-06-05 23:07:59336// Off-store install cannot yet be disabled on Aura.
[email protected]a9736892012-05-30 15:58:05337#if defined(USE_AURA)
[email protected]45dd1b4802012-06-05 23:07:59338#define MAYBE_AllowOffStore DISABLED_AllowOffStore
[email protected]a9736892012-05-30 15:58:05339#else
[email protected]45dd1b4802012-06-05 23:07:59340#define MAYBE_AllowOffStore AllowOffStore
341#endif
[email protected]4b283e672012-08-06 21:45:04342// Crashy: http://crbug.com/140893
343IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DISABLED_AllowOffStore) {
[email protected]06bdd2b2012-11-30 18:47:13344 ExtensionService* service = extensions::ExtensionSystem::Get(
345 browser()->profile())->extension_service();
[email protected]a9736892012-05-30 15:58:05346 const bool kTestData[] = {false, true};
347
348 for (size_t i = 0; i < arraysize(kTestData); ++i) {
[email protected]f8636f92013-08-09 21:02:37349 scoped_refptr<MockPromptProxy> mock_prompt =
350 CreateMockPromptProxyForBrowser(browser());
351
[email protected]a9736892012-05-30 15:58:05352 scoped_refptr<CrxInstaller> crx_installer(
[email protected]f8636f92013-08-09 21:02:37353 CrxInstaller::Create(service, mock_prompt->CreatePrompt()));
[email protected]7224dbd2012-06-05 15:21:50354 crx_installer->set_install_cause(
355 extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);
[email protected]d9039812012-06-09 06:05:48356
357 if (kTestData[i]) {
358 crx_installer->set_off_store_install_allow_reason(
359 CrxInstaller::OffStoreInstallAllowedInTest);
360 }
[email protected]a9736892012-05-30 15:58:05361
362 crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
363 EXPECT_EQ(kTestData[i], WaitForExtensionInstall()) << kTestData[i];
[email protected]c82da8c42012-06-08 19:49:11364 EXPECT_EQ(kTestData[i], mock_prompt->did_succeed());
365 EXPECT_EQ(kTestData[i], mock_prompt->confirmation_requested()) <<
366 kTestData[i];
[email protected]a9736892012-05-30 15:58:05367 if (kTestData[i]) {
[email protected]c82da8c42012-06-08 19:49:11368 EXPECT_EQ(string16(), mock_prompt->error()) << kTestData[i];
[email protected]a9736892012-05-30 15:58:05369 } else {
370 EXPECT_EQ(l10n_util::GetStringUTF16(
371 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE),
[email protected]c82da8c42012-06-08 19:49:11372 mock_prompt->error()) << kTestData[i];
[email protected]a9736892012-05-30 15:58:05373 }
374 }
[email protected]a9736892012-05-30 15:58:05375}
[email protected]bf3d9df2012-07-24 23:20:27376
[email protected]90d3c042013-06-06 10:10:39377IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, HiDpiThemeTest) {
378 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx");
379 crx_path = crx_path.AppendASCII("theme_hidpi.crx");
380
381 ASSERT_TRUE(InstallExtension(crx_path,1));
382
383 const std::string extension_id("gllekhaobjnhgeagipipnkpmmmpchacm");
384 ExtensionService* service = extensions::ExtensionSystem::Get(
385 browser()->profile())->extension_service();
386 ASSERT_TRUE(service);
387 const extensions::Extension* extension =
388 service->GetExtensionById(extension_id, false);
389 ASSERT_TRUE(extension);
390 EXPECT_EQ(extension_id, extension->id());
391
392 UninstallExtension(extension_id);
393 EXPECT_FALSE(service->GetExtensionById(extension_id, false));
394}
395
[email protected]9e9c1d12013-07-31 01:58:12396IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
397 InstallDelayedUntilNextUpdate) {
398 const std::string extension_id("ldnnhddmnhbkjipkidpdiheffobcpfmf");
399 base::FilePath crx_path = test_data_dir_.AppendASCII("delayed_install");
400 ExtensionSystem* extension_system = extensions::ExtensionSystem::Get(
401 browser()->profile());
402 ExtensionService* service = extension_system->extension_service();
403 ASSERT_TRUE(service);
404
405 // Install version 1 of the test extension. This extension does not have
406 // a background page but does have a browser action.
407 ASSERT_TRUE(InstallExtension(crx_path.AppendASCII("v1.crx"), 1));
408 const extensions::Extension* extension =
409 service->GetExtensionById(extension_id, false);
410 ASSERT_TRUE(extension);
411 ASSERT_EQ(extension_id, extension->id());
412 ASSERT_EQ("1.0", extension->version()->GetString());
413
414 // Make test extension non-idle by opening the extension's browser action
415 // popup. This should cause the installation to be delayed.
416 std::string popup_url = std::string("chrome-extension://")
417 + extension_id + std::string("/popup.html");
418 scoped_ptr<ExtensionHost> extension_host = scoped_ptr<ExtensionHost>(
419 OpenUrlInExtensionPopupHost(extension, GURL(popup_url)));
420
421 // Install version 2 of the extension and check that it is indeed delayed.
422 ASSERT_TRUE(UpdateExtensionWaitForIdle(
423 extension_id, crx_path.AppendASCII("v2.crx"), 0));
424
425 ASSERT_EQ(1u, service->delayed_installs()->size());
426 extension = service->GetExtensionById(extension_id, false);
427 ASSERT_EQ("1.0", extension->version()->GetString());
428
429 // Make the extension idle again by navigating away from the extension's
430 // browser action page. This should not trigger the delayed install.
431 extension_system->process_manager()->UnregisterRenderViewHost(
432 extension_host->render_view_host());
433 ASSERT_EQ(1u, service->delayed_installs()->size());
434
435 // Install version 3 of the extension. Because the extension is idle,
436 // this install should succeed.
437 ASSERT_TRUE(UpdateExtensionWaitForIdle(
438 extension_id, crx_path.AppendASCII("v3.crx"), 0));
439 extension = service->GetExtensionById(extension_id, false);
440 ASSERT_EQ("3.0", extension->version()->GetString());
441
442 // The version 2 delayed install should be cleaned up, and finishing
443 // delayed extension installation shouldn't break anything.
444 ASSERT_EQ(0u, service->delayed_installs()->size());
445 service->MaybeFinishDelayedInstallations();
446 extension = service->GetExtensionById(extension_id, false);
447 ASSERT_EQ("3.0", extension->version()->GetString());
448}
449
[email protected]9f3c8532013-07-31 19:52:07450IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blacklist) {
[email protected]3f2a2fa2013-09-24 02:55:25451 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
452 new FakeSafeBrowsingDatabaseManager(true));
453 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
[email protected]9f3c8532013-07-31 19:52:07454
[email protected]3f2a2fa2013-09-24 02:55:25455 blacklist_db->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm");
[email protected]9f3c8532013-07-31 19:52:07456
457 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx")
458 .AppendASCII("theme_hidpi.crx");
459 EXPECT_FALSE(InstallExtension(crx_path, 0));
460}
461
[email protected]85290822013-08-23 20:27:38462IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, NonStrictManifestCheck) {
463 scoped_refptr<MockPromptProxy> mock_prompt =
464 CreateMockPromptProxyForBrowser(browser());
465
466 // We want to simulate the case where the webstore sends a more recent
467 // version of the manifest, but the downloaded .crx file is old since
468 // the newly published version hasn't fully propagated to all the download
469 // servers yet. So load the v2 manifest, but then install the v1 crx file.
470 std::string id = "lhnaeclnpobnlbjbgogdanmhadigfnjp";
471 scoped_ptr<WebstoreInstaller::Approval> approval =
472 GetApproval("crx_installer/v2_no_permission_change/", id, false);
473
474 RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(),
475 test_data_dir_.AppendASCII("crx_installer/v1.crx"));
476
477 EXPECT_TRUE(mock_prompt->did_succeed());
478}
479
[email protected]bf3d9df2012-07-24 23:20:27480} // namespace extensions