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