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