1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/crx_installer.h"
7 #include "base/at_exit.h"
8 #include "base/memory/ref_counted.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/download/download_crx_util.h"
11 #include "chrome/browser/extensions/browser_action_test_util.h"
12 #include "chrome/browser/extensions/extension_browsertest.h"
13 #include "chrome/browser/extensions/extension_install_prompt.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/extensions/extension_util.h"
16 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
17 #include "chrome/browser/extensions/test_extension_dir.h"
18 #include "chrome/browser/profiles/profile.h"
19 #include "chrome/browser/ui/browser.h"
20 #include "chrome/browser/ui/browser_window.h"
21 #include "chrome/browser/ui/tabs/tab_strip_model.h"
22 #include "chrome/grit/generated_resources.h"
23 #include "chrome/test/base/ui_test_utils.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/download_manager.h"
26 #include "content/public/browser/render_view_host.h"
27 #include "content/public/test/browser_test_utils.h"
28 #include "content/public/test/download_test_observer.h"
29 #include "content/public/test/test_utils.h"
30 #include "extensions/browser/extension_prefs.h"
31 #include "extensions/browser/extension_registry.h"
32 #include "extensions/browser/extension_system.h"
33 #include "extensions/browser/install/crx_installer_error.h"
34 #include "extensions/browser/management_policy.h"
35 #include "extensions/browser/notification_types.h"
36 #include "extensions/common/extension.h"
37 #include "extensions/common/feature_switch.h"
38 #include "extensions/common/file_util.h"
39 #include "extensions/common/permissions/permission_set.h"
40 #include "extensions/common/switches.h"
41 #include "ui/base/l10n/l10n_util.h"
43 #if defined(OS_CHROMEOS)
44 #include "chrome/browser/chromeos/login/users/fake_user_manager.h"
45 #include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h"
46 #include "chrome/browser/extensions/extension_assets_manager_chromeos.h"
47 #include "chromeos/chromeos_switches.h"
52 namespace extensions
{
56 class MockInstallPrompt
;
58 // This class holds information about things that happen with a
59 // MockInstallPrompt. We create the MockInstallPrompt but need to pass
60 // ownership of it to CrxInstaller, so it isn't safe to hang this data on
61 // MockInstallPrompt itself becuase we can't guarantee it's lifetime.
62 class MockPromptProxy
: public base::RefCountedThreadSafe
<MockPromptProxy
> {
64 explicit MockPromptProxy(content::WebContents
* web_contents
);
66 bool did_succeed() const { return !extension_id_
.empty(); }
67 const std::string
& extension_id() { return extension_id_
; }
68 bool confirmation_requested() const { return confirmation_requested_
; }
69 const base::string16
& error() const { return error_
; }
71 // To have any effect, this should be called before CreatePrompt.
72 void set_record_oauth2_grant(bool record_oauth2_grant
) {
73 record_oauth2_grant_
.reset(new bool(record_oauth2_grant
));
76 void set_extension_id(const std::string
& id
) { extension_id_
= id
; }
77 void set_confirmation_requested() { confirmation_requested_
= true; }
78 void set_error(const base::string16
& error
) { error_
= error
; }
80 scoped_ptr
<ExtensionInstallPrompt
> CreatePrompt();
83 friend class base::RefCountedThreadSafe
<MockPromptProxy
>;
84 virtual ~MockPromptProxy();
86 // Data used to create a prompt.
87 content::WebContents
* web_contents_
;
88 scoped_ptr
<bool> record_oauth2_grant_
;
90 // Data reported back to us by the prompt we created.
91 bool confirmation_requested_
;
92 std::string extension_id_
;
93 base::string16 error_
;
96 class MockInstallPrompt
: public ExtensionInstallPrompt
{
98 MockInstallPrompt(content::WebContents
* web_contents
,
99 MockPromptProxy
* proxy
) :
100 ExtensionInstallPrompt(web_contents
),
103 void set_record_oauth2_grant(bool record
) { record_oauth2_grant_
= record
; }
105 // Overriding some of the ExtensionInstallUI API.
106 void ConfirmInstall(Delegate
* delegate
,
107 const Extension
* extension
,
108 const ShowDialogCallback
& show_dialog_callback
) override
{
109 proxy_
->set_confirmation_requested();
110 delegate
->InstallUIProceed();
112 void OnInstallSuccess(const Extension
* extension
, SkBitmap
* icon
) override
{
113 proxy_
->set_extension_id(extension
->id());
114 base::MessageLoopForUI::current()->Quit();
116 void OnInstallFailure(const CrxInstallerError
& error
) override
{
117 proxy_
->set_error(error
.message());
118 base::MessageLoopForUI::current()->Quit();
122 scoped_refptr
<MockPromptProxy
> proxy_
;
125 MockPromptProxy::MockPromptProxy(content::WebContents
* web_contents
)
126 : web_contents_(web_contents
), confirmation_requested_(false) {
129 MockPromptProxy::~MockPromptProxy() {}
131 scoped_ptr
<ExtensionInstallPrompt
> MockPromptProxy::CreatePrompt() {
132 scoped_ptr
<MockInstallPrompt
> prompt(
133 new MockInstallPrompt(web_contents_
, this));
134 if (record_oauth2_grant_
.get())
135 prompt
->set_record_oauth2_grant(*record_oauth2_grant_
.get());
136 return prompt
.Pass();
140 scoped_refptr
<MockPromptProxy
> CreateMockPromptProxyForBrowser(
142 return new MockPromptProxy(
143 browser
->tab_strip_model()->GetActiveWebContents());
146 class ManagementPolicyMock
: public extensions::ManagementPolicy::Provider
{
148 ManagementPolicyMock() {}
150 std::string
GetDebugPolicyProviderName() const override
{
151 return "ManagementPolicyMock";
154 bool UserMayLoad(const Extension
* extension
,
155 base::string16
* error
) const override
{
156 *error
= base::UTF8ToUTF16("Dummy error message");
163 class ExtensionCrxInstallerTest
: public ExtensionBrowserTest
{
165 scoped_ptr
<WebstoreInstaller::Approval
> GetApproval(
166 const char* manifest_dir
,
167 const std::string
& id
,
168 bool strict_manifest_checks
) {
169 scoped_ptr
<WebstoreInstaller::Approval
> result
;
171 base::FilePath ext_path
= test_data_dir_
.AppendASCII(manifest_dir
);
173 scoped_ptr
<base::DictionaryValue
> parsed_manifest(
174 file_util::LoadManifest(ext_path
, &error
));
175 if (!parsed_manifest
.get() || !error
.empty())
176 return result
.Pass();
178 return WebstoreInstaller::Approval::CreateWithNoInstallPrompt(
179 browser()->profile(),
181 parsed_manifest
.Pass(),
182 strict_manifest_checks
);
185 void RunCrxInstaller(const WebstoreInstaller::Approval
* approval
,
186 scoped_ptr
<ExtensionInstallPrompt
> prompt
,
187 const base::FilePath
& crx_path
) {
188 ExtensionService
* service
= extensions::ExtensionSystem::Get(
189 browser()->profile())->extension_service();
190 scoped_refptr
<CrxInstaller
> installer(
191 CrxInstaller::Create(service
, prompt
.Pass(), approval
));
192 installer
->set_allow_silent_install(true);
193 installer
->set_is_gallery_install(true);
194 installer
->InstallCrx(crx_path
);
195 content::RunMessageLoop();
198 // Installs a crx from |crx_relpath| (a path relative to the extension test
199 // data dir) with expected id |id|.
200 void InstallWithPrompt(const char* ext_relpath
,
201 const std::string
& id
,
202 scoped_refptr
<MockPromptProxy
> mock_install_prompt
) {
203 base::FilePath ext_path
= test_data_dir_
.AppendASCII(ext_relpath
);
205 scoped_ptr
<WebstoreInstaller::Approval
> approval
;
207 approval
= GetApproval(ext_relpath
, id
, true);
209 base::FilePath crx_path
= PackExtension(ext_path
);
210 EXPECT_FALSE(crx_path
.empty());
211 RunCrxInstaller(approval
.get(), mock_install_prompt
->CreatePrompt(),
214 EXPECT_TRUE(mock_install_prompt
->did_succeed());
217 // Installs an extension and checks that it has scopes granted IFF
218 // |record_oauth2_grant| is true.
219 void CheckHasEmptyScopesAfterInstall(const std::string
& ext_relpath
,
220 bool record_oauth2_grant
) {
221 CommandLine::ForCurrentProcess()->AppendSwitch(
222 switches::kEnableExperimentalExtensionApis
);
224 scoped_refptr
<MockPromptProxy
> mock_prompt
=
225 CreateMockPromptProxyForBrowser(browser());
227 mock_prompt
->set_record_oauth2_grant(record_oauth2_grant
);
228 InstallWithPrompt("browsertest/scopes", std::string(), mock_prompt
);
230 scoped_refptr
<PermissionSet
> permissions
=
231 ExtensionPrefs::Get(browser()->profile())
232 ->GetGrantedPermissions(mock_prompt
->extension_id());
233 ASSERT_TRUE(permissions
.get());
237 // This test is skipped on ChromeOS because it requires the NPAPI,
238 // which is not available on that platform.
239 #if !defined(OS_CHROMEOS)
240 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, Whitelisting
) {
241 std::string id
= "hdgllgikmikobbofgnabhfimcfoopgnd";
242 ExtensionRegistry
* registry
= ExtensionRegistry::Get(
243 browser()->profile());
245 // Even whitelisted extensions with NPAPI should not prompt.
246 scoped_refptr
<MockPromptProxy
> mock_prompt
=
247 CreateMockPromptProxyForBrowser(browser());
248 InstallWithPrompt("uitest/plugins", id
, mock_prompt
);
249 EXPECT_FALSE(mock_prompt
->confirmation_requested());
250 EXPECT_TRUE(registry
->enabled_extensions().GetByID(id
));
254 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
,
255 GalleryInstallGetsExperimental
) {
256 // We must modify the command line temporarily in order to pack an extension
257 // that requests the experimental permission.
258 CommandLine
* command_line
= CommandLine::ForCurrentProcess();
259 CommandLine old_command_line
= *command_line
;
260 command_line
->AppendSwitch(switches::kEnableExperimentalExtensionApis
);
261 base::FilePath crx_path
= PackExtension(
262 test_data_dir_
.AppendASCII("experimental"));
263 ASSERT_FALSE(crx_path
.empty());
265 // Now reset the command line so that we are testing specifically whether
266 // installing from webstore enables experimental permissions.
267 *(CommandLine::ForCurrentProcess()) = old_command_line
;
269 EXPECT_FALSE(InstallExtension(crx_path
, 0));
270 EXPECT_TRUE(InstallExtensionFromWebstore(crx_path
, 1));
273 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, PlatformAppCrx
) {
274 CommandLine::ForCurrentProcess()->AppendSwitch(
275 switches::kEnableExperimentalExtensionApis
);
276 EXPECT_TRUE(InstallExtension(
277 test_data_dir_
.AppendASCII("minimal_platform_app.crx"), 1));
280 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, PackAndInstallExtension
) {
281 if (!FeatureSwitch::easy_off_store_install()->IsEnabled())
284 const int kNumDownloadsExpected
= 1;
286 LOG(ERROR
) << "PackAndInstallExtension: Packing extension";
287 base::FilePath crx_path
= PackExtension(
288 test_data_dir_
.AppendASCII("common/background_page"));
289 ASSERT_FALSE(crx_path
.empty());
290 std::string
crx_path_string(crx_path
.value().begin(), crx_path
.value().end());
291 GURL url
= GURL(std::string("file:///").append(crx_path_string
));
293 scoped_refptr
<MockPromptProxy
> mock_prompt
=
294 CreateMockPromptProxyForBrowser(browser());
295 download_crx_util::SetMockInstallPromptForTesting(
296 mock_prompt
->CreatePrompt());
298 LOG(ERROR
) << "PackAndInstallExtension: Getting download manager";
299 content::DownloadManager
* download_manager
=
300 content::BrowserContext::GetDownloadManager(browser()->profile());
302 LOG(ERROR
) << "PackAndInstallExtension: Setting observer";
303 scoped_ptr
<content::DownloadTestObserver
> observer(
304 new content::DownloadTestObserverTerminal(
305 download_manager
, kNumDownloadsExpected
,
306 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT
));
307 LOG(ERROR
) << "PackAndInstallExtension: Navigating to URL";
308 ui_test_utils::NavigateToURLWithDisposition(browser(), url
, CURRENT_TAB
,
309 ui_test_utils::BROWSER_TEST_NONE
);
311 EXPECT_TRUE(WaitForCrxInstallerDone());
312 LOG(ERROR
) << "PackAndInstallExtension: Extension install";
313 EXPECT_TRUE(mock_prompt
->confirmation_requested());
314 LOG(ERROR
) << "PackAndInstallExtension: Extension install confirmed";
317 // Tests that scopes are only granted if |record_oauth2_grant_| on the prompt is
320 #define MAYBE_GrantScopes DISABLED_GrantScopes
322 #define MAYBE_GrantScopes GrantScopes
324 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, MAYBE_GrantScopes
) {
325 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes",
329 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, DoNotGrantScopes
) {
330 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes",
334 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, AllowOffStore
) {
335 ExtensionService
* service
= extensions::ExtensionSystem::Get(
336 browser()->profile())->extension_service();
337 const bool kTestData
[] = {false, true};
339 for (size_t i
= 0; i
< arraysize(kTestData
); ++i
) {
340 scoped_refptr
<MockPromptProxy
> mock_prompt
=
341 CreateMockPromptProxyForBrowser(browser());
343 scoped_refptr
<CrxInstaller
> crx_installer(
344 CrxInstaller::Create(service
, mock_prompt
->CreatePrompt()));
345 crx_installer
->set_install_cause(
346 extension_misc::INSTALL_CAUSE_USER_DOWNLOAD
);
349 crx_installer
->set_off_store_install_allow_reason(
350 CrxInstaller::OffStoreInstallAllowedInTest
);
353 crx_installer
->InstallCrx(test_data_dir_
.AppendASCII("good.crx"));
354 // The |mock_prompt| will quit running the loop once the |crx_installer|
356 content::RunMessageLoop();
357 EXPECT_EQ(kTestData
[i
], mock_prompt
->did_succeed());
358 EXPECT_EQ(kTestData
[i
], mock_prompt
->confirmation_requested()) <<
361 EXPECT_EQ(base::string16(), mock_prompt
->error()) << kTestData
[i
];
363 EXPECT_EQ(l10n_util::GetStringUTF16(
364 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE
),
365 mock_prompt
->error()) << kTestData
[i
];
370 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, HiDpiThemeTest
) {
371 base::FilePath crx_path
= test_data_dir_
.AppendASCII("theme_hidpi_crx");
372 crx_path
= crx_path
.AppendASCII("theme_hidpi.crx");
374 ASSERT_TRUE(InstallExtension(crx_path
, 1));
376 const std::string
extension_id("gllekhaobjnhgeagipipnkpmmmpchacm");
377 ExtensionRegistry
* registry
= ExtensionRegistry::Get(
378 browser()->profile());
379 const extensions::Extension
* extension
=
380 registry
->enabled_extensions().GetByID(extension_id
);
381 ASSERT_TRUE(extension
);
382 EXPECT_EQ(extension_id
, extension
->id());
384 UninstallExtension(extension_id
);
385 EXPECT_FALSE(registry
->enabled_extensions().GetByID(extension_id
));
388 // See http://crbug.com/315299.
389 #if defined(OS_WIN) || defined(OS_LINUX)
390 #define MAYBE_InstallDelayedUntilNextUpdate \
391 DISABLED_InstallDelayedUntilNextUpdate
393 #define MAYBE_InstallDelayedUntilNextUpdate InstallDelayedUntilNextUpdate
395 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
,
396 MAYBE_InstallDelayedUntilNextUpdate
) {
397 const std::string
extension_id("ldnnhddmnhbkjipkidpdiheffobcpfmf");
398 base::FilePath crx_path
= test_data_dir_
.AppendASCII("delayed_install");
399 ExtensionSystem
* extension_system
= extensions::ExtensionSystem::Get(
400 browser()->profile());
401 ExtensionService
* service
= extension_system
->extension_service();
402 ASSERT_TRUE(service
);
403 ExtensionRegistry
* registry
= ExtensionRegistry::Get(
404 browser()->profile());
405 ASSERT_TRUE(registry
);
407 // Install version 1 of the test extension. This extension does not have
408 // a background page but does have a browser action.
409 ASSERT_TRUE(InstallExtension(crx_path
.AppendASCII("v1.crx"), 1));
410 const extensions::Extension
* extension
=
411 registry
->enabled_extensions().GetByID(extension_id
);
412 ASSERT_TRUE(extension
);
413 ASSERT_EQ(extension_id
, extension
->id());
414 ASSERT_EQ("1.0", extension
->version()->GetString());
416 // Make test extension non-idle by opening the extension's browser action
417 // popup. This should cause the installation to be delayed.
418 content::WindowedNotificationObserver
loading_observer(
419 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING
,
420 content::Source
<Profile
>(profile()));
421 BrowserActionTestUtil
util(browser());
422 // There is only one extension, so just click the first browser action.
423 ASSERT_EQ(1, util
.NumberOfBrowserActions());
425 loading_observer
.Wait();
426 ExtensionHost
* extension_host
=
427 content::Details
<ExtensionHost
>(loading_observer
.details()).ptr();
429 // Install version 2 of the extension and check that it is indeed delayed.
430 ASSERT_TRUE(UpdateExtensionWaitForIdle(
431 extension_id
, crx_path
.AppendASCII("v2.crx"), 0));
433 ASSERT_EQ(1u, service
->delayed_installs()->size());
434 extension
= registry
->enabled_extensions().GetByID(extension_id
);
435 ASSERT_EQ("1.0", extension
->version()->GetString());
437 // Make the extension idle again by closing the popup. This should not trigger
438 // the delayed install.
439 content::RenderProcessHostWatcher
terminated_observer(
440 extension_host
->render_process_host(),
441 content::RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION
);
442 extension_host
->render_view_host()->ClosePage();
443 terminated_observer
.Wait();
444 ASSERT_EQ(1u, service
->delayed_installs()->size());
446 // Install version 3 of the extension. Because the extension is idle,
447 // this install should succeed.
448 ASSERT_TRUE(UpdateExtensionWaitForIdle(
449 extension_id
, crx_path
.AppendASCII("v3.crx"), 0));
450 extension
= registry
->enabled_extensions().GetByID(extension_id
);
451 ASSERT_EQ("3.0", extension
->version()->GetString());
453 // The version 2 delayed install should be cleaned up, and finishing
454 // delayed extension installation shouldn't break anything.
455 ASSERT_EQ(0u, service
->delayed_installs()->size());
456 service
->MaybeFinishDelayedInstallations();
457 extension
= registry
->enabled_extensions().GetByID(extension_id
);
458 ASSERT_EQ("3.0", extension
->version()->GetString());
461 #if defined(FULL_SAFE_BROWSING)
462 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, Blacklist
) {
463 scoped_refptr
<FakeSafeBrowsingDatabaseManager
> blacklist_db(
464 new FakeSafeBrowsingDatabaseManager(true));
465 Blacklist::ScopedDatabaseManagerForTest
scoped_blacklist_db(blacklist_db
);
467 blacklist_db
->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm");
469 base::FilePath crx_path
= test_data_dir_
.AppendASCII("theme_hidpi_crx")
470 .AppendASCII("theme_hidpi.crx");
471 EXPECT_FALSE(InstallExtension(crx_path
, 0));
475 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, NonStrictManifestCheck
) {
476 scoped_refptr
<MockPromptProxy
> mock_prompt
=
477 CreateMockPromptProxyForBrowser(browser());
479 // We want to simulate the case where the webstore sends a more recent
480 // version of the manifest, but the downloaded .crx file is old since
481 // the newly published version hasn't fully propagated to all the download
482 // servers yet. So load the v2 manifest, but then install the v1 crx file.
483 std::string id
= "lhnaeclnpobnlbjbgogdanmhadigfnjp";
484 scoped_ptr
<WebstoreInstaller::Approval
> approval
=
485 GetApproval("crx_installer/v2_no_permission_change/", id
, false);
487 RunCrxInstaller(approval
.get(), mock_prompt
->CreatePrompt(),
488 test_data_dir_
.AppendASCII("crx_installer/v1.crx"));
490 EXPECT_TRUE(mock_prompt
->did_succeed());
493 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, KioskOnlyTest
) {
494 base::FilePath crx_path
=
495 test_data_dir_
.AppendASCII("kiosk/kiosk_only.crx");
496 EXPECT_FALSE(InstallExtension(crx_path
, 0));
497 #if defined(OS_CHROMEOS)
498 // Simulate ChromeOS kiosk mode. |scoped_user_manager| will take over
499 // lifetime of |user_manager|.
500 chromeos::FakeUserManager
* fake_user_manager
=
501 new chromeos::FakeUserManager();
502 fake_user_manager
->AddKioskAppUser("example@example.com");
503 fake_user_manager
->LoginUser("example@example.com");
504 chromeos::ScopedUserManagerEnabler
scoped_user_manager(fake_user_manager
);
505 EXPECT_TRUE(InstallExtension(crx_path
, 1));
509 #if defined(OS_CHROMEOS)
510 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, InstallToSharedLocation
) {
511 base::ShadowingAtExitManager at_exit_manager
;
512 CommandLine::ForCurrentProcess()->AppendSwitch(
513 chromeos::switches::kEnableExtensionAssetsSharing
);
514 base::ScopedTempDir cache_dir
;
515 ASSERT_TRUE(cache_dir
.CreateUniqueTempDir());
516 ExtensionAssetsManagerChromeOS::SetSharedInstallDirForTesting(
519 base::FilePath crx_path
= test_data_dir_
.AppendASCII("crx_installer/v1.crx");
520 const extensions::Extension
* extension
= InstallExtension(
521 crx_path
, 1, extensions::Manifest::EXTERNAL_PREF
);
522 base::FilePath extension_path
= extension
->path();
523 EXPECT_TRUE(cache_dir
.path().IsParent(extension_path
));
524 EXPECT_TRUE(base::PathExists(extension_path
));
526 std::string extension_id
= extension
->id();
527 UninstallExtension(extension_id
);
528 ExtensionRegistry
* registry
= ExtensionRegistry::Get(
529 browser()->profile());
530 EXPECT_FALSE(registry
->enabled_extensions().GetByID(extension_id
));
532 content::RunAllBlockingPoolTasksUntilIdle();
534 EXPECT_FALSE(base::PathExists(extension_path
));
538 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, DoNotSync
) {
539 ExtensionService
* service
= extensions::ExtensionSystem::Get(
540 browser()->profile())->extension_service();
541 scoped_refptr
<CrxInstaller
> crx_installer(
542 CrxInstaller::CreateSilent(service
));
543 crx_installer
->set_do_not_sync(true);
544 crx_installer
->InstallCrx(test_data_dir_
.AppendASCII("good.crx"));
545 EXPECT_TRUE(WaitForCrxInstallerDone());
546 ASSERT_TRUE(crx_installer
->extension());
548 const ExtensionPrefs
* extension_prefs
=
549 ExtensionPrefs::Get(browser()->profile());
550 EXPECT_TRUE(extension_prefs
->DoNotSync(crx_installer
->extension()->id()));
551 EXPECT_FALSE(extensions::util::ShouldSyncApp(crx_installer
->extension(),
552 browser()->profile()));
555 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, ManagementPolicy
) {
556 ManagementPolicyMock policy
;
557 extensions::ExtensionSystem::Get(profile())
558 ->management_policy()
559 ->RegisterProvider(&policy
);
561 base::FilePath crx_path
= test_data_dir_
.AppendASCII("crx_installer/v1.crx");
562 EXPECT_FALSE(InstallExtension(crx_path
, 0));
565 IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest
, WithheldElevationCheck
) {
566 // Enable consent flag and install extension. The <all_hosts> permission will
568 scoped_ptr
<FeatureSwitch::ScopedOverride
> enable_scripts_switch(
569 new FeatureSwitch::ScopedOverride(
570 FeatureSwitch::scripts_require_action(), true));
572 const char kManifest
[] =
574 " \"name\": \"Withheld test\","
575 " \"version\": \"1.0\","
576 " \"permissions\": ["
579 " \"manifest_version\": 2"
581 TestExtensionDir dir
;
582 dir
.WriteManifest(kManifest
);
583 base::FilePath crx_path
= dir
.Pack();
584 EXPECT_FALSE(crx_path
.empty());
585 const Extension
* extension
= InstallExtension(crx_path
, 1);
586 EXPECT_TRUE(base::PathExists(extension
->path()));
588 std::string extension_id
= extension
->id();
589 ExtensionRegistry
* registry
= ExtensionRegistry::Get(
590 browser()->profile());
591 EXPECT_TRUE(registry
->enabled_extensions().GetByID(extension_id
));
593 // Disable consent flag and reinstall extension. It should now be disabled
594 // because previously withheld permissions are now being requested.
595 enable_scripts_switch
.reset();
596 extension
= InstallExtension(crx_path
, -1);
597 EXPECT_FALSE(registry
->enabled_extensions().GetByID(extension_id
));
598 EXPECT_TRUE(registry
->disabled_extensions().GetByID(extension_id
));
599 EXPECT_TRUE(ExtensionPrefs::Get(browser()->profile())->GetDisableReasons(
600 extension_id
) & Extension::DISABLE_PERMISSIONS_INCREASE
);
603 } // namespace extensions