blob: 3321e784feac45d8d9d9ccd234b8073162aea0c3 [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
mtomaszf7d99a5c2014-09-15 16:23:465#include "chrome/browser/extensions/crx_installer.h"
6
[email protected]5a145e82014-05-29 22:19:077#include "base/at_exit.h"
kalmanae342c92014-12-12 22:04:238#include "base/files/file_path.h"
[email protected]f8636f92013-08-09 21:02:379#include "base/memory/ref_counted.h"
[email protected]253fc2bb2014-07-10 04:21:1810#include "base/strings/utf_string_conversions.h"
[email protected]bf2fcd52012-04-16 22:59:3911#include "chrome/browser/download/download_crx_util.h"
[email protected]52b76592013-11-02 17:59:0312#include "chrome/browser/extensions/browser_action_test_util.h"
[email protected]a01e00632010-11-05 16:58:1413#include "chrome/browser/extensions/extension_browsertest.h"
[email protected]c82da8c42012-06-08 19:49:1114#include "chrome/browser/extensions/extension_install_prompt.h"
pkotwicz2f181782014-10-29 17:33:4515#include "chrome/browser/extensions/extension_install_prompt_show_params.h"
[email protected]eaa7dd182010-12-14 11:09:0016#include "chrome/browser/extensions/extension_service.h"
mekc95f9d062015-01-10 00:52:0417#include "chrome/browser/extensions/extension_tab_util.h"
[email protected]658eae52014-06-14 20:28:0518#include "chrome/browser/extensions/extension_util.h"
[email protected]3f2a2fa2013-09-24 02:55:2519#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
gpdavis.chromium48f08c42014-09-18 22:09:3420#include "chrome/browser/extensions/test_extension_dir.h"
[email protected]8ecad5e2010-12-02 21:18:3321#include "chrome/browser/profiles/profile.h"
[email protected]2ad4a902010-11-17 06:05:1322#include "chrome/browser/ui/browser.h"
[email protected]619f86182012-07-03 21:30:1823#include "chrome/browser/ui/browser_window.h"
[email protected]91e51d612012-10-21 23:03:0524#include "chrome/browser/ui/tabs/tab_strip_model.h"
[email protected]af39f002014-08-22 10:18:1825#include "chrome/grit/generated_resources.h"
[email protected]af44e7fb2011-07-29 18:32:3226#include "chrome/test/base/ui_test_utils.h"
[email protected]5a145e82014-05-29 22:19:0727#include "content/public/browser/browser_thread.h"
[email protected]f34efa22013-03-05 19:14:2328#include "content/public/browser/download_manager.h"
[email protected]52b76592013-11-02 17:59:0329#include "content/public/browser/render_view_host.h"
[email protected]8ffad4e2014-01-02 23:18:2630#include "content/public/test/browser_test_utils.h"
[email protected]49b264f2012-08-14 17:12:2631#include "content/public/test/download_test_observer.h"
mtomaszf7d99a5c2014-09-15 16:23:4632#include "content/public/test/test_utils.h"
[email protected]dccba4f82014-05-29 00:52:5633#include "extensions/browser/extension_prefs.h"
gpdavis.chromium48f08c42014-09-18 22:09:3434#include "extensions/browser/extension_registry.h"
[email protected]59b0e602014-01-30 00:41:2435#include "extensions/browser/extension_system.h"
ginkage47e603e2015-02-27 08:42:4136#include "extensions/browser/install/crx_install_error.h"
[email protected]253fc2bb2014-07-10 04:21:1837#include "extensions/browser/management_policy.h"
[email protected]adf5a102014-07-31 12:44:0638#include "extensions/browser/notification_types.h"
[email protected]e4452d32013-11-15 23:07:4139#include "extensions/common/extension.h"
[email protected]5ef835a2013-11-08 20:42:5740#include "extensions/common/feature_switch.h"
[email protected]85df9d12014-04-15 17:02:1441#include "extensions/common/file_util.h"
kalmanae342c92014-12-12 22:04:2342#include "extensions/common/permissions/api_permission.h"
[email protected]5a55f3f2013-10-29 01:08:2943#include "extensions/common/permissions/permission_set.h"
kalmanae342c92014-12-12 22:04:2344#include "extensions/common/permissions/permissions_data.h"
[email protected]c8d02992013-07-31 22:16:5145#include "extensions/common/switches.h"
[email protected]a9736892012-05-30 15:58:0546#include "ui/base/l10n/l10n_util.h"
[email protected]a01e00632010-11-05 16:58:1447
[email protected]14a18bf2013-09-26 08:42:3048#if defined(OS_CHROMEOS)
merkulova793f3022015-02-04 10:18:3049#include "chrome/browser/chromeos/login/users/fake_chrome_user_manager.h"
[email protected]4d390782014-08-15 09:22:5850#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
[email protected]5a145e82014-05-29 22:19:0751#include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
52#include "chromeos/chromeos_switches.h"
[email protected]14a18bf2013-09-26 08:42:3053#endif
54
[email protected]7a5452f2010-12-13 23:03:1955class SkBitmap;
56
[email protected]bf3d9df2012-07-24 23:20:2757namespace extensions {
[email protected]b70a2d92012-06-28 19:51:2158
[email protected]a01e00632010-11-05 16:58:1459namespace {
60
[email protected]f8636f92013-08-09 21:02:3761class MockInstallPrompt;
62
63// This class holds information about things that happen with a
64// MockInstallPrompt. We create the MockInstallPrompt but need to pass
65// ownership of it to CrxInstaller, so it isn't safe to hang this data on
66// MockInstallPrompt itself becuase we can't guarantee it's lifetime.
[email protected]658eae52014-06-14 20:28:0567class MockPromptProxy : public base::RefCountedThreadSafe<MockPromptProxy> {
[email protected]f8636f92013-08-09 21:02:3768 public:
69 explicit MockPromptProxy(content::WebContents* web_contents);
70
71 bool did_succeed() const { return !extension_id_.empty(); }
72 const std::string& extension_id() { return extension_id_; }
73 bool confirmation_requested() const { return confirmation_requested_; }
[email protected]439f1e32013-12-09 20:09:0974 const base::string16& error() const { return error_; }
[email protected]f8636f92013-08-09 21:02:3775
76 // To have any effect, this should be called before CreatePrompt.
77 void set_record_oauth2_grant(bool record_oauth2_grant) {
78 record_oauth2_grant_.reset(new bool(record_oauth2_grant));
79 }
80
81 void set_extension_id(const std::string& id) { extension_id_ = id; }
82 void set_confirmation_requested() { confirmation_requested_ = true; }
[email protected]439f1e32013-12-09 20:09:0983 void set_error(const base::string16& error) { error_ = error; }
[email protected]f8636f92013-08-09 21:02:3784
85 scoped_ptr<ExtensionInstallPrompt> CreatePrompt();
86
87 private:
88 friend class base::RefCountedThreadSafe<MockPromptProxy>;
89 virtual ~MockPromptProxy();
90
91 // Data used to create a prompt.
92 content::WebContents* web_contents_;
93 scoped_ptr<bool> record_oauth2_grant_;
94
95 // Data reported back to us by the prompt we created.
96 bool confirmation_requested_;
97 std::string extension_id_;
[email protected]439f1e32013-12-09 20:09:0998 base::string16 error_;
[email protected]f8636f92013-08-09 21:02:3799};
[email protected]bf2fcd52012-04-16 22:59:39100
[email protected]c82da8c42012-06-08 19:49:11101class MockInstallPrompt : public ExtensionInstallPrompt {
[email protected]a01e00632010-11-05 16:58:14102 public:
[email protected]f8636f92013-08-09 21:02:37103 MockInstallPrompt(content::WebContents* web_contents,
104 MockPromptProxy* proxy) :
[email protected]91e51d612012-10-21 23:03:05105 ExtensionInstallPrompt(web_contents),
[email protected]f8636f92013-08-09 21:02:37106 proxy_(proxy) {}
[email protected]a01e00632010-11-05 16:58:14107
[email protected]b70a2d92012-06-28 19:51:21108 void set_record_oauth2_grant(bool record) { record_oauth2_grant_ = record; }
[email protected]a01e00632010-11-05 16:58:14109
110 // Overriding some of the ExtensionInstallUI API.
dchengae36a4a2014-10-21 12:36:36111 void ConfirmInstall(Delegate* delegate,
112 const Extension* extension,
113 const ShowDialogCallback& show_dialog_callback) override {
[email protected]f8636f92013-08-09 21:02:37114 proxy_->set_confirmation_requested();
[email protected]a01e00632010-11-05 16:58:14115 delegate->InstallUIProceed();
116 }
dchengae36a4a2014-10-21 12:36:36117 void OnInstallSuccess(const Extension* extension, SkBitmap* icon) override {
[email protected]f8636f92013-08-09 21:02:37118 proxy_->set_extension_id(extension->id());
ki.stfuc4f8e242015-10-09 20:40:20119 base::MessageLoopForUI::current()->QuitWhenIdle();
[email protected]a01e00632010-11-05 16:58:14120 }
ginkage47e603e2015-02-27 08:42:41121 void OnInstallFailure(const CrxInstallError& error) override {
[email protected]f8636f92013-08-09 21:02:37122 proxy_->set_error(error.message());
ki.stfuc4f8e242015-10-09 20:40:20123 base::MessageLoopForUI::current()->QuitWhenIdle();
[email protected]a01e00632010-11-05 16:58:14124 }
125
126 private:
[email protected]f8636f92013-08-09 21:02:37127 scoped_refptr<MockPromptProxy> proxy_;
[email protected]a01e00632010-11-05 16:58:14128};
129
[email protected]658eae52014-06-14 20:28:05130MockPromptProxy::MockPromptProxy(content::WebContents* web_contents)
131 : web_contents_(web_contents), confirmation_requested_(false) {
[email protected]f8636f92013-08-09 21:02:37132}
133
134MockPromptProxy::~MockPromptProxy() {}
135
136scoped_ptr<ExtensionInstallPrompt> MockPromptProxy::CreatePrompt() {
137 scoped_ptr<MockInstallPrompt> prompt(
138 new MockInstallPrompt(web_contents_, this));
139 if (record_oauth2_grant_.get())
140 prompt->set_record_oauth2_grant(*record_oauth2_grant_.get());
dchengcf850d362014-10-16 17:26:42141 return prompt.Pass();
[email protected]f8636f92013-08-09 21:02:37142}
143
144
145scoped_refptr<MockPromptProxy> CreateMockPromptProxyForBrowser(
146 Browser* browser) {
147 return new MockPromptProxy(
[email protected]91e51d612012-10-21 23:03:05148 browser->tab_strip_model()->GetActiveWebContents());
[email protected]619f86182012-07-03 21:30:18149}
150
[email protected]253fc2bb2014-07-10 04:21:18151class ManagementPolicyMock : public extensions::ManagementPolicy::Provider {
152 public:
153 ManagementPolicyMock() {}
154
dchengae36a4a2014-10-21 12:36:36155 std::string GetDebugPolicyProviderName() const override {
[email protected]253fc2bb2014-07-10 04:21:18156 return "ManagementPolicyMock";
157 }
158
dchengae36a4a2014-10-21 12:36:36159 bool UserMayLoad(const Extension* extension,
160 base::string16* error) const override {
[email protected]253fc2bb2014-07-10 04:21:18161 *error = base::UTF8ToUTF16("Dummy error message");
162 return false;
163 }
164};
165
kalmanae342c92014-12-12 22:04:23166// Appends "enable-experimental-extension-apis" to the command line for the
167// lifetime of this class.
168class ScopedExperimentalCommandLine {
169 public:
avi3ef9ec9e2014-12-22 22:50:17170 ScopedExperimentalCommandLine()
171 : saved_(*base::CommandLine::ForCurrentProcess()) {
172 base::CommandLine::ForCurrentProcess()->AppendSwitch(
kalmanae342c92014-12-12 22:04:23173 switches::kEnableExperimentalExtensionApis);
174 }
175
176 ~ScopedExperimentalCommandLine() {
avi3ef9ec9e2014-12-22 22:50:17177 *base::CommandLine::ForCurrentProcess() = saved_;
kalmanae342c92014-12-12 22:04:23178 }
179
180 private:
avi3ef9ec9e2014-12-22 22:50:17181 base::CommandLine saved_;
kalmanae342c92014-12-12 22:04:23182};
183
[email protected]a01e00632010-11-05 16:58:14184} // namespace
185
186class ExtensionCrxInstallerTest : public ExtensionBrowserTest {
kalmanae342c92014-12-12 22:04:23187 protected:
[email protected]85290822013-08-23 20:27:38188 scoped_ptr<WebstoreInstaller::Approval> GetApproval(
189 const char* manifest_dir,
[email protected]b70a2d92012-06-28 19:51:21190 const std::string& id,
[email protected]85290822013-08-23 20:27:38191 bool strict_manifest_checks) {
192 scoped_ptr<WebstoreInstaller::Approval> result;
193
194 base::FilePath ext_path = test_data_dir_.AppendASCII(manifest_dir);
195 std::string error;
196 scoped_ptr<base::DictionaryValue> parsed_manifest(
[email protected]85df9d12014-04-15 17:02:14197 file_util::LoadManifest(ext_path, &error));
[email protected]85290822013-08-23 20:27:38198 if (!parsed_manifest.get() || !error.empty())
199 return result.Pass();
200
201 return WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
202 browser()->profile(),
203 id,
204 parsed_manifest.Pass(),
205 strict_manifest_checks);
206 }
207
208 void RunCrxInstaller(const WebstoreInstaller::Approval* approval,
209 scoped_ptr<ExtensionInstallPrompt> prompt,
210 const base::FilePath& crx_path) {
[email protected]06bdd2b2012-11-30 18:47:13211 ExtensionService* service = extensions::ExtensionSystem::Get(
212 browser()->profile())->extension_service();
[email protected]a01e00632010-11-05 16:58:14213 scoped_refptr<CrxInstaller> installer(
[email protected]85290822013-08-23 20:27:38214 CrxInstaller::Create(service, prompt.Pass(), approval));
[email protected]a01e00632010-11-05 16:58:14215 installer->set_allow_silent_install(true);
[email protected]b1f04cc2010-11-10 22:59:30216 installer->set_is_gallery_install(true);
[email protected]85290822013-08-23 20:27:38217 installer->InstallCrx(crx_path);
[email protected]729eb632012-07-26 04:45:26218 content::RunMessageLoop();
[email protected]85290822013-08-23 20:27:38219 }
220
221 // Installs a crx from |crx_relpath| (a path relative to the extension test
222 // data dir) with expected id |id|.
223 void InstallWithPrompt(const char* ext_relpath,
224 const std::string& id,
225 scoped_refptr<MockPromptProxy> mock_install_prompt) {
226 base::FilePath ext_path = test_data_dir_.AppendASCII(ext_relpath);
227
228 scoped_ptr<WebstoreInstaller::Approval> approval;
229 if (!id.empty())
230 approval = GetApproval(ext_relpath, id, true);
231
232 base::FilePath crx_path = PackExtension(ext_path);
233 EXPECT_FALSE(crx_path.empty());
234 RunCrxInstaller(approval.get(), mock_install_prompt->CreatePrompt(),
235 crx_path);
[email protected]a01e00632010-11-05 16:58:14236
[email protected]c82da8c42012-06-08 19:49:11237 EXPECT_TRUE(mock_install_prompt->did_succeed());
[email protected]b70a2d92012-06-28 19:51:21238 }
239
240 // Installs an extension and checks that it has scopes granted IFF
241 // |record_oauth2_grant| is true.
242 void CheckHasEmptyScopesAfterInstall(const std::string& ext_relpath,
243 bool record_oauth2_grant) {
kalmanae342c92014-12-12 22:04:23244 ScopedExperimentalCommandLine scope;
[email protected]b70a2d92012-06-28 19:51:21245
[email protected]f8636f92013-08-09 21:02:37246 scoped_refptr<MockPromptProxy> mock_prompt =
247 CreateMockPromptProxyForBrowser(browser());
248
[email protected]b70a2d92012-06-28 19:51:21249 mock_prompt->set_record_oauth2_grant(record_oauth2_grant);
[email protected]85290822013-08-23 20:27:38250 InstallWithPrompt("browsertest/scopes", std::string(), mock_prompt);
[email protected]b70a2d92012-06-28 19:51:21251
rdevlin.cronine2d0fd02015-09-24 22:35:49252 scoped_ptr<const PermissionSet> permissions =
[email protected]7c82539c2014-02-19 06:09:17253 ExtensionPrefs::Get(browser()->profile())
254 ->GetGrantedPermissions(mock_prompt->extension_id());
[email protected]b70a2d92012-06-28 19:51:21255 ASSERT_TRUE(permissions.get());
[email protected]a01e00632010-11-05 16:58:14256 }
kalmanae342c92014-12-12 22:04:23257
258 // Returns a FilePath to an unpacked "experimental" extension (a test
259 // Extension which requests the "experimental" permission).
260 base::FilePath PackExperimentalExtension() {
261 // We must modify the command line temporarily in order to pack an
262 // extension that requests the experimental permission.
263 ScopedExperimentalCommandLine scope;
264 base::FilePath test_path = test_data_dir_.AppendASCII("experimental");
265 base::FilePath crx_path = PackExtension(test_path);
266 CHECK(!crx_path.empty()) << "Extension not found at " << test_path.value();
267 return crx_path;
268 }
[email protected]a01e00632010-11-05 16:58:14269};
270
[email protected]d4b4d7af2014-08-20 10:45:15271// This test is skipped on ChromeOS because it requires the NPAPI,
272// which is not available on that platform.
273#if !defined(OS_CHROMEOS)
274IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Whitelisting) {
[email protected]21a5ad62012-04-03 04:48:45275 std::string id = "hdgllgikmikobbofgnabhfimcfoopgnd";
gpdavis.chromium48f08c42014-09-18 22:09:34276 ExtensionRegistry* registry = ExtensionRegistry::Get(
277 browser()->profile());
[email protected]21a5ad62012-04-03 04:48:45278
279 // Even whitelisted extensions with NPAPI should not prompt.
[email protected]f8636f92013-08-09 21:02:37280 scoped_refptr<MockPromptProxy> mock_prompt =
281 CreateMockPromptProxyForBrowser(browser());
[email protected]85290822013-08-23 20:27:38282 InstallWithPrompt("uitest/plugins", id, mock_prompt);
[email protected]b70a2d92012-06-28 19:51:21283 EXPECT_FALSE(mock_prompt->confirmation_requested());
gpdavis.chromium48f08c42014-09-18 22:09:34284 EXPECT_TRUE(registry->enabled_extensions().GetByID(id));
[email protected]a01e00632010-11-05 16:58:14285}
[email protected]d4b4d7af2014-08-20 10:45:15286#endif
[email protected]fc38935a2011-10-31 23:53:28287
288IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
kalmanae342c92014-12-12 22:04:23289 ExperimentalExtensionFromGallery) {
290 // Gallery-installed extensions should have their experimental permission
291 // preserved, since we allow the Webstore to make that decision.
292 base::FilePath crx_path = PackExperimentalExtension();
293 const Extension* extension = InstallExtensionFromWebstore(crx_path, 1);
294 ASSERT_TRUE(extension);
295 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
296 APIPermission::kExperimental));
297}
[email protected]240cc92a2011-12-01 01:22:24298
kalmanae342c92014-12-12 22:04:23299IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
300 ExperimentalExtensionFromOutsideGallery) {
301 // Non-gallery-installed extensions should lose their experimental
302 // permission if the flag isn't enabled.
303 base::FilePath crx_path = PackExperimentalExtension();
304 const Extension* extension = InstallExtension(crx_path, 1);
305 ASSERT_TRUE(extension);
306 EXPECT_FALSE(extension->permissions_data()->HasAPIPermission(
307 APIPermission::kExperimental));
308}
[email protected]240cc92a2011-12-01 01:22:24309
kalmanae342c92014-12-12 22:04:23310IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
311 ExperimentalExtensionFromOutsideGalleryWithFlag) {
312 // Non-gallery-installed extensions should maintain their experimental
313 // permission if the flag is enabled.
314 base::FilePath crx_path = PackExperimentalExtension();
315 ScopedExperimentalCommandLine scope;
316 const Extension* extension = InstallExtension(crx_path, 1);
317 ASSERT_TRUE(extension);
318 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
319 APIPermission::kExperimental));
[email protected]fc38935a2011-10-31 23:53:28320}
[email protected]ee14cad2012-03-29 01:59:37321
322IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, PlatformAppCrx) {
kalmanae342c92014-12-12 22:04:23323 ScopedExperimentalCommandLine scope;
[email protected]ee14cad2012-03-29 01:59:37324 EXPECT_TRUE(InstallExtension(
[email protected]dc37b002012-04-23 23:02:26325 test_data_dir_.AppendASCII("minimal_platform_app.crx"), 1));
[email protected]ee14cad2012-03-29 01:59:37326}
[email protected]bf2fcd52012-04-16 22:59:39327
[email protected]d4b4d7af2014-08-20 10:45:15328IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, PackAndInstallExtension) {
[email protected]544471a2012-10-13 05:27:09329 if (!FeatureSwitch::easy_off_store_install()->IsEnabled())
[email protected]89019d62012-05-17 18:47:09330 return;
331
[email protected]bf2fcd52012-04-16 22:59:39332 const int kNumDownloadsExpected = 1;
[email protected]bf2fcd52012-04-16 22:59:39333
334 LOG(ERROR) << "PackAndInstallExtension: Packing extension";
[email protected]650b2d52013-02-10 03:41:45335 base::FilePath crx_path = PackExtension(
[email protected]bf2fcd52012-04-16 22:59:39336 test_data_dir_.AppendASCII("common/background_page"));
337 ASSERT_FALSE(crx_path.empty());
338 std::string crx_path_string(crx_path.value().begin(), crx_path.value().end());
339 GURL url = GURL(std::string("file:///").append(crx_path_string));
340
[email protected]f8636f92013-08-09 21:02:37341 scoped_refptr<MockPromptProxy> mock_prompt =
342 CreateMockPromptProxyForBrowser(browser());
343 download_crx_util::SetMockInstallPromptForTesting(
344 mock_prompt->CreatePrompt());
[email protected]bf2fcd52012-04-16 22:59:39345
346 LOG(ERROR) << "PackAndInstallExtension: Getting download manager";
347 content::DownloadManager* download_manager =
[email protected]b441a8492012-06-06 14:55:57348 content::BrowserContext::GetDownloadManager(browser()->profile());
[email protected]bf2fcd52012-04-16 22:59:39349
350 LOG(ERROR) << "PackAndInstallExtension: Setting observer";
[email protected]49b264f2012-08-14 17:12:26351 scoped_ptr<content::DownloadTestObserver> observer(
352 new content::DownloadTestObserverTerminal(
[email protected]47665442012-07-27 02:31:22353 download_manager, kNumDownloadsExpected,
[email protected]49b264f2012-08-14 17:12:26354 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT));
[email protected]bf2fcd52012-04-16 22:59:39355 LOG(ERROR) << "PackAndInstallExtension: Navigating to URL";
356 ui_test_utils::NavigateToURLWithDisposition(browser(), url, CURRENT_TAB,
357 ui_test_utils::BROWSER_TEST_NONE);
358
[email protected]8c6af5b2012-06-15 20:10:26359 EXPECT_TRUE(WaitForCrxInstallerDone());
[email protected]bf2fcd52012-04-16 22:59:39360 LOG(ERROR) << "PackAndInstallExtension: Extension install";
[email protected]c82da8c42012-06-08 19:49:11361 EXPECT_TRUE(mock_prompt->confirmation_requested());
[email protected]bf2fcd52012-04-16 22:59:39362 LOG(ERROR) << "PackAndInstallExtension: Extension install confirmed";
363}
[email protected]a9736892012-05-30 15:58:05364
[email protected]b70a2d92012-06-28 19:51:21365// Tests that scopes are only granted if |record_oauth2_grant_| on the prompt is
366// true.
[email protected]7a561912012-08-21 21:06:05367#if defined(OS_WIN)
[email protected]1e09ec82012-12-21 22:48:09368#define MAYBE_GrantScopes DISABLED_GrantScopes
[email protected]7a561912012-08-21 21:06:05369#else
370#define MAYBE_GrantScopes GrantScopes
371#endif
372IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, MAYBE_GrantScopes) {
[email protected]b70a2d92012-06-28 19:51:21373 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes",
374 true));
375}
376
377IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotGrantScopes) {
378 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes",
379 false));
380}
381
[email protected]d4b4d7af2014-08-20 10:45:15382IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, AllowOffStore) {
[email protected]06bdd2b2012-11-30 18:47:13383 ExtensionService* service = extensions::ExtensionSystem::Get(
384 browser()->profile())->extension_service();
[email protected]a9736892012-05-30 15:58:05385 const bool kTestData[] = {false, true};
386
387 for (size_t i = 0; i < arraysize(kTestData); ++i) {
[email protected]f8636f92013-08-09 21:02:37388 scoped_refptr<MockPromptProxy> mock_prompt =
389 CreateMockPromptProxyForBrowser(browser());
390
[email protected]a9736892012-05-30 15:58:05391 scoped_refptr<CrxInstaller> crx_installer(
[email protected]f8636f92013-08-09 21:02:37392 CrxInstaller::Create(service, mock_prompt->CreatePrompt()));
[email protected]7224dbd2012-06-05 15:21:50393 crx_installer->set_install_cause(
394 extension_misc::INSTALL_CAUSE_USER_DOWNLOAD);
[email protected]d9039812012-06-09 06:05:48395
396 if (kTestData[i]) {
397 crx_installer->set_off_store_install_allow_reason(
398 CrxInstaller::OffStoreInstallAllowedInTest);
399 }
[email protected]a9736892012-05-30 15:58:05400
401 crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
[email protected]d4b4d7af2014-08-20 10:45:15402 // The |mock_prompt| will quit running the loop once the |crx_installer|
403 // is done.
404 content::RunMessageLoop();
[email protected]c82da8c42012-06-08 19:49:11405 EXPECT_EQ(kTestData[i], mock_prompt->did_succeed());
406 EXPECT_EQ(kTestData[i], mock_prompt->confirmation_requested()) <<
407 kTestData[i];
[email protected]a9736892012-05-30 15:58:05408 if (kTestData[i]) {
[email protected]b959d7d42013-12-13 17:26:37409 EXPECT_EQ(base::string16(), mock_prompt->error()) << kTestData[i];
[email protected]a9736892012-05-30 15:58:05410 } else {
411 EXPECT_EQ(l10n_util::GetStringUTF16(
412 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE),
[email protected]c82da8c42012-06-08 19:49:11413 mock_prompt->error()) << kTestData[i];
[email protected]a9736892012-05-30 15:58:05414 }
415 }
[email protected]a9736892012-05-30 15:58:05416}
[email protected]bf3d9df2012-07-24 23:20:27417
[email protected]90d3c042013-06-06 10:10:39418IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, HiDpiThemeTest) {
419 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx");
420 crx_path = crx_path.AppendASCII("theme_hidpi.crx");
421
[email protected]658eae52014-06-14 20:28:05422 ASSERT_TRUE(InstallExtension(crx_path, 1));
[email protected]90d3c042013-06-06 10:10:39423
424 const std::string extension_id("gllekhaobjnhgeagipipnkpmmmpchacm");
gpdavis.chromium48f08c42014-09-18 22:09:34425 ExtensionRegistry* registry = ExtensionRegistry::Get(
426 browser()->profile());
[email protected]90d3c042013-06-06 10:10:39427 const extensions::Extension* extension =
gpdavis.chromium48f08c42014-09-18 22:09:34428 registry->enabled_extensions().GetByID(extension_id);
[email protected]90d3c042013-06-06 10:10:39429 ASSERT_TRUE(extension);
430 EXPECT_EQ(extension_id, extension->id());
431
432 UninstallExtension(extension_id);
gpdavis.chromium48f08c42014-09-18 22:09:34433 EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id));
[email protected]90d3c042013-06-06 10:10:39434}
435
[email protected]9e9c1d12013-07-31 01:58:12436IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest,
mekc95f9d062015-01-10 00:52:04437 InstallDelayedUntilNextUpdate) {
[email protected]9e9c1d12013-07-31 01:58:12438 const std::string extension_id("ldnnhddmnhbkjipkidpdiheffobcpfmf");
mekc95f9d062015-01-10 00:52:04439 base::FilePath base_path = test_data_dir_.AppendASCII("delayed_install");
440
[email protected]9e9c1d12013-07-31 01:58:12441 ExtensionSystem* extension_system = extensions::ExtensionSystem::Get(
442 browser()->profile());
443 ExtensionService* service = extension_system->extension_service();
444 ASSERT_TRUE(service);
gpdavis.chromium48f08c42014-09-18 22:09:34445 ExtensionRegistry* registry = ExtensionRegistry::Get(
446 browser()->profile());
447 ASSERT_TRUE(registry);
[email protected]9e9c1d12013-07-31 01:58:12448
449 // Install version 1 of the test extension. This extension does not have
450 // a background page but does have a browser action.
mekc95f9d062015-01-10 00:52:04451 base::FilePath v1_path = PackExtension(base_path.AppendASCII("v1"));
452 ASSERT_FALSE(v1_path.empty());
453 ASSERT_TRUE(InstallExtension(v1_path, 1));
[email protected]9e9c1d12013-07-31 01:58:12454 const extensions::Extension* extension =
gpdavis.chromium48f08c42014-09-18 22:09:34455 registry->enabled_extensions().GetByID(extension_id);
[email protected]9e9c1d12013-07-31 01:58:12456 ASSERT_TRUE(extension);
457 ASSERT_EQ(extension_id, extension->id());
458 ASSERT_EQ("1.0", extension->version()->GetString());
459
mekc95f9d062015-01-10 00:52:04460 // Make test extension non-idle by opening the extension's options page.
461 ExtensionTabUtil::OpenOptionsPage(extension, browser());
462 WaitForExtensionNotIdle(extension_id);
[email protected]9e9c1d12013-07-31 01:58:12463
464 // Install version 2 of the extension and check that it is indeed delayed.
mekc95f9d062015-01-10 00:52:04465 base::FilePath v2_path = PackExtension(base_path.AppendASCII("v2"));
466 ASSERT_FALSE(v2_path.empty());
467 ASSERT_TRUE(UpdateExtensionWaitForIdle(extension_id, v2_path, 0));
[email protected]9e9c1d12013-07-31 01:58:12468
469 ASSERT_EQ(1u, service->delayed_installs()->size());
gpdavis.chromium48f08c42014-09-18 22:09:34470 extension = registry->enabled_extensions().GetByID(extension_id);
[email protected]9e9c1d12013-07-31 01:58:12471 ASSERT_EQ("1.0", extension->version()->GetString());
472
mekc95f9d062015-01-10 00:52:04473 // Make the extension idle again by navigating away from the options page.
474 // This should not trigger the delayed install.
475 ui_test_utils::NavigateToURL(browser(), GURL("about:blank"));
476 WaitForExtensionIdle(extension_id);
[email protected]9e9c1d12013-07-31 01:58:12477 ASSERT_EQ(1u, service->delayed_installs()->size());
mekc95f9d062015-01-10 00:52:04478 extension = registry->enabled_extensions().GetByID(extension_id);
479 ASSERT_EQ("1.0", extension->version()->GetString());
[email protected]9e9c1d12013-07-31 01:58:12480
481 // Install version 3 of the extension. Because the extension is idle,
482 // this install should succeed.
mekc95f9d062015-01-10 00:52:04483 base::FilePath v3_path = PackExtension(base_path.AppendASCII("v3"));
484 ASSERT_FALSE(v3_path.empty());
485 ASSERT_TRUE(UpdateExtensionWaitForIdle(extension_id, v3_path, 0));
gpdavis.chromium48f08c42014-09-18 22:09:34486 extension = registry->enabled_extensions().GetByID(extension_id);
[email protected]9e9c1d12013-07-31 01:58:12487 ASSERT_EQ("3.0", extension->version()->GetString());
488
489 // The version 2 delayed install should be cleaned up, and finishing
490 // delayed extension installation shouldn't break anything.
491 ASSERT_EQ(0u, service->delayed_installs()->size());
492 service->MaybeFinishDelayedInstallations();
gpdavis.chromium48f08c42014-09-18 22:09:34493 extension = registry->enabled_extensions().GetByID(extension_id);
[email protected]9e9c1d12013-07-31 01:58:12494 ASSERT_EQ("3.0", extension->version()->GetString());
495}
496
[email protected]e3767aa2013-11-08 23:49:07497#if defined(FULL_SAFE_BROWSING)
[email protected]9f3c8532013-07-31 19:52:07498IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blacklist) {
[email protected]3f2a2fa2013-09-24 02:55:25499 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
500 new FakeSafeBrowsingDatabaseManager(true));
501 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
[email protected]9f3c8532013-07-31 19:52:07502
[email protected]3f2a2fa2013-09-24 02:55:25503 blacklist_db->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm");
[email protected]9f3c8532013-07-31 19:52:07504
505 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx")
506 .AppendASCII("theme_hidpi.crx");
507 EXPECT_FALSE(InstallExtension(crx_path, 0));
508}
[email protected]e3767aa2013-11-08 23:49:07509#endif
[email protected]9f3c8532013-07-31 19:52:07510
[email protected]85290822013-08-23 20:27:38511IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, NonStrictManifestCheck) {
512 scoped_refptr<MockPromptProxy> mock_prompt =
513 CreateMockPromptProxyForBrowser(browser());
514
515 // We want to simulate the case where the webstore sends a more recent
516 // version of the manifest, but the downloaded .crx file is old since
517 // the newly published version hasn't fully propagated to all the download
518 // servers yet. So load the v2 manifest, but then install the v1 crx file.
519 std::string id = "lhnaeclnpobnlbjbgogdanmhadigfnjp";
520 scoped_ptr<WebstoreInstaller::Approval> approval =
521 GetApproval("crx_installer/v2_no_permission_change/", id, false);
522
523 RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(),
524 test_data_dir_.AppendASCII("crx_installer/v1.crx"));
525
526 EXPECT_TRUE(mock_prompt->did_succeed());
527}
528
[email protected]14a18bf2013-09-26 08:42:30529IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, KioskOnlyTest) {
530 base::FilePath crx_path =
531 test_data_dir_.AppendASCII("kiosk/kiosk_only.crx");
532 EXPECT_FALSE(InstallExtension(crx_path, 0));
533#if defined(OS_CHROMEOS)
534 // Simulate ChromeOS kiosk mode. |scoped_user_manager| will take over
535 // lifetime of |user_manager|.
merkulova793f3022015-02-04 10:18:30536 chromeos::FakeChromeUserManager* fake_user_manager =
537 new chromeos::FakeChromeUserManager();
alemate3ffbde6f2015-11-03 02:02:55538 const AccountId account_id(AccountId::FromUserEmail("[email protected]"));
539 fake_user_manager->AddKioskAppUser(account_id);
540 fake_user_manager->LoginUser(account_id);
[email protected]14a18bf2013-09-26 08:42:30541 chromeos::ScopedUserManagerEnabler scoped_user_manager(fake_user_manager);
542 EXPECT_TRUE(InstallExtension(crx_path, 1));
543#endif
544}
545
[email protected]5a145e82014-05-29 22:19:07546#if defined(OS_CHROMEOS)
dpolukhincbd48d192015-06-04 14:09:37547IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallToSharedLocation) {
avi3ef9ec9e2014-12-22 22:50:17548 base::CommandLine::ForCurrentProcess()->AppendSwitch(
[email protected]5a145e82014-05-29 22:19:07549 chromeos::switches::kEnableExtensionAssetsSharing);
550 base::ScopedTempDir cache_dir;
551 ASSERT_TRUE(cache_dir.CreateUniqueTempDir());
552 ExtensionAssetsManagerChromeOS::SetSharedInstallDirForTesting(
553 cache_dir.path());
554
555 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx");
556 const extensions::Extension* extension = InstallExtension(
557 crx_path, 1, extensions::Manifest::EXTERNAL_PREF);
558 base::FilePath extension_path = extension->path();
559 EXPECT_TRUE(cache_dir.path().IsParent(extension_path));
560 EXPECT_TRUE(base::PathExists(extension_path));
561
562 std::string extension_id = extension->id();
563 UninstallExtension(extension_id);
gpdavis.chromium48f08c42014-09-18 22:09:34564 ExtensionRegistry* registry = ExtensionRegistry::Get(
565 browser()->profile());
566 EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id));
[email protected]5a145e82014-05-29 22:19:07567
mtomaszf7d99a5c2014-09-15 16:23:46568 content::RunAllBlockingPoolTasksUntilIdle();
[email protected]5a145e82014-05-29 22:19:07569
570 EXPECT_FALSE(base::PathExists(extension_path));
571}
572#endif
573
[email protected]658eae52014-06-14 20:28:05574IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotSync) {
575 ExtensionService* service = extensions::ExtensionSystem::Get(
576 browser()->profile())->extension_service();
577 scoped_refptr<CrxInstaller> crx_installer(
578 CrxInstaller::CreateSilent(service));
[email protected]c30bda262014-06-19 04:10:13579 crx_installer->set_do_not_sync(true);
[email protected]658eae52014-06-14 20:28:05580 crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx"));
581 EXPECT_TRUE(WaitForCrxInstallerDone());
582 ASSERT_TRUE(crx_installer->extension());
583
584 const ExtensionPrefs* extension_prefs =
585 ExtensionPrefs::Get(browser()->profile());
586 EXPECT_TRUE(extension_prefs->DoNotSync(crx_installer->extension()->id()));
treibc644a1c2015-07-13 08:37:04587 EXPECT_FALSE(extensions::util::ShouldSync(crx_installer->extension(),
588 browser()->profile()));
[email protected]658eae52014-06-14 20:28:05589}
590
[email protected]253fc2bb2014-07-10 04:21:18591IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, ManagementPolicy) {
592 ManagementPolicyMock policy;
593 extensions::ExtensionSystem::Get(profile())
594 ->management_policy()
595 ->RegisterProvider(&policy);
596
597 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx");
598 EXPECT_FALSE(InstallExtension(crx_path, 0));
599}
600
[email protected]bf3d9df2012-07-24 23:20:27601} // namespace extensions