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. 4 5#include "chrome/browser/extensions/crx_installer.h" 6 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/management_policy.h" 34#include "extensions/browser/notification_types.h" 35#include "extensions/common/extension.h" 36#include "extensions/common/feature_switch.h" 37#include "extensions/common/file_util.h" 38#include "extensions/common/permissions/permission_set.h" 39#include "extensions/common/switches.h" 40#include "ui/base/l10n/l10n_util.h" 41 42#if defined(OS_CHROMEOS) 43#include "chrome/browser/chromeos/login/users/fake_user_manager.h" 44#include "chrome/browser/chromeos/login/users/scoped_user_manager_enabler.h" 45#include "chrome/browser/extensions/extension_assets_manager_chromeos.h" 46#include "chromeos/chromeos_switches.h" 47#endif 48 49class SkBitmap; 50 51namespace extensions { 52 53namespace { 54 55class MockInstallPrompt; 56 57// This class holds information about things that happen with a 58// MockInstallPrompt. We create the MockInstallPrompt but need to pass 59// ownership of it to CrxInstaller, so it isn't safe to hang this data on 60// MockInstallPrompt itself becuase we can't guarantee it's lifetime. 61class MockPromptProxy : public base::RefCountedThreadSafe<MockPromptProxy> { 62 public: 63 explicit MockPromptProxy(content::WebContents* web_contents); 64 65 bool did_succeed() const { return !extension_id_.empty(); } 66 const std::string& extension_id() { return extension_id_; } 67 bool confirmation_requested() const { return confirmation_requested_; } 68 const base::string16& error() const { return error_; } 69 70 // To have any effect, this should be called before CreatePrompt. 71 void set_record_oauth2_grant(bool record_oauth2_grant) { 72 record_oauth2_grant_.reset(new bool(record_oauth2_grant)); 73 } 74 75 void set_extension_id(const std::string& id) { extension_id_ = id; } 76 void set_confirmation_requested() { confirmation_requested_ = true; } 77 void set_error(const base::string16& error) { error_ = error; } 78 79 scoped_ptr<ExtensionInstallPrompt> CreatePrompt(); 80 81 private: 82 friend class base::RefCountedThreadSafe<MockPromptProxy>; 83 virtual ~MockPromptProxy(); 84 85 // Data used to create a prompt. 86 content::WebContents* web_contents_; 87 scoped_ptr<bool> record_oauth2_grant_; 88 89 // Data reported back to us by the prompt we created. 90 bool confirmation_requested_; 91 std::string extension_id_; 92 base::string16 error_; 93}; 94 95class MockInstallPrompt : public ExtensionInstallPrompt { 96 public: 97 MockInstallPrompt(content::WebContents* web_contents, 98 MockPromptProxy* proxy) : 99 ExtensionInstallPrompt(web_contents), 100 proxy_(proxy) {} 101 102 void set_record_oauth2_grant(bool record) { record_oauth2_grant_ = record; } 103 104 // Overriding some of the ExtensionInstallUI API. 105 virtual void ConfirmInstall( 106 Delegate* delegate, 107 const Extension* extension, 108 const ShowDialogCallback& show_dialog_callback) OVERRIDE { 109 proxy_->set_confirmation_requested(); 110 delegate->InstallUIProceed(); 111 } 112 virtual void OnInstallSuccess(const Extension* extension, 113 SkBitmap* icon) OVERRIDE { 114 proxy_->set_extension_id(extension->id()); 115 base::MessageLoopForUI::current()->Quit(); 116 } 117 virtual void OnInstallFailure(const CrxInstallerError& error) OVERRIDE { 118 proxy_->set_error(error.message()); 119 base::MessageLoopForUI::current()->Quit(); 120 } 121 122 private: 123 scoped_refptr<MockPromptProxy> proxy_; 124}; 125 126MockPromptProxy::MockPromptProxy(content::WebContents* web_contents) 127 : web_contents_(web_contents), confirmation_requested_(false) { 128} 129 130MockPromptProxy::~MockPromptProxy() {} 131 132scoped_ptr<ExtensionInstallPrompt> MockPromptProxy::CreatePrompt() { 133 scoped_ptr<MockInstallPrompt> prompt( 134 new MockInstallPrompt(web_contents_, this)); 135 if (record_oauth2_grant_.get()) 136 prompt->set_record_oauth2_grant(*record_oauth2_grant_.get()); 137 return prompt.PassAs<ExtensionInstallPrompt>(); 138} 139 140 141scoped_refptr<MockPromptProxy> CreateMockPromptProxyForBrowser( 142 Browser* browser) { 143 return new MockPromptProxy( 144 browser->tab_strip_model()->GetActiveWebContents()); 145} 146 147class ManagementPolicyMock : public extensions::ManagementPolicy::Provider { 148 public: 149 ManagementPolicyMock() {} 150 151 virtual std::string GetDebugPolicyProviderName() const OVERRIDE { 152 return "ManagementPolicyMock"; 153 } 154 155 virtual bool UserMayLoad(const Extension* extension, 156 base::string16* error) const OVERRIDE { 157 *error = base::UTF8ToUTF16("Dummy error message"); 158 return false; 159 } 160}; 161 162} // namespace 163 164class ExtensionCrxInstallerTest : public ExtensionBrowserTest { 165 public: 166 scoped_ptr<WebstoreInstaller::Approval> GetApproval( 167 const char* manifest_dir, 168 const std::string& id, 169 bool strict_manifest_checks) { 170 scoped_ptr<WebstoreInstaller::Approval> result; 171 172 base::FilePath ext_path = test_data_dir_.AppendASCII(manifest_dir); 173 std::string error; 174 scoped_ptr<base::DictionaryValue> parsed_manifest( 175 file_util::LoadManifest(ext_path, &error)); 176 if (!parsed_manifest.get() || !error.empty()) 177 return result.Pass(); 178 179 return WebstoreInstaller::Approval::CreateWithNoInstallPrompt( 180 browser()->profile(), 181 id, 182 parsed_manifest.Pass(), 183 strict_manifest_checks); 184 } 185 186 void RunCrxInstaller(const WebstoreInstaller::Approval* approval, 187 scoped_ptr<ExtensionInstallPrompt> prompt, 188 const base::FilePath& crx_path) { 189 ExtensionService* service = extensions::ExtensionSystem::Get( 190 browser()->profile())->extension_service(); 191 scoped_refptr<CrxInstaller> installer( 192 CrxInstaller::Create(service, prompt.Pass(), approval)); 193 installer->set_allow_silent_install(true); 194 installer->set_is_gallery_install(true); 195 installer->InstallCrx(crx_path); 196 content::RunMessageLoop(); 197 } 198 199 // Installs a crx from |crx_relpath| (a path relative to the extension test 200 // data dir) with expected id |id|. 201 void InstallWithPrompt(const char* ext_relpath, 202 const std::string& id, 203 scoped_refptr<MockPromptProxy> mock_install_prompt) { 204 base::FilePath ext_path = test_data_dir_.AppendASCII(ext_relpath); 205 206 scoped_ptr<WebstoreInstaller::Approval> approval; 207 if (!id.empty()) 208 approval = GetApproval(ext_relpath, id, true); 209 210 base::FilePath crx_path = PackExtension(ext_path); 211 EXPECT_FALSE(crx_path.empty()); 212 RunCrxInstaller(approval.get(), mock_install_prompt->CreatePrompt(), 213 crx_path); 214 215 EXPECT_TRUE(mock_install_prompt->did_succeed()); 216 } 217 218 // Installs an extension and checks that it has scopes granted IFF 219 // |record_oauth2_grant| is true. 220 void CheckHasEmptyScopesAfterInstall(const std::string& ext_relpath, 221 bool record_oauth2_grant) { 222 CommandLine::ForCurrentProcess()->AppendSwitch( 223 switches::kEnableExperimentalExtensionApis); 224 225 scoped_refptr<MockPromptProxy> mock_prompt = 226 CreateMockPromptProxyForBrowser(browser()); 227 228 mock_prompt->set_record_oauth2_grant(record_oauth2_grant); 229 InstallWithPrompt("browsertest/scopes", std::string(), mock_prompt); 230 231 scoped_refptr<PermissionSet> permissions = 232 ExtensionPrefs::Get(browser()->profile()) 233 ->GetGrantedPermissions(mock_prompt->extension_id()); 234 ASSERT_TRUE(permissions.get()); 235 } 236}; 237 238// This test is skipped on ChromeOS because it requires the NPAPI, 239// which is not available on that platform. 240#if !defined(OS_CHROMEOS) 241IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Whitelisting) { 242 std::string id = "hdgllgikmikobbofgnabhfimcfoopgnd"; 243 ExtensionRegistry* registry = ExtensionRegistry::Get( 244 browser()->profile()); 245 246 // Even whitelisted extensions with NPAPI should not prompt. 247 scoped_refptr<MockPromptProxy> mock_prompt = 248 CreateMockPromptProxyForBrowser(browser()); 249 InstallWithPrompt("uitest/plugins", id, mock_prompt); 250 EXPECT_FALSE(mock_prompt->confirmation_requested()); 251 EXPECT_TRUE(registry->enabled_extensions().GetByID(id)); 252} 253#endif 254 255IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, 256 GalleryInstallGetsExperimental) { 257 // We must modify the command line temporarily in order to pack an extension 258 // that requests the experimental permission. 259 CommandLine* command_line = CommandLine::ForCurrentProcess(); 260 CommandLine old_command_line = *command_line; 261 command_line->AppendSwitch(switches::kEnableExperimentalExtensionApis); 262 base::FilePath crx_path = PackExtension( 263 test_data_dir_.AppendASCII("experimental")); 264 ASSERT_FALSE(crx_path.empty()); 265 266 // Now reset the command line so that we are testing specifically whether 267 // installing from webstore enables experimental permissions. 268 *(CommandLine::ForCurrentProcess()) = old_command_line; 269 270 EXPECT_FALSE(InstallExtension(crx_path, 0)); 271 EXPECT_TRUE(InstallExtensionFromWebstore(crx_path, 1)); 272} 273 274IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, PlatformAppCrx) { 275 CommandLine::ForCurrentProcess()->AppendSwitch( 276 switches::kEnableExperimentalExtensionApis); 277 EXPECT_TRUE(InstallExtension( 278 test_data_dir_.AppendASCII("minimal_platform_app.crx"), 1)); 279} 280 281IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, PackAndInstallExtension) { 282 if (!FeatureSwitch::easy_off_store_install()->IsEnabled()) 283 return; 284 285 const int kNumDownloadsExpected = 1; 286 287 LOG(ERROR) << "PackAndInstallExtension: Packing extension"; 288 base::FilePath crx_path = PackExtension( 289 test_data_dir_.AppendASCII("common/background_page")); 290 ASSERT_FALSE(crx_path.empty()); 291 std::string crx_path_string(crx_path.value().begin(), crx_path.value().end()); 292 GURL url = GURL(std::string("file:///").append(crx_path_string)); 293 294 scoped_refptr<MockPromptProxy> mock_prompt = 295 CreateMockPromptProxyForBrowser(browser()); 296 download_crx_util::SetMockInstallPromptForTesting( 297 mock_prompt->CreatePrompt()); 298 299 LOG(ERROR) << "PackAndInstallExtension: Getting download manager"; 300 content::DownloadManager* download_manager = 301 content::BrowserContext::GetDownloadManager(browser()->profile()); 302 303 LOG(ERROR) << "PackAndInstallExtension: Setting observer"; 304 scoped_ptr<content::DownloadTestObserver> observer( 305 new content::DownloadTestObserverTerminal( 306 download_manager, kNumDownloadsExpected, 307 content::DownloadTestObserver::ON_DANGEROUS_DOWNLOAD_ACCEPT)); 308 LOG(ERROR) << "PackAndInstallExtension: Navigating to URL"; 309 ui_test_utils::NavigateToURLWithDisposition(browser(), url, CURRENT_TAB, 310 ui_test_utils::BROWSER_TEST_NONE); 311 312 EXPECT_TRUE(WaitForCrxInstallerDone()); 313 LOG(ERROR) << "PackAndInstallExtension: Extension install"; 314 EXPECT_TRUE(mock_prompt->confirmation_requested()); 315 LOG(ERROR) << "PackAndInstallExtension: Extension install confirmed"; 316} 317 318// Tests that scopes are only granted if |record_oauth2_grant_| on the prompt is 319// true. 320#if defined(OS_WIN) 321#define MAYBE_GrantScopes DISABLED_GrantScopes 322#else 323#define MAYBE_GrantScopes GrantScopes 324#endif 325IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, MAYBE_GrantScopes) { 326 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes", 327 true)); 328} 329 330IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotGrantScopes) { 331 EXPECT_NO_FATAL_FAILURE(CheckHasEmptyScopesAfterInstall("browsertest/scopes", 332 false)); 333} 334 335IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, AllowOffStore) { 336 ExtensionService* service = extensions::ExtensionSystem::Get( 337 browser()->profile())->extension_service(); 338 const bool kTestData[] = {false, true}; 339 340 for (size_t i = 0; i < arraysize(kTestData); ++i) { 341 scoped_refptr<MockPromptProxy> mock_prompt = 342 CreateMockPromptProxyForBrowser(browser()); 343 344 scoped_refptr<CrxInstaller> crx_installer( 345 CrxInstaller::Create(service, mock_prompt->CreatePrompt())); 346 crx_installer->set_install_cause( 347 extension_misc::INSTALL_CAUSE_USER_DOWNLOAD); 348 349 if (kTestData[i]) { 350 crx_installer->set_off_store_install_allow_reason( 351 CrxInstaller::OffStoreInstallAllowedInTest); 352 } 353 354 crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx")); 355 // The |mock_prompt| will quit running the loop once the |crx_installer| 356 // is done. 357 content::RunMessageLoop(); 358 EXPECT_EQ(kTestData[i], mock_prompt->did_succeed()); 359 EXPECT_EQ(kTestData[i], mock_prompt->confirmation_requested()) << 360 kTestData[i]; 361 if (kTestData[i]) { 362 EXPECT_EQ(base::string16(), mock_prompt->error()) << kTestData[i]; 363 } else { 364 EXPECT_EQ(l10n_util::GetStringUTF16( 365 IDS_EXTENSION_INSTALL_DISALLOWED_ON_SITE), 366 mock_prompt->error()) << kTestData[i]; 367 } 368 } 369} 370 371IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, HiDpiThemeTest) { 372 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx"); 373 crx_path = crx_path.AppendASCII("theme_hidpi.crx"); 374 375 ASSERT_TRUE(InstallExtension(crx_path, 1)); 376 377 const std::string extension_id("gllekhaobjnhgeagipipnkpmmmpchacm"); 378 ExtensionRegistry* registry = ExtensionRegistry::Get( 379 browser()->profile()); 380 const extensions::Extension* extension = 381 registry->enabled_extensions().GetByID(extension_id); 382 ASSERT_TRUE(extension); 383 EXPECT_EQ(extension_id, extension->id()); 384 385 UninstallExtension(extension_id); 386 EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id)); 387} 388 389// See http://crbug.com/315299. 390#if defined(OS_WIN) || defined(OS_LINUX) 391#define MAYBE_InstallDelayedUntilNextUpdate \ 392 DISABLED_InstallDelayedUntilNextUpdate 393#else 394#define MAYBE_InstallDelayedUntilNextUpdate InstallDelayedUntilNextUpdate 395#endif 396IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, 397 MAYBE_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 ExtensionRegistry* registry = ExtensionRegistry::Get( 405 browser()->profile()); 406 ASSERT_TRUE(registry); 407 408 // Install version 1 of the test extension. This extension does not have 409 // a background page but does have a browser action. 410 ASSERT_TRUE(InstallExtension(crx_path.AppendASCII("v1.crx"), 1)); 411 const extensions::Extension* extension = 412 registry->enabled_extensions().GetByID(extension_id); 413 ASSERT_TRUE(extension); 414 ASSERT_EQ(extension_id, extension->id()); 415 ASSERT_EQ("1.0", extension->version()->GetString()); 416 417 // Make test extension non-idle by opening the extension's browser action 418 // popup. This should cause the installation to be delayed. 419 content::WindowedNotificationObserver loading_observer( 420 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING, 421 content::Source<Profile>(profile())); 422 BrowserActionTestUtil util(browser()); 423 // There is only one extension, so just click the first browser action. 424 ASSERT_EQ(1, util.NumberOfBrowserActions()); 425 util.Press(0); 426 loading_observer.Wait(); 427 ExtensionHost* extension_host = 428 content::Details<ExtensionHost>(loading_observer.details()).ptr(); 429 430 // Install version 2 of the extension and check that it is indeed delayed. 431 ASSERT_TRUE(UpdateExtensionWaitForIdle( 432 extension_id, crx_path.AppendASCII("v2.crx"), 0)); 433 434 ASSERT_EQ(1u, service->delayed_installs()->size()); 435 extension = registry->enabled_extensions().GetByID(extension_id); 436 ASSERT_EQ("1.0", extension->version()->GetString()); 437 438 // Make the extension idle again by closing the popup. This should not trigger 439 // the delayed install. 440 content::RenderProcessHostWatcher terminated_observer( 441 extension_host->render_process_host(), 442 content::RenderProcessHostWatcher::WATCH_FOR_HOST_DESTRUCTION); 443 extension_host->render_view_host()->ClosePage(); 444 terminated_observer.Wait(); 445 ASSERT_EQ(1u, service->delayed_installs()->size()); 446 447 // Install version 3 of the extension. Because the extension is idle, 448 // this install should succeed. 449 ASSERT_TRUE(UpdateExtensionWaitForIdle( 450 extension_id, crx_path.AppendASCII("v3.crx"), 0)); 451 extension = registry->enabled_extensions().GetByID(extension_id); 452 ASSERT_EQ("3.0", extension->version()->GetString()); 453 454 // The version 2 delayed install should be cleaned up, and finishing 455 // delayed extension installation shouldn't break anything. 456 ASSERT_EQ(0u, service->delayed_installs()->size()); 457 service->MaybeFinishDelayedInstallations(); 458 extension = registry->enabled_extensions().GetByID(extension_id); 459 ASSERT_EQ("3.0", extension->version()->GetString()); 460} 461 462#if defined(FULL_SAFE_BROWSING) 463IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, Blacklist) { 464 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( 465 new FakeSafeBrowsingDatabaseManager(true)); 466 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); 467 468 blacklist_db->SetUnsafe("gllekhaobjnhgeagipipnkpmmmpchacm"); 469 470 base::FilePath crx_path = test_data_dir_.AppendASCII("theme_hidpi_crx") 471 .AppendASCII("theme_hidpi.crx"); 472 EXPECT_FALSE(InstallExtension(crx_path, 0)); 473} 474#endif 475 476IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, NonStrictManifestCheck) { 477 scoped_refptr<MockPromptProxy> mock_prompt = 478 CreateMockPromptProxyForBrowser(browser()); 479 480 // We want to simulate the case where the webstore sends a more recent 481 // version of the manifest, but the downloaded .crx file is old since 482 // the newly published version hasn't fully propagated to all the download 483 // servers yet. So load the v2 manifest, but then install the v1 crx file. 484 std::string id = "lhnaeclnpobnlbjbgogdanmhadigfnjp"; 485 scoped_ptr<WebstoreInstaller::Approval> approval = 486 GetApproval("crx_installer/v2_no_permission_change/", id, false); 487 488 RunCrxInstaller(approval.get(), mock_prompt->CreatePrompt(), 489 test_data_dir_.AppendASCII("crx_installer/v1.crx")); 490 491 EXPECT_TRUE(mock_prompt->did_succeed()); 492} 493 494IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, KioskOnlyTest) { 495 base::FilePath crx_path = 496 test_data_dir_.AppendASCII("kiosk/kiosk_only.crx"); 497 EXPECT_FALSE(InstallExtension(crx_path, 0)); 498#if defined(OS_CHROMEOS) 499 // Simulate ChromeOS kiosk mode. |scoped_user_manager| will take over 500 // lifetime of |user_manager|. 501 chromeos::FakeUserManager* fake_user_manager = 502 new chromeos::FakeUserManager(); 503 fake_user_manager->AddKioskAppUser("example@example.com"); 504 fake_user_manager->LoginUser("example@example.com"); 505 chromeos::ScopedUserManagerEnabler scoped_user_manager(fake_user_manager); 506 EXPECT_TRUE(InstallExtension(crx_path, 1)); 507#endif 508} 509 510#if defined(OS_CHROMEOS) 511IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, InstallToSharedLocation) { 512 base::ShadowingAtExitManager at_exit_manager; 513 CommandLine::ForCurrentProcess()->AppendSwitch( 514 chromeos::switches::kEnableExtensionAssetsSharing); 515 base::ScopedTempDir cache_dir; 516 ASSERT_TRUE(cache_dir.CreateUniqueTempDir()); 517 ExtensionAssetsManagerChromeOS::SetSharedInstallDirForTesting( 518 cache_dir.path()); 519 520 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx"); 521 const extensions::Extension* extension = InstallExtension( 522 crx_path, 1, extensions::Manifest::EXTERNAL_PREF); 523 base::FilePath extension_path = extension->path(); 524 EXPECT_TRUE(cache_dir.path().IsParent(extension_path)); 525 EXPECT_TRUE(base::PathExists(extension_path)); 526 527 std::string extension_id = extension->id(); 528 UninstallExtension(extension_id); 529 ExtensionRegistry* registry = ExtensionRegistry::Get( 530 browser()->profile()); 531 EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id)); 532 533 content::RunAllBlockingPoolTasksUntilIdle(); 534 535 EXPECT_FALSE(base::PathExists(extension_path)); 536} 537#endif 538 539IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, DoNotSync) { 540 ExtensionService* service = extensions::ExtensionSystem::Get( 541 browser()->profile())->extension_service(); 542 scoped_refptr<CrxInstaller> crx_installer( 543 CrxInstaller::CreateSilent(service)); 544 crx_installer->set_do_not_sync(true); 545 crx_installer->InstallCrx(test_data_dir_.AppendASCII("good.crx")); 546 EXPECT_TRUE(WaitForCrxInstallerDone()); 547 ASSERT_TRUE(crx_installer->extension()); 548 549 const ExtensionPrefs* extension_prefs = 550 ExtensionPrefs::Get(browser()->profile()); 551 EXPECT_TRUE(extension_prefs->DoNotSync(crx_installer->extension()->id())); 552 EXPECT_FALSE(extensions::util::ShouldSyncApp(crx_installer->extension(), 553 browser()->profile())); 554} 555 556IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, ManagementPolicy) { 557 ManagementPolicyMock policy; 558 extensions::ExtensionSystem::Get(profile()) 559 ->management_policy() 560 ->RegisterProvider(&policy); 561 562 base::FilePath crx_path = test_data_dir_.AppendASCII("crx_installer/v1.crx"); 563 EXPECT_FALSE(InstallExtension(crx_path, 0)); 564} 565 566IN_PROC_BROWSER_TEST_F(ExtensionCrxInstallerTest, WithheldElevationCheck) { 567 // Enable consent flag and install extension. The <all_hosts> permission will 568 // be withheld. 569 scoped_ptr<FeatureSwitch::ScopedOverride> enable_scripts_switch( 570 new FeatureSwitch::ScopedOverride( 571 FeatureSwitch::scripts_require_action(), true)); 572 573 const char kManifest[] = 574 "{" 575 " \"name\": \"Withheld test\"," 576 " \"version\": \"1.0\"," 577 " \"permissions\": [" 578 " \"http://*/*\"" 579 " ]," 580 " \"manifest_version\": 2" 581 "}"; 582 TestExtensionDir dir; 583 dir.WriteManifest(kManifest); 584 base::FilePath crx_path = dir.Pack(); 585 EXPECT_FALSE(crx_path.empty()); 586 const Extension* extension = InstallExtension(crx_path, 1); 587 EXPECT_TRUE(base::PathExists(extension->path())); 588 589 std::string extension_id = extension->id(); 590 ExtensionRegistry* registry = ExtensionRegistry::Get( 591 browser()->profile()); 592 EXPECT_TRUE(registry->enabled_extensions().GetByID(extension_id)); 593 594 // Disable consent flag and reinstall extension. It should now be disabled 595 // because previously withheld permissions are now being requested. 596 enable_scripts_switch.reset(); 597 extension = InstallExtension(crx_path, -1); 598 EXPECT_FALSE(registry->enabled_extensions().GetByID(extension_id)); 599 EXPECT_TRUE(registry->disabled_extensions().GetByID(extension_id)); 600 EXPECT_TRUE(ExtensionPrefs::Get(browser()->profile())->GetDisableReasons( 601 extension_id) & Extension::DISABLE_PERMISSIONS_INCREASE); 602} 603 604} // namespace extensions 605