blob: aeb7313a007b71bf1e19f58b7e0775153508ff9f [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]5a145e82014-05-29 22:19:075#include "base/at_exit.h"
[email protected]f8636f92013-08-09 21:02:376#include "base/memory/ref_counted.h"
[email protected]253fc2bb2014-07-10 04:21:187#include "base/strings/utf_string_conversions.h"
[email protected]bf2fcd52012-04-16 22:59:398#include "chrome/browser/download/download_crx_util.h"
[email protected]52b76592013-11-02 17:59:039#include "chrome/browser/extensions/browser_action_test_util.h"
[email protected]a01e00632010-11-05 16:58:1410#include "chrome/browser/extensions/crx_installer.h"
11#include "chrome/browser/extensions/extension_browsertest.h"
[email protected]c82da8c42012-06-08 19:49:1112#include "chrome/browser/extensions/extension_install_prompt.h"
[email protected]eaa7dd182010-12-14 11:09:0013#include "chrome/browser/extensions/extension_service.h"
[email protected]658eae52014-06-14 20:28:0514#include "chrome/browser/extensions/extension_util.h"
[email protected]3f2a2fa2013-09-24 02:55:2515#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
[email protected]8ecad5e2010-12-02 21:18:3316#include "chrome/browser/profiles/profile.h"
[email protected]2ad4a902010-11-17 06:05:1317#include "chrome/browser/ui/browser.h"
[email protected]619f86182012-07-03 21:30:1818#include "chrome/browser/ui/browser_window.h"
[email protected]91e51d612012-10-21 23:03:0519#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]af44e7fb2011-07-29 18:32:3220#include "chrome/test/base/ui_test_utils.h"
[email protected]5a145e82014-05-29 22:19:0721#include "content/public/browser/browser_thread.h"
[email protected]f34efa22013-03-05 19:14:2322#include "content/public/browser/download_manager.h"
[email protected]52b76592013-11-02 17:59:0323#include "content/public/browser/render_view_host.h"
[email protected]8ffad4e2014-01-02 23:18:2624#include "content/public/test/browser_test_utils.h"
[email protected]49b264f2012-08-14 17:12:2625#include "content/public/test/download_test_observer.h"
[email protected]dccba4f82014-05-29 00:52:5626#include "extensions/browser/extension_prefs.h"
[email protected]59b0e602014-01-30 00:41:2427#include "extensions/browser/extension_system.h"
[email protected]253fc2bb2014-07-10 04:21:1828#include "extensions/browser/management_policy.h"
[email protected]adf5a102014-07-31 12:44:0629#include "extensions/browser/notification_types.h"
[email protected]e4452d32013-11-15 23:07:4130#include "extensions/common/extension.h"
[email protected]5ef835a2013-11-08 20:42:5731#include "extensions/common/feature_switch.h"
[email protected]85df9d12014-04-15 17:02:1432#include "extensions/common/file_util.h"
[email protected]5a55f3f2013-10-29 01:08:2933#include "extensions/common/permissions/permission_set.h"
[email protected]c8d02992013-07-31 22:16:5134#include "extensions/common/switches.h"
[email protected]a9736892012-05-30 15:58:0535#include "grit/generated_resources.h"
36#include "ui/base/l10n/l10n_util.h"
[email protected]a01e00632010-11-05 16:58:1437
[email protected]14a18bf2013-09-26 08:42:3038#if defined(OS_CHROMEOS)
[email protected]83d82d42014-05-16 02:04:4239#include "chrome/browser/chromeos/login/users/fake_user_manager.h"
40#include "chrome/browser/chromeos/login/users/user_manager.h"
[email protected]5a145e82014-05-29 22:19:0741#include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
42#include "chromeos/chromeos_switches.h"
[email protected]14a18bf2013-09-26 08:42:3043#endif
44
[email protected]7a5452f2010-12-13 23:03:1945class SkBitmap;
46
[email protected]bf3d9df2012-07-24 23:20:2747namespace extensions {
[email protected]b70a2d92012-06-28 19:51:2148
[email protected]a01e00632010-11-05 16:58:1449namespace {
50
[email protected]f8636f92013-08-09 21:02:3751class MockInstallPrompt;
52
53// This class holds information about things that happen with a
54// MockInstallPrompt. We create the MockInstallPrompt but need to pass
55// ownership of it to CrxInstaller, so it isn't safe to hang this data on
56// MockInstallPrompt itself becuase we can't guarantee it's lifetime.
[email protected]658eae52014-06-14 20:28:0557class MockPromptProxy : public base::RefCountedThreadSafe<MockPromptProxy> {
[email protected]f8636f92013-08-09 21:02:3758 public:
59 explicit MockPromptProxy(content::WebContents* web_contents);
60
61 bool did_succeed() const { return !extension_id_.empty(); }
62 const std::string& extension_id() { return extension_id_; }
63 bool confirmation_requested() const { return confirmation_requested_; }
[email protected]439f1e32013-12-09 20:09:0964 const base::string16& error() const { return error_; }
[email protected]f8636f92013-08-09 21:02:3765
66 // To have any effect, this should be called before CreatePrompt.
67 void set_record_oauth2_grant(bool record_oauth2_grant) {
68 record_oauth2_grant_.reset(new bool(record_oauth2_grant));
69 }
70
71 void set_extension_id(const std::string& id) { extension_id_ = id; }
72 void set_confirmation_requested() { confirmation_requested_ = true; }
[email protected]439f1e32013-12-09 20:09:0973 void set_error(const base::string16& error) { error_ = error; }
[email protected]f8636f92013-08-09 21:02:3774
75 scoped_ptr<ExtensionInstallPrompt> CreatePrompt();
76
77 private:
78 friend class base::RefCountedThreadSafe<MockPromptProxy>;
79 virtual ~MockPromptProxy();
80
81 // Data used to create a prompt.
82 content::WebContents* web_contents_;
83 scoped_ptr<bool> record_oauth2_grant_;
84
85 // Data reported back to us by the prompt we created.
86 bool confirmation_requested_;
87 std::string extension_id_;
[email protected]439f1e32013-12-09 20:09:0988 base::string16 error_;
[email protected]f8636f92013-08-09 21:02:3789};
[email protected]bf2fcd52012-04-16 22:59:3990
[email protected]c82da8c42012-06-08 19:49:1191class MockInstallPrompt : public ExtensionInstallPrompt {
[email protected]a01e00632010-11-05 16:58:1492 public:
[email protected]f8636f92013-08-09 21:02:3793 MockInstallPrompt(content::WebContents* web_contents,
94 MockPromptProxy* proxy) :
[email protected]91e51d612012-10-21 23:03:0595 ExtensionInstallPrompt(web_contents),
[email protected]f8636f92013-08-09 21:02:3796 proxy_(proxy) {}
[email protected]a01e00632010-11-05 16:58:1497
[email protected]b70a2d92012-06-28 19:51:2198 void set_record_oauth2_grant(bool record) { record_oauth2_grant_ = record; }
[email protected]a01e00632010-11-05 16:58:1499
100 // Overriding some of the ExtensionInstallUI API.
[email protected]49aeab62013-02-07 02:53:11101 virtual void ConfirmInstall(
102 Delegate* delegate,
103 const Extension* extension,
104 const ShowDialogCallback& show_dialog_callback) OVERRIDE {
[email protected]f8636f92013-08-09 21:02:37105 proxy_->set_confirmation_requested();
[email protected]a01e00632010-11-05 16:58:14106 delegate->InstallUIProceed();
107 }
[email protected]49aeab62013-02-07 02:53:11108 virtual void OnInstallSuccess(const Extension* extension,
109 SkBitmap* icon) OVERRIDE {
[email protected]f8636f92013-08-09 21:02:37110 proxy_->set_extension_id(extension->id());
[email protected]b3a25092013-05-28 22:08:16111 base::MessageLoopForUI::current()->Quit();
[email protected]a01e00632010-11-05 16:58:14112 }
[email protected]49aeab62013-02-07 02:53:11113 virtual void OnInstallFailure(const CrxInstallerError& error) OVERRIDE {
[email protected]f8636f92013-08-09 21:02:37114 proxy_->set_error(error.message());
[email protected]b3a25092013-05-28 22:08:16115 base::MessageLoopForUI::current()->Quit();
[email protected]a01e00632010-11-05 16:58:14116 }
117
118 private:
[email protected]f8636f92013-08-09 21:02:37119 scoped_refptr<MockPromptProxy> proxy_;
[email protected]a01e00632010-11-05 16:58:14120};
121
[email protected]658eae52014-06-14 20:28:05122MockPromptProxy::MockPromptProxy(content::WebContents* web_contents)
123 : web_contents_(web_contents), confirmation_requested_(false) {
[email protected]f8636f92013-08-09 21:02:37124}
125
126MockPromptProxy::~MockPromptProxy() {}
127
128scoped_ptr<ExtensionInstallPrompt> MockPromptProxy::CreatePrompt() {
129 scoped_ptr<MockInstallPrompt> prompt(
130 new MockInstallPrompt(web_contents_, this));
131 if (record_oauth2_grant_.get())
132 prompt->set_record_oauth2_grant(*record_oauth2_grant_.get());
133 return prompt.PassAs<ExtensionInstallPrompt>();
134}
135
136
137scoped_refptr<MockPromptProxy> CreateMockPromptProxyForBrowser(
138 Browser* browser) {
139 return new MockPromptProxy(
[email protected]91e51d612012-10-21 23:03:05140 browser->tab_strip_model()->GetActiveWebContents());
[email protected]619f86182012-07-03 21:30:18141}
142
[email protected]253fc2bb2014-07-10 04:21:18143class ManagementPolicyMock : public extensions::ManagementPolicy::Provider {
144 public:
145 ManagementPolicyMock() {}
146
147 virtual std::string GetDebugPolicyProviderName() const OVERRIDE {
148 return "ManagementPolicyMock";
149 }
150
151 virtual bool UserMayLoad(const Extension* extension,
152 base::string16* error) const OVERRIDE {
153 *error = base::UTF8ToUTF16("Dummy error message");
154 return false;
155 }
156};
157
[email protected]a01e00632010-11-05 16:58:14158} // namespace
159
160class ExtensionCrxInstallerTest : public ExtensionBrowserTest {
161 public:
[email protected]85290822013-08-23 20:27:38162 scoped_ptr<WebstoreInstaller::Approval> GetApproval(
163 const char* manifest_dir,
[email protected]b70a2d92012-06-28 19:51:21164 const std::string& id,
[email protected]85290822013-08-23 20:27:38165 bool strict_manifest_checks) {
166 scoped_ptr<WebstoreInstaller::Approval> result;
167
168 base::FilePath ext_path = test_data_dir_.AppendASCII(manifest_dir);
169 std::string error;
170 scoped_ptr<base::DictionaryValue> parsed_manifest(
[email protected]85df9d12014-04-15 17:02:14171 file_util::LoadManifest(ext_path, &error));
[email protected]85290822013-08-23 20:27:38172 if (!parsed_manifest.get() || !error.empty())
173 return result.Pass();
174
175 return WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
176 browser()->profile(),
177 id,
178 parsed_manifest.Pass(),
179 strict_manifest_checks);
180 }
181
182 void RunCrxInstaller(const WebstoreInstaller::Approval* approval,
183 scoped_ptr<ExtensionInstallPrompt> prompt,
184 const base::FilePath& crx_path) {
[email protected]06bdd2b2012-11-30 18:47:13185 ExtensionService* service = extensions::ExtensionSystem::Get(
186 browser()->profile())->extension_service();
[email protected]a01e00632010-11-05 16:58:14187 scoped_refptr<CrxInstaller> installer(
[email protected]85290822013-08-23 20:27:38188 CrxInstaller::Create(service, prompt.Pass(), approval));
[email protected]a01e00632010-11-05 16:58:14189 installer->set_allow_silent_install(true);
[email protected]b1f04cc2010-11-10 22:59:30190 installer->set_is_gallery_install(true);
[email protected]85290822013-08-23 20:27:38191 installer->InstallCrx(crx_path);
[email protected]729eb632012-07-26 04:45:26192 content::RunMessageLoop();
[email protected]85290822013-08-23 20:27:38193 }
194
195 // Installs a crx from |crx_relpath| (a path relative to the extension test
196 // data dir) with expected id |id|.
197 void InstallWithPrompt(const char* ext_relpath,
198 const std::string& id,
199 scoped_refptr<MockPromptProxy> mock_install_prompt) {
200 base::FilePath ext_path = test_data_dir_.AppendASCII(ext_relpath);
201
202 scoped_ptr<WebstoreInstaller::Approval> approval;
203 if (!id.empty())
204 approval = GetApproval(ext_relpath, id, true);
205
206 base::FilePath crx_path = PackExtension(ext_path);
207 EXPECT_FALSE(crx_path.empty());
208 RunCrxInstaller(approval.get(), mock_install_prompt->CreatePrompt(),
209 crx_path);
[email protected]a01e00632010-11-05 16:58:14210
[email protected]c82da8c42012-06-08 19:49:11211 EXPECT_TRUE(mock_install_prompt->did_succeed());
[email protected]b70a2d92012-06-28 19:51:21212 }
213
214 // Installs an extension and checks that it has scopes granted IFF
215 // |record_oauth2_grant| is true.
216 void CheckHasEmptyScopesAfterInstall(const std::string& ext_relpath,
217 bool record_oauth2_grant) {
218 CommandLine::ForCurrentProcess()->AppendSwitch(
219 switches::kEnableExperimentalExtensionApis);
220
[email protected]f8636f92013-08-09 21:02:37221 scoped_refptr<MockPromptProxy> mock_prompt =
222 CreateMockPromptProxyForBrowser(browser());
223
[email protected]b70a2d92012-06-28 19:51:21224 mock_prompt->set_record_oauth2_grant(record_oauth2_grant);
[email protected]85290822013-08-23 20:27:38225 InstallWithPrompt("browsertest/scopes", std::string(), mock_prompt);
[email protected]b70a2d92012-06-28 19:51:21226
[email protected]bf3d9df2012-07-24 23:20:27227 scoped_refptr<PermissionSet> permissions =
[email protected]7c82539c2014-02-19 06:09:17228 ExtensionPrefs::Get(browser()->profile())
229 ->GetGrantedPermissions(mock_prompt->extension_id());
[email protected]b70a2d92012-06-28 19:51:21230 ASSERT_TRUE(permissions.get());
[email protected]a01e00632010-11-05 16:58:14231 }
232};
233
[email protected]45dd1b4802012-06-05 23:07:59234#if defined(OS_CHROMEOS)
235#define MAYBE_Whitelisting DISABLED_Whitelisting
236#else
237#define MAYBE_Whitelisting Whitelisting
238#endif
239IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, MAYBE_Whitelisting) {
[email protected]21a5ad62012-04-03 04:48:45240 std::string id = "hdgllgikmikobbofgnabhfimcfoopgnd";
[email protected]06bdd2b2012-11-30 18:47:13241 ExtensionService* service = extensions::ExtensionSystem::Get(
242 browser()->profile())->extension_service();
[email protected]21a5ad62012-04-03 04:48:45243
244 // Even whitelisted extensions with NPAPI should not prompt.
[email protected]f8636f92013-08-09 21:02:37245 scoped_refptr<MockPromptProxy> mock_prompt =
246 CreateMockPromptProxyForBrowser(browser());
[email protected]85290822013-08-23 20:27:38247 InstallWithPrompt("uitest/plugins", id, mock_prompt);
[email protected]b70a2d92012-06-28 19:51:21248 EXPECT_FALSE(mock_prompt->confirmation_requested());
[email protected]21a5ad62012-04-03 04:48:45249 EXPECT_TRUE(service->GetExtensionById(id, false));
[email protected]a01e00632010-11-05 16:58:14250}
[email protected]fc38935a2011-10-31 23:53:28251
252IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
[email protected]240cc92a2011-12-01 01:22:24253 GalleryInstallGetsExperimental) {
254 // We must modify the command line temporarily in order to pack an extension
255 // that requests the experimental permission.
256 CommandLine* command_line = CommandLine::ForCurrentProcess();
257 CommandLine old_command_line = *command_line;
258 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis);
[email protected]650b2d52013-02-10 03:41:45259 base::FilePath crx_path = PackExtension(
[email protected]240cc92a2011-12-01 01:22:24260 test_data_dir_.AppendASCII("experimental"));
261 ASSERT_FALSE(crx_path.empty());
262
263 // Now reset the command line so that we are testing specifically whether
264 // installing from webstore enables experimental permissions.
265 *(CommandLine::ForCurrentProcess()) = old_command_line;
266
267 EXPECT_FALSE(InstallExtension(crx_path, 0));
268 EXPECT_TRUE(InstallExtensionFromWebstore(crx_path, 1));
[email protected]fc38935a2011-10-31 23:53:28269}
[email protected]ee14cad2012-03-29 01:59:37270
271IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, PlatformAppCrx) {
[email protected]b70a2d92012-06-28 19:51:21272 CommandLine::ForCurrentProcess()->AppendSwitch(
273 switches::kEnableExperimentalExtensionApis);
[email protected]ee14cad2012-03-29 01:59:37274 EXPECT_TRUE(InstallExtension(
[email protected]dc37b002012-04-23 23:02:26275 test_data_dir_.AppendASCII("minimal_platform_app.crx"), 1));
[email protected]ee14cad2012-03-29 01:59:37276}
[email protected]bf2fcd52012-04-16 22:59:39277
[email protected]3f3365c62012-07-09 19:13:21278// http://crbug.com/136397
279#if defined(OS_CHROMEOS)
280#define MAYBE_PackAndInstallExtension DISABLED_PackAndInstallExtension
281#else
282#define MAYBE_PackAndInstallExtension PackAndInstallExtension
283#endif
284IN_PROC_BROWSER_TEST_F(
285 ExtensionCrxInstallerTest, MAYBE_PackAndInstallExtension) {
[email protected]544471a2012-10-13 05:27:09286 if (!FeatureSwitch::easy_off_store_install()->IsEnabled())
[email protected]89019d62012-05-17 18:47:09287 return;
288
[email protected]bf2fcd52012-04-16 22:59:39289 const int kNumDownloadsExpected = 1;
[email protected]bf2fcd52012-04-16 22:59:39290
291 LOG(ERROR) << "PackAndInstallExtension: Packing extension";
[email protected]650b2d52013-02-10 03:41:45292 base::FilePath crx_path = PackExtension(
[email protected]bf2fcd52012-04-16 22:59:39293 test_data_dir_.AppendASCII("common/background_page"));
294 ASSERT_FALSE(crx_path.empty());
295 std::string crx_path_string(crx_path.value().begin(), crx_path.value().end());
296 GURL url = GURL(std::string("file:///").append(crx_path_string));
297
[email protected]f8636f92013-08-09 21:02:37298 scoped_refptr<MockPromptProxy> mock_prompt =
299 CreateMockPromptProxyForBrowser(browser());
300 download_crx_util::SetMockInstallPromptForTesting(
301 mock_prompt->CreatePrompt());
[email protected]bf2fcd52012-04-16 22:59:39302
303 LOG(ERROR) << "PackAndInstallExtension: Getting download manager";
304 content::DownloadManager* download_manager =
[email protected]b441a8492012-06-06 14:55:57305 content::BrowserContext::GetDownloadManager(browser()->profile());
[email protected]bf2fcd52012-04-16 22:59:39306
307 LOG(ERROR) << "PackAndInstallExtension: Setting observer";
[email protected]49b264f2012-08-14 17:12:26308 scoped_ptr<content::DownloadTestObserver> observer(
309 new content::DownloadTestObserverTerminal(
[email protected]47665442012-07-27 02:31:22310 download_manager, kNumDownloadsExpected,
[email protected]49b264f2012-08-14 17:12:26311 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
[email protected]bf2fcd52012-04-16 22:59:39312 LOG(ERROR) << "PackAndInstallExtension: Navigating to URL";
313 ui_test_utils::NavigateToURLWithDisposition(browser(), url, CURRENT_TAB,
314 ui_test_utils::BROWSER_TEST_NONE);
315
[email protected]8c6af5b2012-06-15 20:10:26316 EXPECT_TRUE(WaitForCrxInstallerDone());
[email protected]bf2fcd52012-04-16 22:59:39317 LOG(ERROR) << "PackAndInstallExtension: Extension install";
[email protected]c82da8c42012-06-08 19:49:11318 EXPECT_TRUE(mock_prompt->confirmation_requested());
[email protected]bf2fcd52012-04-16 22:59:39319 LOG(ERROR) << "PackAndInstallExtension: Extension install confirmed";
320}
[email protected]a9736892012-05-30 15:58:05321
[email protected]b70a2d92012-06-28 19:51:21322// Tests that scopes are only granted if |record_oauth2_grant_| on the prompt is
323// true.
[email protected]7a561912012-08-21 21:06:05324#if defined(OS_WIN)
[email protected]1e09ec82012-12-21 22:48:09325#define MAYBE_GrantScopes DISABLED_GrantScopes
[email protected]7a561912012-08-21 21:06:05326#else
327#define MAYBE_GrantScopes GrantScopes
328#endif
329IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, MAYBE_GrantScopes) {
[email protected]b70a2d92012-06-28 19:51:21330 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes",
331 true));
332}
333
334IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotGrantScopes) {
335 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes",
336 false));
337}
338
[email protected]45dd1b4802012-06-05 23:07:59339// Off-store install cannot yet be disabled on Aura.
[email protected]a9736892012-05-30 15:58:05340#if defined(USE_AURA)
[email protected]45dd1b4802012-06-05 23:07:59341#define MAYBE_AllowOffStore DISABLED_AllowOffStore
[email protected]a9736892012-05-30 15:58:05342#else
[email protected]45dd1b4802012-06-05 23:07:59343#define MAYBE_AllowOffStore AllowOffStore
344#endif
[email protected]4b283e672012-08-06 21:45:04345// Crashy: http://crbug.com/140893
346IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DISABLED_AllowOffStore) {
[email protected]06bdd2b2012-11-30 18:47:13347 ExtensionService* service = extensions::ExtensionSystem::Get(
348 browser()->profile())->extension_service();
[email protected]a9736892012-05-30 15:58:05349 const bool kTestData[] = {false, true};
350
351 for (size_t i = 0; i < arraysize(kTestData); ++i) {
[email protected]f8636f92013-08-09 21:02:37352 scoped_refptr<MockPromptProxy> mock_prompt =
353 CreateMockPromptProxyForBrowser(browser());
354
[email protected]a9736892012-05-30 15:58:05355 scoped_refptr<CrxInstaller> crx_installer(
[email protected]f8636f92013-08-09 21:02:37356 CrxInstaller::Create(service, mock_prompt->CreatePrompt()));
[email protected]7224dbd2012-06-05 15:21:50357 crx_installer->set_install_cause(
358 extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);
[email protected]d9039812012-06-09 06:05:48359
360 if (kTestData[i]) {
361 crx_installer->set_off_store_install_allow_reason(
362 CrxInstaller::OffStoreInstallAllowedInTest);
363 }
[email protected]a9736892012-05-30 15:58:05364
365 crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
[email protected]918c2712013-10-21 23:59:56366 EXPECT_EQ(kTestData[i],
367 WaitForExtensionInstall()) << kTestData[i];
[email protected]c82da8c42012-06-08 19:49:11368 EXPECT_EQ(kTestData[i], mock_prompt->did_succeed());
369 EXPECT_EQ(kTestData[i], mock_prompt->confirmation_requested()) <<
370 kTestData[i];
[email protected]a9736892012-05-30 15:58:05371 if (kTestData[i]) {
[email protected]b959d7d42013-12-13 17:26:37372 EXPECT_EQ(base::string16(), mock_prompt->error()) << kTestData[i];
[email protected]a9736892012-05-30 15:58:05373 } else {
374 EXPECT_EQ(l10n_util::GetStringUTF16(
375 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE),
[email protected]c82da8c42012-06-08 19:49:11376 mock_prompt->error()) << kTestData[i];
[email protected]a9736892012-05-30 15:58:05377 }
378 }
[email protected]a9736892012-05-30 15:58:05379}
[email protected]bf3d9df2012-07-24 23:20:27380
[email protected]90d3c042013-06-06 10:10:39381IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, HiDpiThemeTest) {
382 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx");
383 crx_path = crx_path.AppendASCII("theme_hidpi.crx");
384
[email protected]658eae52014-06-14 20:28:05385 ASSERT_TRUE(InstallExtension(crx_path, 1));
[email protected]90d3c042013-06-06 10:10:39386
387 const std::string extension_id("gllekhaobjnhgeagipipnkpmmmpchacm");
388 ExtensionService* service = extensions::ExtensionSystem::Get(
389 browser()->profile())->extension_service();
390 ASSERT_TRUE(service);
391 const extensions::Extension* extension =
392 service->GetExtensionById(extension_id, false);
393 ASSERT_TRUE(extension);
394 EXPECT_EQ(extension_id, extension->id());
395
396 UninstallExtension(extension_id);
397 EXPECT_FALSE(service->GetExtensionById(extension_id, false));
398}
399
[email protected]143238b2013-11-05 23:02:46400// See http://crbug.com/315299.
[email protected]c4c0c0a12014-07-23 17:06:02401#if defined(OS_WIN) || defined(OS_LINUX)
[email protected]143238b2013-11-05 23:02:46402#define MAYBE_InstallDelayedUntilNextUpdate \
403 DISABLED_InstallDelayedUntilNextUpdate
404#else
405#define MAYBE_InstallDelayedUntilNextUpdate InstallDelayedUntilNextUpdate
[email protected]c4c0c0a12014-07-23 17:06:02406#endif
[email protected]9e9c1d12013-07-31 01:58:12407IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
[email protected]143238b2013-11-05 23:02:46408 MAYBE_InstallDelayedUntilNextUpdate) {
[email protected]9e9c1d12013-07-31 01:58:12409 const std::string extension_id("ldnnhddmnhbkjipkidpdiheffobcpfmf");
410 base::FilePath crx_path = test_data_dir_.AppendASCII("delayed_install");
411 ExtensionSystem* extension_system = extensions::ExtensionSystem::Get(
412 browser()->profile());
413 ExtensionService* service = extension_system->extension_service();
414 ASSERT_TRUE(service);
415
416 // Install version 1 of the test extension. This extension does not have
417 // a background page but does have a browser action.
418 ASSERT_TRUE(InstallExtension(crx_path.AppendASCII("v1.crx"), 1));
419 const extensions::Extension* extension =
420 service->GetExtensionById(extension_id, false);
421 ASSERT_TRUE(extension);
422 ASSERT_EQ(extension_id, extension->id());
423 ASSERT_EQ("1.0", extension->version()->GetString());
424
425 // Make test extension non-idle by opening the extension's browser action
426 // popup. This should cause the installation to be delayed.
[email protected]52b76592013-11-02 17:59:03427 content::WindowedNotificationObserver loading_observer(
[email protected]adf5a102014-07-31 12:44:06428 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
[email protected]52b76592013-11-02 17:59:03429 content::Source<Profile>(profile()));
430 BrowserActionTestUtil util(browser());
431 // There is only one extension, so just click the first browser action.
432 ASSERT_EQ(1, util.NumberOfBrowserActions());
433 util.Press(0);
434 loading_observer.Wait();
435 ExtensionHost* extension_host =
436 content::Details<ExtensionHost>(loading_observer.details()).ptr();
[email protected]9e9c1d12013-07-31 01:58:12437
438 // Install version 2 of the extension and check that it is indeed delayed.
439 ASSERT_TRUE(UpdateExtensionWaitForIdle(
440 extension_id, crx_path.AppendASCII("v2.crx"), 0));
441
442 ASSERT_EQ(1u, service->delayed_installs()->size());
443 extension = service->GetExtensionById(extension_id, false);
444 ASSERT_EQ("1.0", extension->version()->GetString());
445
[email protected]52b76592013-11-02 17:59:03446 // Make the extension idle again by closing the popup. This should not trigger
[email protected]658eae52014-06-14 20:28:05447 // the delayed install.
[email protected]8ffad4e2014-01-02 23:18:26448 content::RenderProcessHostWatcher terminated_observer(
449 extension_host->render_process_host(),
450 content::RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION);
[email protected]52b76592013-11-02 17:59:03451 extension_host->render_view_host()->ClosePage();
452 terminated_observer.Wait();
[email protected]9e9c1d12013-07-31 01:58:12453 ASSERT_EQ(1u, service->delayed_installs()->size());
454
455 // Install version 3 of the extension. Because the extension is idle,
456 // this install should succeed.
457 ASSERT_TRUE(UpdateExtensionWaitForIdle(
458 extension_id, crx_path.AppendASCII("v3.crx"), 0));
459 extension = service->GetExtensionById(extension_id, false);
460 ASSERT_EQ("3.0", extension->version()->GetString());
461
462 // The version 2 delayed install should be cleaned up, and finishing
463 // delayed extension installation shouldn't break anything.
464 ASSERT_EQ(0u, service->delayed_installs()->size());
465 service->MaybeFinishDelayedInstallations();
466 extension = service->GetExtensionById(extension_id, false);
467 ASSERT_EQ("3.0", extension->version()->GetString());
468}
469
[email protected]e3767aa2013-11-08 23:49:07470#if defined(FULL_SAFE_BROWSING)
[email protected]9f3c8532013-07-31 19:52:07471IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blacklist) {
[email protected]3f2a2fa2013-09-24 02:55:25472 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
473 new FakeSafeBrowsingDatabaseManager(true));
474 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
[email protected]9f3c8532013-07-31 19:52:07475
[email protected]3f2a2fa2013-09-24 02:55:25476 blacklist_db->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm");
[email protected]9f3c8532013-07-31 19:52:07477
478 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx")
479 .AppendASCII("theme_hidpi.crx");
480 EXPECT_FALSE(InstallExtension(crx_path, 0));
481}
[email protected]e3767aa2013-11-08 23:49:07482#endif
[email protected]9f3c8532013-07-31 19:52:07483
[email protected]85290822013-08-23 20:27:38484IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, NonStrictManifestCheck) {
485 scoped_refptr<MockPromptProxy> mock_prompt =
486 CreateMockPromptProxyForBrowser(browser());
487
488 // We want to simulate the case where the webstore sends a more recent
489 // version of the manifest, but the downloaded .crx file is old since
490 // the newly published version hasn't fully propagated to all the download
491 // servers yet. So load the v2 manifest, but then install the v1 crx file.
492 std::string id = "lhnaeclnpobnlbjbgogdanmhadigfnjp";
493 scoped_ptr<WebstoreInstaller::Approval> approval =
494 GetApproval("crx_installer/v2_no_permission_change/", id, false);
495
496 RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(),
497 test_data_dir_.AppendASCII("crx_installer/v1.crx"));
498
499 EXPECT_TRUE(mock_prompt->did_succeed());
500}
501
[email protected]14a18bf2013-09-26 08:42:30502IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, KioskOnlyTest) {
503 base::FilePath crx_path =
504 test_data_dir_.AppendASCII("kiosk/kiosk_only.crx");
505 EXPECT_FALSE(InstallExtension(crx_path, 0));
506#if defined(OS_CHROMEOS)
507 // Simulate ChromeOS kiosk mode. |scoped_user_manager| will take over
508 // lifetime of |user_manager|.
509 chromeos::FakeUserManager* fake_user_manager =
510 new chromeos::FakeUserManager();
511 fake_user_manager->AddKioskAppUser("[email protected]");
512 fake_user_manager->LoginUser("[email protected]");
513 chromeos::ScopedUserManagerEnabler scoped_user_manager(fake_user_manager);
514 EXPECT_TRUE(InstallExtension(crx_path, 1));
515#endif
516}
517
[email protected]5a145e82014-05-29 22:19:07518#if defined(OS_CHROMEOS)
519IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallToSharedLocation) {
520 base::ShadowingAtExitManager at_exit_manager;
521 CommandLine::ForCurrentProcess()->AppendSwitch(
522 chromeos::switches::kEnableExtensionAssetsSharing);
523 base::ScopedTempDir cache_dir;
524 ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
525 ExtensionAssetsManagerChromeOS::SetSharedInstallDirForTesting(
526 cache_dir.path());
527
528 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx");
529 const extensions::Extension* extension = InstallExtension(
530 crx_path, 1, extensions::Manifest::EXTERNAL_PREF);
531 base::FilePath extension_path = extension->path();
532 EXPECT_TRUE(cache_dir.path().IsParent(extension_path));
533 EXPECT_TRUE(base::PathExists(extension_path));
534
535 std::string extension_id = extension->id();
536 UninstallExtension(extension_id);
537 ExtensionService* service = extensions::ExtensionSystem::Get(
538 browser()->profile())->extension_service();
539 EXPECT_FALSE(service->GetExtensionById(extension_id, false));
540
541 // In the worst case you need to repeat this up to 3 times to make sure that
542 // all pending tasks we sent from UI thread to task runner and back to UI.
543 for (int i = 0; i < 3; i++) {
544 // Wait for background task completion that sends replay to UI thread.
545 content::BrowserThread::GetBlockingPool()->FlushForTesting();
546 // Wait for UI thread task completion.
547 base::RunLoop().RunUntilIdle();
548 }
549
550 EXPECT_FALSE(base::PathExists(extension_path));
551}
552#endif
553
[email protected]658eae52014-06-14 20:28:05554IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotSync) {
555 ExtensionService* service = extensions::ExtensionSystem::Get(
556 browser()->profile())->extension_service();
557 scoped_refptr<CrxInstaller> crx_installer(
558 CrxInstaller::CreateSilent(service));
[email protected]c30bda262014-06-19 04:10:13559 crx_installer->set_do_not_sync(true);
[email protected]658eae52014-06-14 20:28:05560 crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
561 EXPECT_TRUE(WaitForCrxInstallerDone());
562 ASSERT_TRUE(crx_installer->extension());
563
564 const ExtensionPrefs* extension_prefs =
565 ExtensionPrefs::Get(browser()->profile());
566 EXPECT_TRUE(extension_prefs->DoNotSync(crx_installer->extension()->id()));
567 EXPECT_FALSE(extensions::util::ShouldSyncApp(crx_installer->extension(),
568 browser()->profile()));
569}
570
[email protected]253fc2bb2014-07-10 04:21:18571IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, ManagementPolicy) {
572 ManagementPolicyMock policy;
573 extensions::ExtensionSystem::Get(profile())
574 ->management_policy()
575 ->RegisterProvider(&policy);
576
577 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx");
578 EXPECT_FALSE(InstallExtension(crx_path, 0));
579}
580
[email protected]bf3d9df2012-07-24 23:20:27581} // namespace extensions