management_browsertest.cc revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 "base/bind.h" 6#include "base/bind_helpers.h" 7#include "base/memory/ref_counted.h" 8#include "base/prefs/pref_service.h" 9#include "base/prefs/scoped_user_pref_update.h" 10#include "base/stl_util.h" 11#include "chrome/browser/chrome_notification_types.h" 12#include "chrome/browser/extensions/extension_browsertest.h" 13#include "chrome/browser/extensions/extension_service.h" 14#include "chrome/browser/extensions/extension_test_message_listener.h" 15#include "chrome/browser/extensions/external_policy_loader.h" 16#include "chrome/browser/extensions/updater/extension_downloader.h" 17#include "chrome/browser/extensions/updater/extension_updater.h" 18#include "chrome/browser/profiles/profile.h" 19#include "chrome/browser/ui/browser.h" 20#include "chrome/common/pref_names.h" 21#include "chrome/common/url_constants.h" 22#include "chrome/test/base/ui_test_utils.h" 23#include "content/public/browser/notification_service.h" 24#include "content/public/browser/render_view_host.h" 25#include "content/public/test/browser_test_utils.h" 26#include "content/test/net/url_request_prepackaged_interceptor.h" 27#include "extensions/browser/extension_host.h" 28#include "extensions/browser/extension_prefs.h" 29#include "extensions/browser/extension_registry.h" 30#include "extensions/browser/extension_system.h" 31#include "extensions/browser/pref_names.h" 32#include "net/url_request/url_fetcher.h" 33 34using extensions::Extension; 35using extensions::ExtensionRegistry; 36using extensions::Manifest; 37 38class ExtensionManagementTest : public ExtensionBrowserTest { 39 protected: 40 // Helper method that returns whether the extension is at the given version. 41 // This calls version(), which must be defined in the extension's bg page, 42 // as well as asking the extension itself. 43 // 44 // Note that 'version' here means something different than the version field 45 // in the extension's manifest. We use the version as reported by the 46 // background page to test how overinstalling crx files with the same 47 // manifest version works. 48 bool IsExtensionAtVersion(const Extension* extension, 49 const std::string& expected_version) { 50 // Test that the extension's version from the manifest and reported by the 51 // background page is correct. This is to ensure that the processes are in 52 // sync with the Extension. 53 extensions::ProcessManager* manager = 54 extensions::ExtensionSystem::Get(browser()->profile())-> 55 process_manager(); 56 extensions::ExtensionHost* ext_host = 57 manager->GetBackgroundHostForExtension(extension->id()); 58 EXPECT_TRUE(ext_host); 59 if (!ext_host) 60 return false; 61 62 std::string version_from_bg; 63 bool exec = content::ExecuteScriptAndExtractString( 64 ext_host->render_view_host(), "version()", &version_from_bg); 65 EXPECT_TRUE(exec); 66 if (!exec) 67 return false; 68 69 if (version_from_bg != expected_version || 70 extension->VersionString() != expected_version) 71 return false; 72 return true; 73 } 74}; 75 76#if defined(OS_LINUX) 77// Times out sometimes on Linux. http://crbug.com/89727 78#define MAYBE_InstallSameVersion DISABLED_InstallSameVersion 79#else 80#define MAYBE_InstallSameVersion InstallSameVersion 81#endif 82 83// Tests that installing the same version overwrites. 84IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_InstallSameVersion) { 85 const Extension* extension = InstallExtension( 86 test_data_dir_.AppendASCII("install/install.crx"), 1); 87 ASSERT_TRUE(extension); 88 base::FilePath old_path = extension->path(); 89 90 // Install an extension with the same version. The previous install should be 91 // overwritten. 92 extension = InstallExtension( 93 test_data_dir_.AppendASCII("install/install_same_version.crx"), 0); 94 ASSERT_TRUE(extension); 95 base::FilePath new_path = extension->path(); 96 97 EXPECT_FALSE(IsExtensionAtVersion(extension, "1.0")); 98 EXPECT_NE(old_path.value(), new_path.value()); 99} 100 101IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallOlderVersion) { 102 const Extension* extension = InstallExtension( 103 test_data_dir_.AppendASCII("install/install.crx"), 1); 104 ASSERT_TRUE(extension); 105 ASSERT_FALSE(InstallExtension( 106 test_data_dir_.AppendASCII("install/install_older_version.crx"), 0)); 107 EXPECT_TRUE(IsExtensionAtVersion(extension, "1.0")); 108} 109 110IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, InstallThenCancel) { 111 const Extension* extension = InstallExtension( 112 test_data_dir_.AppendASCII("install/install.crx"), 1); 113 ASSERT_TRUE(extension); 114 115 // Cancel this install. 116 ASSERT_FALSE(StartInstallButCancel( 117 test_data_dir_.AppendASCII("install/install_v2.crx"))); 118 EXPECT_TRUE(IsExtensionAtVersion(extension, "1.0")); 119} 120 121#if defined(OS_WIN) 122// http://crbug.com/141913 123#define MAYBE_InstallRequiresConfirm DISABLED_InstallRequiresConfirm 124#else 125#define MAYBE_InstallRequiresConfirm InstallRequiresConfirm 126#endif 127IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_InstallRequiresConfirm) { 128 // Installing the extension without an auto confirming UI should result in 129 // it being disabled, since good.crx has permissions that require approval. 130 ExtensionService* service = extensions::ExtensionSystem::Get( 131 browser()->profile())->extension_service(); 132 std::string id = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; 133 ASSERT_FALSE(InstallExtension(test_data_dir_.AppendASCII("good.crx"), 0)); 134 ASSERT_TRUE(service->GetExtensionById(id, true)); 135 UninstallExtension(id); 136 137 // And the install should succeed when the permissions are accepted. 138 ASSERT_TRUE(InstallExtensionWithUIAutoConfirm( 139 test_data_dir_.AppendASCII("good.crx"), 1, browser())); 140 UninstallExtension(id); 141} 142 143// Tests that disabling and re-enabling an extension works. 144IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, DisableEnable) { 145 extensions::ProcessManager* manager = 146 extensions::ExtensionSystem::Get(browser()->profile())->process_manager(); 147 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 148 const size_t size_before = registry->enabled_extensions().size(); 149 150 // Load an extension, expect the background page to be available. 151 std::string extension_id = "bjafgdebaacbbbecmhlhpofkepfkgcpa"; 152 ASSERT_TRUE(LoadExtension( 153 test_data_dir_.AppendASCII("good").AppendASCII("Extensions") 154 .AppendASCII(extension_id) 155 .AppendASCII("1.0"))); 156 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 157 EXPECT_EQ(0u, registry->disabled_extensions().size()); 158 EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension_id)); 159 160 // After disabling, the background page should go away. 161 DisableExtension(extension_id); 162 EXPECT_EQ(size_before, registry->enabled_extensions().size()); 163 EXPECT_EQ(1u, registry->disabled_extensions().size()); 164 EXPECT_FALSE(manager->GetBackgroundHostForExtension(extension_id)); 165 166 // And bring it back. 167 EnableExtension(extension_id); 168 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size()); 169 EXPECT_EQ(0u, registry->disabled_extensions().size()); 170 EXPECT_TRUE(manager->GetBackgroundHostForExtension(extension_id)); 171} 172 173// Used for testing notifications sent during extension updates. 174class NotificationListener : public content::NotificationObserver { 175 public: 176 NotificationListener() : started_(false), finished_(false) { 177 int types[] = { 178 chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED, 179 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND 180 }; 181 for (size_t i = 0; i < arraysize(types); i++) { 182 registrar_.Add( 183 this, types[i], content::NotificationService::AllSources()); 184 } 185 } 186 virtual ~NotificationListener() {} 187 188 bool started() { return started_; } 189 190 bool finished() { return finished_; } 191 192 const std::set<std::string>& updates() { return updates_; } 193 194 void Reset() { 195 started_ = false; 196 finished_ = false; 197 updates_.clear(); 198 } 199 200 // Implements content::NotificationObserver interface. 201 virtual void Observe(int type, 202 const content::NotificationSource& source, 203 const content::NotificationDetails& details) OVERRIDE { 204 switch (type) { 205 case chrome::NOTIFICATION_EXTENSION_UPDATING_STARTED: { 206 EXPECT_FALSE(started_); 207 started_ = true; 208 break; 209 } 210 case chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND: { 211 const std::string& id = 212 content::Details<extensions::UpdateDetails>(details)->id; 213 updates_.insert(id); 214 break; 215 } 216 default: 217 NOTREACHED(); 218 } 219 } 220 221 void OnFinished() { 222 EXPECT_FALSE(finished_); 223 finished_ = true; 224 } 225 226 private: 227 content::NotificationRegistrar registrar_; 228 229 // Did we see EXTENSION_UPDATING_STARTED? 230 bool started_; 231 232 // Did we see EXTENSION_UPDATING_FINISHED? 233 bool finished_; 234 235 // The set of extension id's we've seen via EXTENSION_UPDATE_FOUND. 236 std::set<std::string> updates_; 237}; 238 239#if defined(OS_WIN) 240// Fails consistently on Windows XP, see: http://crbug.com/120640. 241#define MAYBE_AutoUpdate DISABLED_AutoUpdate 242#else 243// See http://crbug.com/103371 and http://crbug.com/120640. 244#if defined(ADDRESS_SANITIZER) 245#define MAYBE_AutoUpdate DISABLED_AutoUpdate 246#else 247#define MAYBE_AutoUpdate AutoUpdate 248#endif 249#endif 250 251// Tests extension autoupdate. 252IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, MAYBE_AutoUpdate) { 253 NotificationListener notification_listener; 254 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); 255 // Note: This interceptor gets requests on the IO thread. 256 content::URLLocalHostRequestPrepackagedInterceptor interceptor; 257 net::URLFetcher::SetEnableInterceptionForTests(true); 258 259 interceptor.SetResponseIgnoreQuery( 260 GURL("http://localhost/autoupdate/manifest"), 261 basedir.AppendASCII("manifest_v2.xml")); 262 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"), 263 basedir.AppendASCII("v2.crx")); 264 265 // Install version 1 of the extension. 266 ExtensionTestMessageListener listener1("v1 installed", false); 267 ExtensionService* service = extensions::ExtensionSystem::Get( 268 browser()->profile())->extension_service(); 269 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 270 const size_t size_before = registry->enabled_extensions().size(); 271 ASSERT_TRUE(registry->disabled_extensions().is_empty()); 272 const Extension* extension = 273 InstallExtension(basedir.AppendASCII("v1.crx"), 1); 274 ASSERT_TRUE(extension); 275 listener1.WaitUntilSatisfied(); 276 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 277 ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id()); 278 ASSERT_EQ("1.0", extension->VersionString()); 279 280 extensions::ExtensionUpdater::CheckParams params; 281 params.callback = 282 base::Bind(&NotificationListener::OnFinished, 283 base::Unretained(¬ification_listener)); 284 285 // Run autoupdate and make sure version 2 of the extension was installed. 286 ExtensionTestMessageListener listener2("v2 installed", false); 287 service->updater()->CheckNow(params); 288 ASSERT_TRUE(WaitForExtensionInstall()); 289 listener2.WaitUntilSatisfied(); 290 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 291 extension = service->GetExtensionById( 292 "ogjcoiohnmldgjemafoockdghcjciccf", false); 293 ASSERT_TRUE(extension); 294 ASSERT_EQ("2.0", extension->VersionString()); 295 ASSERT_TRUE(notification_listener.started()); 296 ASSERT_TRUE(notification_listener.finished()); 297 ASSERT_TRUE(ContainsKey(notification_listener.updates(), 298 "ogjcoiohnmldgjemafoockdghcjciccf")); 299 notification_listener.Reset(); 300 301 // Now try doing an update to version 3, which has been incorrectly 302 // signed. This should fail. 303 interceptor.SetResponseIgnoreQuery( 304 GURL("http://localhost/autoupdate/manifest"), 305 basedir.AppendASCII("manifest_v3.xml")); 306 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v3.crx"), 307 basedir.AppendASCII("v3.crx")); 308 309 service->updater()->CheckNow(params); 310 ASSERT_TRUE(WaitForExtensionInstallError()); 311 ASSERT_TRUE(notification_listener.started()); 312 ASSERT_TRUE(notification_listener.finished()); 313 ASSERT_TRUE(ContainsKey(notification_listener.updates(), 314 "ogjcoiohnmldgjemafoockdghcjciccf")); 315 316 // Make sure the extension state is the same as before. 317 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 318 extension = service->GetExtensionById( 319 "ogjcoiohnmldgjemafoockdghcjciccf", false); 320 ASSERT_TRUE(extension); 321 ASSERT_EQ("2.0", extension->VersionString()); 322} 323 324#if defined(OS_WIN) 325// Fails consistently on Windows XP, see: http://crbug.com/120640. 326#define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions 327#else 328#if defined(ADDRESS_SANITIZER) 329#define MAYBE_AutoUpdateDisabledExtensions DISABLED_AutoUpdateDisabledExtensions 330#else 331#define MAYBE_AutoUpdateDisabledExtensions AutoUpdateDisabledExtensions 332#endif 333#endif 334 335// Tests extension autoupdate. 336IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, 337 MAYBE_AutoUpdateDisabledExtensions) { 338 NotificationListener notification_listener; 339 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); 340 // Note: This interceptor gets requests on the IO thread. 341 content::URLLocalHostRequestPrepackagedInterceptor interceptor; 342 net::URLFetcher::SetEnableInterceptionForTests(true); 343 344 interceptor.SetResponseIgnoreQuery( 345 GURL("http://localhost/autoupdate/manifest"), 346 basedir.AppendASCII("manifest_v2.xml")); 347 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"), 348 basedir.AppendASCII("v2.crx")); 349 350 // Install version 1 of the extension. 351 ExtensionTestMessageListener listener1("v1 installed", false); 352 ExtensionService* service = extensions::ExtensionSystem::Get( 353 browser()->profile())->extension_service(); 354 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 355 const size_t enabled_size_before = registry->enabled_extensions().size(); 356 const size_t disabled_size_before = registry->disabled_extensions().size(); 357 const Extension* extension = 358 InstallExtension(basedir.AppendASCII("v1.crx"), 1); 359 ASSERT_TRUE(extension); 360 listener1.WaitUntilSatisfied(); 361 DisableExtension(extension->id()); 362 ASSERT_EQ(disabled_size_before + 1, registry->disabled_extensions().size()); 363 ASSERT_EQ(enabled_size_before, registry->enabled_extensions().size()); 364 ASSERT_EQ("ogjcoiohnmldgjemafoockdghcjciccf", extension->id()); 365 ASSERT_EQ("1.0", extension->VersionString()); 366 367 extensions::ExtensionUpdater::CheckParams params; 368 params.callback = 369 base::Bind(&NotificationListener::OnFinished, 370 base::Unretained(¬ification_listener)); 371 372 ExtensionTestMessageListener listener2("v2 installed", false); 373 // Run autoupdate and make sure version 2 of the extension was installed but 374 // is still disabled. 375 service->updater()->CheckNow(params); 376 ASSERT_TRUE(WaitForExtensionInstall()); 377 ASSERT_EQ(disabled_size_before + 1, registry->disabled_extensions().size()); 378 ASSERT_EQ(enabled_size_before, registry->enabled_extensions().size()); 379 extension = service->GetExtensionById( 380 "ogjcoiohnmldgjemafoockdghcjciccf", true); 381 ASSERT_TRUE(extension); 382 ASSERT_FALSE(service->GetExtensionById( 383 "ogjcoiohnmldgjemafoockdghcjciccf", false)); 384 ASSERT_EQ("2.0", extension->VersionString()); 385 386 // The extension should have not made the callback because it is disabled. 387 // When we enabled it, it should then make the callback. 388 ASSERT_FALSE(listener2.was_satisfied()); 389 EnableExtension(extension->id()); 390 listener2.WaitUntilSatisfied(); 391 ASSERT_TRUE(notification_listener.started()); 392 ASSERT_TRUE(notification_listener.finished()); 393 ASSERT_TRUE(ContainsKey(notification_listener.updates(), 394 "ogjcoiohnmldgjemafoockdghcjciccf")); 395 notification_listener.Reset(); 396} 397 398IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalUrlUpdate) { 399 ExtensionService* service = extensions::ExtensionSystem::Get( 400 browser()->profile())->extension_service(); 401 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; 402 extensions::ExtensionUpdater::CheckParams params; 403 404 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); 405 406 // Note: This interceptor gets requests on the IO thread. 407 content::URLLocalHostRequestPrepackagedInterceptor interceptor; 408 net::URLFetcher::SetEnableInterceptionForTests(true); 409 410 interceptor.SetResponseIgnoreQuery( 411 GURL("http://localhost/autoupdate/manifest"), 412 basedir.AppendASCII("manifest_v2.xml")); 413 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"), 414 basedir.AppendASCII("v2.crx")); 415 416 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 417 const size_t size_before = registry->enabled_extensions().size(); 418 ASSERT_TRUE(registry->disabled_extensions().is_empty()); 419 420 extensions::PendingExtensionManager* pending_extension_manager = 421 service->pending_extension_manager(); 422 423 // The code that reads external_extensions.json uses this method to inform 424 // the ExtensionService of an extension to download. Using the real code 425 // is race-prone, because instantating the ExtensionService starts a read 426 // of external_extensions.json before this test function starts. 427 428 EXPECT_TRUE(pending_extension_manager->AddFromExternalUpdateUrl( 429 kExtensionId, 430 std::string(), 431 GURL("http://localhost/autoupdate/manifest"), 432 Manifest::EXTERNAL_PREF_DOWNLOAD, 433 Extension::NO_FLAGS, 434 false)); 435 436 // Run autoupdate and make sure version 2 of the extension was installed. 437 service->updater()->CheckNow(params); 438 ASSERT_TRUE(WaitForExtensionInstall()); 439 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 440 const Extension* extension = service->GetExtensionById(kExtensionId, false); 441 ASSERT_TRUE(extension); 442 ASSERT_EQ("2.0", extension->VersionString()); 443 444 // Uninstalling the extension should set a pref that keeps the extension from 445 // being installed again the next time external_extensions.json is read. 446 447 UninstallExtension(kExtensionId); 448 449 extensions::ExtensionPrefs* extension_prefs = 450 extensions::ExtensionPrefs::Get(browser()->profile()); 451 EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) 452 << "Uninstalling should set kill bit on externaly installed extension."; 453 454 // Try to install the extension again from an external source. It should fail 455 // because of the killbit. 456 EXPECT_FALSE(pending_extension_manager->AddFromExternalUpdateUrl( 457 kExtensionId, 458 std::string(), 459 GURL("http://localhost/autoupdate/manifest"), 460 Manifest::EXTERNAL_PREF_DOWNLOAD, 461 Extension::NO_FLAGS, 462 false)); 463 EXPECT_FALSE(pending_extension_manager->IsIdPending(kExtensionId)) 464 << "External reinstall of a killed extension shouldn't work."; 465 EXPECT_TRUE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) 466 << "External reinstall of a killed extension should leave it killed."; 467 468 // Installing from non-external source. 469 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1)); 470 471 EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) 472 << "Reinstalling should clear the kill bit."; 473 474 // Uninstalling from a non-external source should not set the kill bit. 475 UninstallExtension(kExtensionId); 476 477 EXPECT_FALSE(extension_prefs->IsExternalExtensionUninstalled(kExtensionId)) 478 << "Uninstalling non-external extension should not set kill bit."; 479} 480 481namespace { 482 483const char* kForceInstallNotEmptyHelp = 484 "A policy may already be controlling the list of force-installed " 485 "extensions. Please remove all policy settings from your computer " 486 "before running tests. E.g. from /etc/chromium/policies Linux or " 487 "from the registry on Windows, etc."; 488 489} 490 491// See http://crbug.com/57378 for flakiness details. 492IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, ExternalPolicyRefresh) { 493 ExtensionService* service = extensions::ExtensionSystem::Get( 494 browser()->profile())->extension_service(); 495 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; 496 497 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); 498 499 // Note: This interceptor gets requests on the IO thread. 500 content::URLLocalHostRequestPrepackagedInterceptor interceptor; 501 net::URLFetcher::SetEnableInterceptionForTests(true); 502 503 interceptor.SetResponseIgnoreQuery( 504 GURL("http://localhost/autoupdate/manifest"), 505 basedir.AppendASCII("manifest_v2.xml")); 506 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"), 507 basedir.AppendASCII("v2.crx")); 508 509 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 510 const size_t size_before = registry->enabled_extensions().size(); 511 ASSERT_TRUE(registry->disabled_extensions().is_empty()); 512 513 PrefService* prefs = browser()->profile()->GetPrefs(); 514 const base::DictionaryValue* forcelist = 515 prefs->GetDictionary(extensions::pref_names::kInstallForceList); 516 ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp; 517 518 { 519 // Set the policy as a user preference and fire notification observers. 520 DictionaryPrefUpdate pref_update(prefs, 521 extensions::pref_names::kInstallForceList); 522 base::DictionaryValue* forcelist = pref_update.Get(); 523 extensions::ExternalPolicyLoader::AddExtension( 524 forcelist, kExtensionId, "http://localhost/autoupdate/manifest"); 525 } 526 527 // Check if the extension got installed. 528 ASSERT_TRUE(WaitForExtensionInstall()); 529 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 530 const Extension* extension = service->GetExtensionById(kExtensionId, false); 531 ASSERT_TRUE(extension); 532 ASSERT_EQ("2.0", extension->VersionString()); 533 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location()); 534 535 // Try to disable and uninstall the extension which should fail. 536 DisableExtension(kExtensionId); 537 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size()); 538 EXPECT_EQ(0u, registry->disabled_extensions().size()); 539 UninstallExtension(kExtensionId); 540 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size()); 541 EXPECT_EQ(0u, registry->disabled_extensions().size()); 542 543 // Now try to disable it through the management api, again failing. 544 ExtensionTestMessageListener listener1("ready", false); 545 ASSERT_TRUE(LoadExtension( 546 test_data_dir_.AppendASCII("management/uninstall_extension"))); 547 ASSERT_TRUE(listener1.WaitUntilSatisfied()); 548 EXPECT_EQ(size_before + 2, registry->enabled_extensions().size()); 549 EXPECT_EQ(0u, registry->disabled_extensions().size()); 550 551 // Check that emptying the list triggers uninstall. 552 prefs->ClearPref(extensions::pref_names::kInstallForceList); 553 EXPECT_EQ(size_before + 1, registry->enabled_extensions().size()); 554 EXPECT_FALSE(service->GetExtensionById(kExtensionId, true)); 555} 556 557// See http://crbug.com/103371 and http://crbug.com/120640. 558#if defined(ADDRESS_SANITIZER) || defined(OS_WIN) 559#define MAYBE_PolicyOverridesUserInstall DISABLED_PolicyOverridesUserInstall 560#else 561#define MAYBE_PolicyOverridesUserInstall PolicyOverridesUserInstall 562#endif 563 564IN_PROC_BROWSER_TEST_F(ExtensionManagementTest, 565 MAYBE_PolicyOverridesUserInstall) { 566 ExtensionService* service = extensions::ExtensionSystem::Get( 567 browser()->profile())->extension_service(); 568 ExtensionRegistry* registry = ExtensionRegistry::Get(browser()->profile()); 569 const char* kExtensionId = "ogjcoiohnmldgjemafoockdghcjciccf"; 570 extensions::ExtensionUpdater::CheckParams params; 571 service->updater()->set_default_check_params(params); 572 const size_t size_before = registry->enabled_extensions().size(); 573 base::FilePath basedir = test_data_dir_.AppendASCII("autoupdate"); 574 ASSERT_TRUE(registry->disabled_extensions().is_empty()); 575 576 // Note: This interceptor gets requests on the IO thread. 577 content::URLLocalHostRequestPrepackagedInterceptor interceptor; 578 net::URLFetcher::SetEnableInterceptionForTests(true); 579 580 interceptor.SetResponseIgnoreQuery( 581 GURL("http://localhost/autoupdate/manifest"), 582 basedir.AppendASCII("manifest_v2.xml")); 583 interceptor.SetResponseIgnoreQuery(GURL("http://localhost/autoupdate/v2.crx"), 584 basedir.AppendASCII("v2.crx")); 585 586 // Check that the policy is initially empty. 587 PrefService* prefs = browser()->profile()->GetPrefs(); 588 const base::DictionaryValue* forcelist = 589 prefs->GetDictionary(extensions::pref_names::kInstallForceList); 590 ASSERT_TRUE(forcelist->empty()) << kForceInstallNotEmptyHelp; 591 592 // User install of the extension. 593 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1)); 594 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 595 const Extension* extension = service->GetExtensionById(kExtensionId, false); 596 ASSERT_TRUE(extension); 597 EXPECT_EQ(Manifest::INTERNAL, extension->location()); 598 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); 599 600 // Setup the force install policy. It should override the location. 601 { 602 DictionaryPrefUpdate pref_update(prefs, 603 extensions::pref_names::kInstallForceList); 604 extensions::ExternalPolicyLoader::AddExtension( 605 pref_update.Get(), kExtensionId, 606 "http://localhost/autoupdate/manifest"); 607 } 608 ASSERT_TRUE(WaitForExtensionInstall()); 609 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 610 extension = service->GetExtensionById(kExtensionId, false); 611 ASSERT_TRUE(extension); 612 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location()); 613 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); 614 615 // Remove the policy, and verify that the extension was uninstalled. 616 // TODO(joaodasilva): it would be nicer if the extension was kept instead, 617 // and reverted location to INTERNAL or whatever it was before the policy 618 // was applied. 619 prefs->ClearPref(extensions::pref_names::kInstallForceList); 620 ASSERT_EQ(size_before, registry->enabled_extensions().size()); 621 extension = service->GetExtensionById(kExtensionId, true); 622 EXPECT_FALSE(extension); 623 624 // User install again, but have it disabled too before setting the policy. 625 ASSERT_TRUE(InstallExtension(basedir.AppendASCII("v2.crx"), 1)); 626 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 627 extension = service->GetExtensionById(kExtensionId, false); 628 ASSERT_TRUE(extension); 629 EXPECT_EQ(Manifest::INTERNAL, extension->location()); 630 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); 631 EXPECT_TRUE(registry->disabled_extensions().is_empty()); 632 633 DisableExtension(kExtensionId); 634 EXPECT_EQ(1u, registry->disabled_extensions().size()); 635 extension = service->GetExtensionById(kExtensionId, true); 636 EXPECT_TRUE(extension); 637 EXPECT_FALSE(service->IsExtensionEnabled(kExtensionId)); 638 639 // Install the policy again. It should overwrite the extension's location, 640 // and force enable it too. 641 { 642 DictionaryPrefUpdate pref_update(prefs, 643 extensions::pref_names::kInstallForceList); 644 base::DictionaryValue* forcelist = pref_update.Get(); 645 extensions::ExternalPolicyLoader::AddExtension( 646 forcelist, kExtensionId, "http://localhost/autoupdate/manifest"); 647 } 648 ASSERT_TRUE(WaitForExtensionInstall()); 649 ASSERT_EQ(size_before + 1, registry->enabled_extensions().size()); 650 extension = service->GetExtensionById(kExtensionId, false); 651 ASSERT_TRUE(extension); 652 EXPECT_EQ(Manifest::EXTERNAL_POLICY_DOWNLOAD, extension->location()); 653 EXPECT_TRUE(service->IsExtensionEnabled(kExtensionId)); 654 EXPECT_TRUE(registry->disabled_extensions().is_empty()); 655} 656