extension_service_unittest.cc revision 116680a4aac90f2aa7413d9095a592090648e557
1// Copyright (c) 2013 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 <algorithm> 6#include <set> 7#include <vector> 8 9#include "base/at_exit.h" 10#include "base/basictypes.h" 11#include "base/bind.h" 12#include "base/command_line.h" 13#include "base/file_util.h" 14#include "base/files/file_enumerator.h" 15#include "base/files/scoped_temp_dir.h" 16#include "base/json/json_file_value_serializer.h" 17#include "base/json/json_reader.h" 18#include "base/json/json_string_value_serializer.h" 19#include "base/memory/scoped_ptr.h" 20#include "base/memory/weak_ptr.h" 21#include "base/message_loop/message_loop.h" 22#include "base/prefs/scoped_user_pref_update.h" 23#include "base/stl_util.h" 24#include "base/strings/string16.h" 25#include "base/strings/string_number_conversions.h" 26#include "base/strings/string_util.h" 27#include "base/strings/utf_string_conversions.h" 28#include "base/version.h" 29#include "chrome/browser/browser_process.h" 30#include "chrome/browser/chrome_notification_types.h" 31#include "chrome/browser/extensions/app_sync_data.h" 32#include "chrome/browser/extensions/blacklist.h" 33#include "chrome/browser/extensions/chrome_app_sorting.h" 34#include "chrome/browser/extensions/component_loader.h" 35#include "chrome/browser/extensions/crx_installer.h" 36#include "chrome/browser/extensions/default_apps.h" 37#include "chrome/browser/extensions/extension_creator.h" 38#include "chrome/browser/extensions/extension_error_reporter.h" 39#include "chrome/browser/extensions/extension_error_ui.h" 40#include "chrome/browser/extensions/extension_notification_observer.h" 41#include "chrome/browser/extensions/extension_service.h" 42#include "chrome/browser/extensions/extension_service_test_base.h" 43#include "chrome/browser/extensions/extension_special_storage_policy.h" 44#include "chrome/browser/extensions/extension_sync_data.h" 45#include "chrome/browser/extensions/extension_sync_service.h" 46#include "chrome/browser/extensions/extension_util.h" 47#include "chrome/browser/extensions/external_install_error.h" 48#include "chrome/browser/extensions/external_install_manager.h" 49#include "chrome/browser/extensions/external_policy_loader.h" 50#include "chrome/browser/extensions/external_pref_loader.h" 51#include "chrome/browser/extensions/external_provider_impl.h" 52#include "chrome/browser/extensions/fake_safe_browsing_database_manager.h" 53#include "chrome/browser/extensions/installed_loader.h" 54#include "chrome/browser/extensions/pack_extension_job.h" 55#include "chrome/browser/extensions/pending_extension_info.h" 56#include "chrome/browser/extensions/pending_extension_manager.h" 57#include "chrome/browser/extensions/test_blacklist.h" 58#include "chrome/browser/extensions/test_extension_system.h" 59#include "chrome/browser/extensions/unpacked_installer.h" 60#include "chrome/browser/extensions/updater/extension_updater.h" 61#include "chrome/browser/prefs/pref_service_syncable.h" 62#include "chrome/browser/sync/profile_sync_service.h" 63#include "chrome/browser/sync/profile_sync_service_factory.h" 64#include "chrome/common/chrome_constants.h" 65#include "chrome/common/chrome_switches.h" 66#include "chrome/common/extensions/api/plugins/plugins_handler.h" 67#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 68#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h" 69#include "chrome/common/extensions/manifest_url_handler.h" 70#include "chrome/common/pref_names.h" 71#include "chrome/common/url_constants.h" 72#include "chrome/test/base/scoped_browser_locale.h" 73#include "chrome/test/base/testing_profile.h" 74#include "components/pref_registry/pref_registry_syncable.h" 75#include "content/public/browser/dom_storage_context.h" 76#include "content/public/browser/gpu_data_manager.h" 77#include "content/public/browser/indexed_db_context.h" 78#include "content/public/browser/notification_registrar.h" 79#include "content/public/browser/notification_service.h" 80#include "content/public/browser/plugin_service.h" 81#include "content/public/browser/render_process_host.h" 82#include "content/public/browser/storage_partition.h" 83#include "content/public/common/content_constants.h" 84#include "content/public/test/test_utils.h" 85#include "extensions/browser/extension_registry.h" 86#include "extensions/browser/extension_system.h" 87#include "extensions/browser/external_provider_interface.h" 88#include "extensions/browser/install_flag.h" 89#include "extensions/browser/management_policy.h" 90#include "extensions/browser/pref_names.h" 91#include "extensions/browser/test_management_policy.h" 92#include "extensions/common/constants.h" 93#include "extensions/common/extension.h" 94#include "extensions/common/extension_builder.h" 95#include "extensions/common/extension_l10n_util.h" 96#include "extensions/common/extension_resource.h" 97#include "extensions/common/feature_switch.h" 98#include "extensions/common/manifest_constants.h" 99#include "extensions/common/manifest_handlers/background_info.h" 100#include "extensions/common/permissions/permission_set.h" 101#include "extensions/common/permissions/permissions_data.h" 102#include "extensions/common/switches.h" 103#include "extensions/common/url_pattern.h" 104#include "extensions/common/value_builder.h" 105#include "gpu/config/gpu_info.h" 106#include "grit/browser_resources.h" 107#include "net/cookies/canonical_cookie.h" 108#include "net/cookies/cookie_monster.h" 109#include "net/cookies/cookie_options.h" 110#include "net/url_request/url_request_context.h" 111#include "net/url_request/url_request_context_getter.h" 112#include "sync/api/fake_sync_change_processor.h" 113#include "sync/api/string_ordinal.h" 114#include "sync/api/sync_data.h" 115#include "sync/api/sync_error_factory.h" 116#include "sync/api/sync_error_factory_mock.h" 117#include "sync/api/syncable_service.h" 118#include "sync/protocol/app_specifics.pb.h" 119#include "sync/protocol/extension_specifics.pb.h" 120#include "sync/protocol/sync.pb.h" 121#include "testing/gtest/include/gtest/gtest.h" 122#include "testing/platform_test.h" 123#include "url/gurl.h" 124#include "webkit/browser/database/database_tracker.h" 125#include "webkit/browser/quota/quota_manager.h" 126#include "webkit/common/database/database_identifier.h" 127 128#if defined(OS_CHROMEOS) 129#include "chrome/browser/chromeos/login/users/user_manager.h" 130#include "chrome/browser/chromeos/settings/cros_settings.h" 131#include "chrome/browser/chromeos/settings/device_settings_service.h" 132#endif 133 134// The blacklist tests rely on safe browsing. 135#if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING) 136#define ENABLE_BLACKLIST_TESTS 137#endif 138 139using base::DictionaryValue; 140using base::ListValue; 141using base::Value; 142using content::BrowserContext; 143using content::BrowserThread; 144using content::DOMStorageContext; 145using content::IndexedDBContext; 146using content::PluginService; 147using extensions::APIPermission; 148using extensions::APIPermissionSet; 149using extensions::AppSorting; 150using extensions::Blacklist; 151using extensions::CrxInstaller; 152using extensions::Extension; 153using extensions::ExtensionCreator; 154using extensions::ExtensionPrefs; 155using extensions::ExtensionRegistry; 156using extensions::ExtensionResource; 157using extensions::ExtensionSystem; 158using extensions::FakeSafeBrowsingDatabaseManager; 159using extensions::FeatureSwitch; 160using extensions::Manifest; 161using extensions::PermissionSet; 162using extensions::TestExtensionSystem; 163using extensions::UnloadedExtensionInfo; 164using extensions::URLPatternSet; 165 166namespace keys = extensions::manifest_keys; 167 168namespace { 169 170// Extension ids used during testing. 171const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj"; 172const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk"; 173const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa"; 174const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 175const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh"; 176const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; 177const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi"; 178const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln"; 179const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad"; 180const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf"; 181const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin"; 182const char unpacked[] = "cbcdidchbppangcjoddlpdjlenngjldk"; 183const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj"; 184 185struct ExtensionsOrder { 186 bool operator()(const scoped_refptr<const Extension>& a, 187 const scoped_refptr<const Extension>& b) { 188 return a->name() < b->name(); 189 } 190}; 191 192static std::vector<base::string16> GetErrors() { 193 const std::vector<base::string16>* errors = 194 ExtensionErrorReporter::GetInstance()->GetErrors(); 195 std::vector<base::string16> ret_val; 196 197 for (std::vector<base::string16>::const_iterator iter = errors->begin(); 198 iter != errors->end(); ++iter) { 199 std::string utf8_error = base::UTF16ToUTF8(*iter); 200 if (utf8_error.find(".svn") == std::string::npos) { 201 ret_val.push_back(*iter); 202 } 203 } 204 205 // The tests rely on the errors being in a certain order, which can vary 206 // depending on how filesystem iteration works. 207 std::stable_sort(ret_val.begin(), ret_val.end()); 208 209 return ret_val; 210} 211 212static void AddPattern(URLPatternSet* extent, const std::string& pattern) { 213 int schemes = URLPattern::SCHEME_ALL; 214 extent->AddPattern(URLPattern(schemes, pattern)); 215} 216 217base::FilePath GetTemporaryFile() { 218 base::FilePath temp_file; 219 CHECK(base::CreateTemporaryFile(&temp_file)); 220 return temp_file; 221} 222 223bool WaitForCountNotificationsCallback(int *count) { 224 return --(*count) == 0; 225} 226 227} // namespace 228 229class MockExtensionProvider : public extensions::ExternalProviderInterface { 230 public: 231 MockExtensionProvider( 232 VisitorInterface* visitor, 233 Manifest::Location location) 234 : location_(location), visitor_(visitor), visit_count_(0) { 235 } 236 237 virtual ~MockExtensionProvider() {} 238 239 void UpdateOrAddExtension(const std::string& id, 240 const std::string& version, 241 const base::FilePath& path) { 242 extension_map_[id] = std::make_pair(version, path); 243 } 244 245 void RemoveExtension(const std::string& id) { 246 extension_map_.erase(id); 247 } 248 249 // ExternalProvider implementation: 250 virtual void VisitRegisteredExtension() OVERRIDE { 251 visit_count_++; 252 for (DataMap::const_iterator i = extension_map_.begin(); 253 i != extension_map_.end(); ++i) { 254 Version version(i->second.first); 255 256 visitor_->OnExternalExtensionFileFound( 257 i->first, &version, i->second.second, location_, 258 Extension::NO_FLAGS, false); 259 } 260 visitor_->OnExternalProviderReady(this); 261 } 262 263 virtual bool HasExtension(const std::string& id) const OVERRIDE { 264 return extension_map_.find(id) != extension_map_.end(); 265 } 266 267 virtual bool GetExtensionDetails( 268 const std::string& id, 269 Manifest::Location* location, 270 scoped_ptr<Version>* version) const OVERRIDE { 271 DataMap::const_iterator it = extension_map_.find(id); 272 if (it == extension_map_.end()) 273 return false; 274 275 if (version) 276 version->reset(new Version(it->second.first)); 277 278 if (location) 279 *location = location_; 280 281 return true; 282 } 283 284 virtual bool IsReady() const OVERRIDE { 285 return true; 286 } 287 288 virtual void ServiceShutdown() OVERRIDE { 289 } 290 291 int visit_count() const { return visit_count_; } 292 void set_visit_count(int visit_count) { 293 visit_count_ = visit_count; 294 } 295 296 private: 297 typedef std::map< std::string, std::pair<std::string, base::FilePath> > 298 DataMap; 299 DataMap extension_map_; 300 Manifest::Location location_; 301 VisitorInterface* visitor_; 302 303 // visit_count_ tracks the number of calls to VisitRegisteredExtension(). 304 // Mutable because it must be incremented on each call to 305 // VisitRegisteredExtension(), which must be a const method to inherit 306 // from the class being mocked. 307 mutable int visit_count_; 308 309 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider); 310}; 311 312class MockProviderVisitor 313 : public extensions::ExternalProviderInterface::VisitorInterface { 314 public: 315 // The provider will return |fake_base_path| from 316 // GetBaseCrxFilePath(). User can test the behavior with 317 // and without an empty path using this parameter. 318 explicit MockProviderVisitor(base::FilePath fake_base_path) 319 : ids_found_(0), 320 fake_base_path_(fake_base_path), 321 expected_creation_flags_(Extension::NO_FLAGS) { 322 profile_.reset(new TestingProfile); 323 } 324 325 MockProviderVisitor(base::FilePath fake_base_path, 326 int expected_creation_flags) 327 : ids_found_(0), 328 fake_base_path_(fake_base_path), 329 expected_creation_flags_(expected_creation_flags) { 330 } 331 332 int Visit(const std::string& json_data) { 333 // Give the test json file to the provider for parsing. 334 provider_.reset(new extensions::ExternalProviderImpl( 335 this, 336 new extensions::ExternalTestingLoader(json_data, fake_base_path_), 337 profile_.get(), 338 Manifest::EXTERNAL_PREF, 339 Manifest::EXTERNAL_PREF_DOWNLOAD, 340 Extension::NO_FLAGS)); 341 342 // We also parse the file into a dictionary to compare what we get back 343 // from the provider. 344 JSONStringValueSerializer serializer(json_data); 345 base::Value* json_value = serializer.Deserialize(NULL, NULL); 346 347 if (!json_value || !json_value->IsType(base::Value::TYPE_DICTIONARY)) { 348 NOTREACHED() << "Unable to deserialize json data"; 349 return -1; 350 } else { 351 base::DictionaryValue* external_extensions = 352 static_cast<base::DictionaryValue*>(json_value); 353 prefs_.reset(external_extensions); 354 } 355 356 // Reset our counter. 357 ids_found_ = 0; 358 // Ask the provider to look up all extensions and return them. 359 provider_->VisitRegisteredExtension(); 360 361 return ids_found_; 362 } 363 364 virtual bool OnExternalExtensionFileFound(const std::string& id, 365 const Version* version, 366 const base::FilePath& path, 367 Manifest::Location unused, 368 int creation_flags, 369 bool mark_acknowledged) OVERRIDE { 370 EXPECT_EQ(expected_creation_flags_, creation_flags); 371 372 ++ids_found_; 373 base::DictionaryValue* pref; 374 // This tests is to make sure that the provider only notifies us of the 375 // values we gave it. So if the id we doesn't exist in our internal 376 // dictionary then something is wrong. 377 EXPECT_TRUE(prefs_->GetDictionary(id, &pref)) 378 << "Got back ID (" << id.c_str() << ") we weren't expecting"; 379 380 EXPECT_TRUE(path.IsAbsolute()); 381 if (!fake_base_path_.empty()) 382 EXPECT_TRUE(fake_base_path_.IsParent(path)); 383 384 if (pref) { 385 EXPECT_TRUE(provider_->HasExtension(id)); 386 387 // Ask provider if the extension we got back is registered. 388 Manifest::Location location = Manifest::INVALID_LOCATION; 389 scoped_ptr<Version> v1; 390 base::FilePath crx_path; 391 392 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1)); 393 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str()); 394 395 scoped_ptr<Version> v2; 396 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2)); 397 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str()); 398 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str()); 399 EXPECT_EQ(Manifest::EXTERNAL_PREF, location); 400 401 // Remove it so we won't count it ever again. 402 prefs_->Remove(id, NULL); 403 } 404 return true; 405 } 406 407 virtual bool OnExternalExtensionUpdateUrlFound( 408 const std::string& id, 409 const std::string& install_parameter, 410 const GURL& update_url, 411 Manifest::Location location, 412 int creation_flags, 413 bool mark_acknowledged) OVERRIDE { 414 ++ids_found_; 415 base::DictionaryValue* pref; 416 // This tests is to make sure that the provider only notifies us of the 417 // values we gave it. So if the id we doesn't exist in our internal 418 // dictionary then something is wrong. 419 EXPECT_TRUE(prefs_->GetDictionary(id, &pref)) 420 << L"Got back ID (" << id.c_str() << ") we weren't expecting"; 421 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location); 422 423 if (pref) { 424 EXPECT_TRUE(provider_->HasExtension(id)); 425 426 // External extensions with update URLs do not have versions. 427 scoped_ptr<Version> v1; 428 Manifest::Location location1 = Manifest::INVALID_LOCATION; 429 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1)); 430 EXPECT_FALSE(v1.get()); 431 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1); 432 433 std::string parsed_install_parameter; 434 pref->GetString("install_parameter", &parsed_install_parameter); 435 EXPECT_EQ(parsed_install_parameter, install_parameter); 436 437 // Remove it so we won't count it again. 438 prefs_->Remove(id, NULL); 439 } 440 return true; 441 } 442 443 virtual void OnExternalProviderReady( 444 const extensions::ExternalProviderInterface* provider) OVERRIDE { 445 EXPECT_EQ(provider, provider_.get()); 446 EXPECT_TRUE(provider->IsReady()); 447 } 448 449 private: 450 int ids_found_; 451 base::FilePath fake_base_path_; 452 int expected_creation_flags_; 453 scoped_ptr<extensions::ExternalProviderImpl> provider_; 454 scoped_ptr<base::DictionaryValue> prefs_; 455 scoped_ptr<TestingProfile> profile_; 456 457 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor); 458}; 459 460class ExtensionServiceTest : public extensions::ExtensionServiceTestBase, 461 public content::NotificationObserver { 462 public: 463 ExtensionServiceTest() 464 : unloaded_reason_(UnloadedExtensionInfo::REASON_UNDEFINED), 465 installed_(NULL), 466 was_update_(false), 467 override_external_install_prompt_( 468 FeatureSwitch::prompt_for_external_extensions(), 469 false), 470 expected_extensions_count_(0) { 471 registrar_.Add(this, 472 chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED, 473 content::NotificationService::AllSources()); 474 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED, 475 content::NotificationService::AllSources()); 476 registrar_.Add(this, 477 chrome::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED, 478 content::NotificationService::AllSources()); 479 } 480 481 virtual void Observe(int type, 482 const content::NotificationSource& source, 483 const content::NotificationDetails& details) OVERRIDE { 484 switch (type) { 485 case chrome::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: { 486 const Extension* extension = 487 content::Details<const Extension>(details).ptr(); 488 loaded_.push_back(make_scoped_refptr(extension)); 489 // The tests rely on the errors being in a certain order, which can vary 490 // depending on how filesystem iteration works. 491 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder()); 492 break; 493 } 494 495 case chrome::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: { 496 UnloadedExtensionInfo* unloaded_info = 497 content::Details<UnloadedExtensionInfo>(details).ptr(); 498 const Extension* e = unloaded_info->extension; 499 unloaded_id_ = e->id(); 500 unloaded_reason_ = unloaded_info->reason; 501 extensions::ExtensionList::iterator i = 502 std::find(loaded_.begin(), loaded_.end(), e); 503 // TODO(erikkay) fix so this can be an assert. Right now the tests 504 // are manually calling clear() on loaded_, so this isn't doable. 505 if (i == loaded_.end()) 506 return; 507 loaded_.erase(i); 508 break; 509 } 510 case chrome::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED: { 511 const extensions::InstalledExtensionInfo* installed_info = 512 content::Details<const extensions::InstalledExtensionInfo>(details) 513 .ptr(); 514 installed_ = installed_info->extension; 515 was_update_ = installed_info->is_update; 516 old_name_ = installed_info->old_name; 517 break; 518 } 519 520 default: 521 DCHECK(false); 522 } 523 } 524 525 void AddMockExternalProvider( 526 extensions::ExternalProviderInterface* provider) { 527 service()->AddProviderForTesting(provider); 528 } 529 530 void MockSyncStartFlare(bool* was_called, 531 syncer::ModelType* model_type_passed_in, 532 syncer::ModelType model_type) { 533 *was_called = true; 534 *model_type_passed_in = model_type; 535 } 536 537 protected: 538 // Paths to some of the fake extensions. 539 base::FilePath good0_path() { 540 return data_dir() 541 .AppendASCII("good") 542 .AppendASCII("Extensions") 543 .AppendASCII(good0) 544 .AppendASCII("1.0.0.0"); 545 } 546 547 base::FilePath good1_path() { 548 return data_dir() 549 .AppendASCII("good") 550 .AppendASCII("Extensions") 551 .AppendASCII(good1) 552 .AppendASCII("2"); 553 } 554 555 base::FilePath good2_path() { 556 return data_dir() 557 .AppendASCII("good") 558 .AppendASCII("Extensions") 559 .AppendASCII(good2) 560 .AppendASCII("1.0"); 561 } 562 563 void TestExternalProvider(MockExtensionProvider* provider, 564 Manifest::Location location); 565 566 void PackCRX(const base::FilePath& dir_path, 567 const base::FilePath& pem_path, 568 const base::FilePath& crx_path) { 569 // Use the existing pem key, if provided. 570 base::FilePath pem_output_path; 571 if (pem_path.value().empty()) { 572 pem_output_path = crx_path.DirName().AppendASCII("temp.pem"); 573 } else { 574 ASSERT_TRUE(base::PathExists(pem_path)); 575 } 576 577 ASSERT_TRUE(base::DeleteFile(crx_path, false)); 578 579 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); 580 ASSERT_TRUE(creator->Run(dir_path, 581 crx_path, 582 pem_path, 583 pem_output_path, 584 ExtensionCreator::kOverwriteCRX)); 585 586 ASSERT_TRUE(base::PathExists(crx_path)); 587 } 588 589 enum InstallState { 590 INSTALL_FAILED, 591 INSTALL_UPDATED, 592 INSTALL_NEW, 593 INSTALL_WITHOUT_LOAD, 594 }; 595 596 const Extension* PackAndInstallCRX(const base::FilePath& dir_path, 597 const base::FilePath& pem_path, 598 InstallState install_state, 599 int creation_flags) { 600 base::FilePath crx_path; 601 base::ScopedTempDir temp_dir; 602 EXPECT_TRUE(temp_dir.CreateUniqueTempDir()); 603 crx_path = temp_dir.path().AppendASCII("temp.crx"); 604 605 PackCRX(dir_path, pem_path, crx_path); 606 return InstallCRX(crx_path, install_state, creation_flags); 607 } 608 609 const Extension* PackAndInstallCRX(const base::FilePath& dir_path, 610 const base::FilePath& pem_path, 611 InstallState install_state) { 612 return PackAndInstallCRX(dir_path, pem_path, install_state, 613 Extension::NO_FLAGS); 614 } 615 616 const Extension* PackAndInstallCRX(const base::FilePath& dir_path, 617 InstallState install_state) { 618 return PackAndInstallCRX(dir_path, base::FilePath(), install_state, 619 Extension::NO_FLAGS); 620 } 621 622 // Attempts to install an extension. Use INSTALL_FAILED if the installation 623 // is expected to fail. 624 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is 625 // non-empty, expects that the existing extension's title was 626 // |expected_old_name|. 627 const Extension* InstallCRX(const base::FilePath& path, 628 InstallState install_state, 629 int creation_flags, 630 const std::string& expected_old_name) { 631 InstallCRXInternal(path, creation_flags); 632 return VerifyCrxInstall(path, install_state, expected_old_name); 633 } 634 635 // Attempts to install an extension. Use INSTALL_FAILED if the installation 636 // is expected to fail. 637 const Extension* InstallCRX(const base::FilePath& path, 638 InstallState install_state, 639 int creation_flags) { 640 return InstallCRX(path, install_state, creation_flags, std::string()); 641 } 642 643 // Attempts to install an extension. Use INSTALL_FAILED if the installation 644 // is expected to fail. 645 const Extension* InstallCRX(const base::FilePath& path, 646 InstallState install_state) { 647 return InstallCRX(path, install_state, Extension::NO_FLAGS); 648 } 649 650 const Extension* InstallCRXFromWebStore(const base::FilePath& path, 651 InstallState install_state) { 652 InstallCRXInternal(path, Extension::FROM_WEBSTORE); 653 return VerifyCrxInstall(path, install_state); 654 } 655 656 const Extension* InstallCRXWithLocation(const base::FilePath& crx_path, 657 Manifest::Location install_location, 658 InstallState install_state) { 659 EXPECT_TRUE(base::PathExists(crx_path)) 660 << "Path does not exist: "<< crx_path.value().c_str(); 661 // no client (silent install) 662 scoped_refptr<CrxInstaller> installer( 663 CrxInstaller::CreateSilent(service())); 664 installer->set_install_source(install_location); 665 666 content::WindowedNotificationObserver observer( 667 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 668 content::NotificationService::AllSources()); 669 installer->InstallCrx(crx_path); 670 observer.Wait(); 671 672 return VerifyCrxInstall(crx_path, install_state); 673 } 674 675 // Verifies the result of a CRX installation. Used by InstallCRX. Set the 676 // |install_state| to INSTALL_FAILED if the installation is expected to fail. 677 // Returns an Extension pointer if the install succeeded, NULL otherwise. 678 const Extension* VerifyCrxInstall(const base::FilePath& path, 679 InstallState install_state) { 680 return VerifyCrxInstall(path, install_state, std::string()); 681 } 682 683 // Verifies the result of a CRX installation. Used by InstallCRX. Set the 684 // |install_state| to INSTALL_FAILED if the installation is expected to fail. 685 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is 686 // non-empty, expects that the existing extension's title was 687 // |expected_old_name|. 688 // Returns an Extension pointer if the install succeeded, NULL otherwise. 689 const Extension* VerifyCrxInstall(const base::FilePath& path, 690 InstallState install_state, 691 const std::string& expected_old_name) { 692 std::vector<base::string16> errors = GetErrors(); 693 const Extension* extension = NULL; 694 if (install_state != INSTALL_FAILED) { 695 if (install_state == INSTALL_NEW) 696 ++expected_extensions_count_; 697 698 EXPECT_TRUE(installed_) << path.value(); 699 // If and only if INSTALL_UPDATED, it should have the is_update flag. 700 EXPECT_EQ(install_state == INSTALL_UPDATED, was_update_) 701 << path.value(); 702 // If INSTALL_UPDATED, old_name_ should match the given string. 703 if (install_state == INSTALL_UPDATED && !expected_old_name.empty()) 704 EXPECT_EQ(expected_old_name, old_name_); 705 EXPECT_EQ(0u, errors.size()) << path.value(); 706 707 if (install_state == INSTALL_WITHOUT_LOAD) { 708 EXPECT_EQ(0u, loaded_.size()) << path.value(); 709 } else { 710 EXPECT_EQ(1u, loaded_.size()) << path.value(); 711 size_t actual_extension_count = 712 registry()->enabled_extensions().size() + 713 registry()->disabled_extensions().size(); 714 EXPECT_EQ(expected_extensions_count_, actual_extension_count) << 715 path.value(); 716 extension = loaded_[0].get(); 717 EXPECT_TRUE(service()->GetExtensionById(extension->id(), false)) 718 << path.value(); 719 } 720 721 for (std::vector<base::string16>::iterator err = errors.begin(); 722 err != errors.end(); ++err) { 723 LOG(ERROR) << *err; 724 } 725 } else { 726 EXPECT_FALSE(installed_) << path.value(); 727 EXPECT_EQ(0u, loaded_.size()) << path.value(); 728 EXPECT_EQ(1u, errors.size()) << path.value(); 729 } 730 731 installed_ = NULL; 732 was_update_ = false; 733 old_name_ = ""; 734 loaded_.clear(); 735 ExtensionErrorReporter::GetInstance()->ClearErrors(); 736 return extension; 737 } 738 739 enum UpdateState { 740 FAILED_SILENTLY, 741 FAILED, 742 UPDATED, 743 INSTALLED, 744 ENABLED 745 }; 746 747 void BlackListWebGL() { 748 static const std::string json_blacklist = 749 "{\n" 750 " \"name\": \"gpu blacklist\",\n" 751 " \"version\": \"1.0\",\n" 752 " \"entries\": [\n" 753 " {\n" 754 " \"id\": 1,\n" 755 " \"features\": [\"webgl\"]\n" 756 " }\n" 757 " ]\n" 758 "}"; 759 gpu::GPUInfo gpu_info; 760 content::GpuDataManager::GetInstance()->InitializeForTesting( 761 json_blacklist, gpu_info); 762 } 763 764 // Helper method to set up a WindowedNotificationObserver to wait for a 765 // specific CrxInstaller to finish if we don't know the value of the 766 // |installer| yet. 767 static bool IsCrxInstallerDone(extensions::CrxInstaller** installer, 768 const content::NotificationSource& source, 769 const content::NotificationDetails& details) { 770 return content::Source<extensions::CrxInstaller>(source).ptr() == 771 *installer; 772 } 773 774 void UpdateExtension(const std::string& id, 775 const base::FilePath& in_path, 776 UpdateState expected_state) { 777 ASSERT_TRUE(base::PathExists(in_path)); 778 779 // We need to copy this to a temporary location because Update() will delete 780 // it. 781 base::FilePath path = temp_dir().path(); 782 path = path.Append(in_path.BaseName()); 783 ASSERT_TRUE(base::CopyFile(in_path, path)); 784 785 int previous_enabled_extension_count = 786 registry()->enabled_extensions().size(); 787 int previous_installed_extension_count = 788 previous_enabled_extension_count + 789 registry()->disabled_extensions().size(); 790 791 extensions::CrxInstaller* installer = NULL; 792 content::WindowedNotificationObserver observer( 793 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 794 base::Bind(&IsCrxInstallerDone, &installer)); 795 service()->UpdateExtension(id, path, true, &installer); 796 797 if (installer) 798 observer.Wait(); 799 else 800 base::RunLoop().RunUntilIdle(); 801 802 std::vector<base::string16> errors = GetErrors(); 803 int error_count = errors.size(); 804 int enabled_extension_count = registry()->enabled_extensions().size(); 805 int installed_extension_count = 806 enabled_extension_count + registry()->disabled_extensions().size(); 807 808 int expected_error_count = (expected_state == FAILED) ? 1 : 0; 809 EXPECT_EQ(expected_error_count, error_count) << path.value(); 810 811 if (expected_state <= FAILED) { 812 EXPECT_EQ(previous_enabled_extension_count, 813 enabled_extension_count); 814 EXPECT_EQ(previous_installed_extension_count, 815 installed_extension_count); 816 } else { 817 int expected_installed_extension_count = 818 (expected_state >= INSTALLED) ? 1 : 0; 819 int expected_enabled_extension_count = 820 (expected_state >= ENABLED) ? 1 : 0; 821 EXPECT_EQ(expected_installed_extension_count, 822 installed_extension_count); 823 EXPECT_EQ(expected_enabled_extension_count, 824 enabled_extension_count); 825 } 826 827 // Update() should the temporary input file. 828 EXPECT_FALSE(base::PathExists(path)); 829 } 830 831 void TerminateExtension(const std::string& id) { 832 const Extension* extension = service()->GetInstalledExtension(id); 833 if (!extension) { 834 ADD_FAILURE(); 835 return; 836 } 837 service()->TrackTerminatedExtensionForTest(extension); 838 } 839 840 size_t GetPrefKeyCount() { 841 const base::DictionaryValue* dict = 842 profile()->GetPrefs()->GetDictionary("extensions.settings"); 843 if (!dict) { 844 ADD_FAILURE(); 845 return 0; 846 } 847 return dict->size(); 848 } 849 850 void UninstallExtension(const std::string& id, bool use_helper) { 851 // Verify that the extension is installed. 852 base::FilePath extension_path = extensions_install_dir().AppendASCII(id); 853 EXPECT_TRUE(base::PathExists(extension_path)); 854 size_t pref_key_count = GetPrefKeyCount(); 855 EXPECT_GT(pref_key_count, 0u); 856 ValidateIntegerPref(id, "state", Extension::ENABLED); 857 858 // Uninstall it. 859 if (use_helper) { 860 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper( 861 service(), id, ExtensionService::UNINSTALL_REASON_FOR_TESTING)); 862 } else { 863 EXPECT_TRUE(service()->UninstallExtension( 864 id, ExtensionService::UNINSTALL_REASON_FOR_TESTING, NULL)); 865 } 866 --expected_extensions_count_; 867 868 // We should get an unload notification. 869 EXPECT_FALSE(unloaded_id_.empty()); 870 EXPECT_EQ(id, unloaded_id_); 871 872 // Verify uninstalled state. 873 size_t new_pref_key_count = GetPrefKeyCount(); 874 if (new_pref_key_count == pref_key_count) { 875 ValidateIntegerPref(id, "location", 876 Extension::EXTERNAL_EXTENSION_UNINSTALLED); 877 } else { 878 EXPECT_EQ(new_pref_key_count, pref_key_count - 1); 879 } 880 881 // The extension should not be in the service anymore. 882 EXPECT_FALSE(service()->GetInstalledExtension(id)); 883 base::RunLoop().RunUntilIdle(); 884 885 // The directory should be gone. 886 EXPECT_FALSE(base::PathExists(extension_path)); 887 } 888 889 void ValidatePrefKeyCount(size_t count) { 890 EXPECT_EQ(count, GetPrefKeyCount()); 891 } 892 893 testing::AssertionResult ValidateBooleanPref( 894 const std::string& extension_id, 895 const std::string& pref_path, 896 bool expected_val) { 897 std::string msg = "while checking: "; 898 msg += extension_id; 899 msg += " "; 900 msg += pref_path; 901 msg += " == "; 902 msg += expected_val ? "true" : "false"; 903 904 PrefService* prefs = profile()->GetPrefs(); 905 const base::DictionaryValue* dict = 906 prefs->GetDictionary("extensions.settings"); 907 if (!dict) { 908 return testing::AssertionFailure() 909 << "extension.settings does not exist " << msg; 910 } 911 912 const base::DictionaryValue* pref = NULL; 913 if (!dict->GetDictionary(extension_id, &pref)) { 914 return testing::AssertionFailure() 915 << "extension pref does not exist " << msg; 916 } 917 918 bool val; 919 if (!pref->GetBoolean(pref_path, &val)) { 920 return testing::AssertionFailure() 921 << pref_path << " pref not found " << msg; 922 } 923 924 return expected_val == val 925 ? testing::AssertionSuccess() 926 : testing::AssertionFailure() << "base::Value is incorrect " << msg; 927 } 928 929 bool IsPrefExist(const std::string& extension_id, 930 const std::string& pref_path) { 931 const base::DictionaryValue* dict = 932 profile()->GetPrefs()->GetDictionary("extensions.settings"); 933 if (dict == NULL) return false; 934 const base::DictionaryValue* pref = NULL; 935 if (!dict->GetDictionary(extension_id, &pref)) { 936 return false; 937 } 938 if (pref == NULL) { 939 return false; 940 } 941 bool val; 942 if (!pref->GetBoolean(pref_path, &val)) { 943 return false; 944 } 945 return true; 946 } 947 948 void ValidateIntegerPref(const std::string& extension_id, 949 const std::string& pref_path, 950 int expected_val) { 951 std::string msg = " while checking: "; 952 msg += extension_id; 953 msg += " "; 954 msg += pref_path; 955 msg += " == "; 956 msg += base::IntToString(expected_val); 957 958 PrefService* prefs = profile()->GetPrefs(); 959 const base::DictionaryValue* dict = 960 prefs->GetDictionary("extensions.settings"); 961 ASSERT_TRUE(dict != NULL) << msg; 962 const base::DictionaryValue* pref = NULL; 963 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; 964 EXPECT_TRUE(pref != NULL) << msg; 965 int val; 966 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg; 967 EXPECT_EQ(expected_val, val) << msg; 968 } 969 970 void ValidateStringPref(const std::string& extension_id, 971 const std::string& pref_path, 972 const std::string& expected_val) { 973 std::string msg = " while checking: "; 974 msg += extension_id; 975 msg += ".manifest."; 976 msg += pref_path; 977 msg += " == "; 978 msg += expected_val; 979 980 const base::DictionaryValue* dict = 981 profile()->GetPrefs()->GetDictionary("extensions.settings"); 982 ASSERT_TRUE(dict != NULL) << msg; 983 const base::DictionaryValue* pref = NULL; 984 std::string manifest_path = extension_id + ".manifest"; 985 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg; 986 EXPECT_TRUE(pref != NULL) << msg; 987 std::string val; 988 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg; 989 EXPECT_EQ(expected_val, val) << msg; 990 } 991 992 void SetPref(const std::string& extension_id, 993 const std::string& pref_path, 994 base::Value* value, 995 const std::string& msg) { 996 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings"); 997 base::DictionaryValue* dict = update.Get(); 998 ASSERT_TRUE(dict != NULL) << msg; 999 base::DictionaryValue* pref = NULL; 1000 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; 1001 EXPECT_TRUE(pref != NULL) << msg; 1002 pref->Set(pref_path, value); 1003 } 1004 1005 void SetPrefInteg(const std::string& extension_id, 1006 const std::string& pref_path, 1007 int value) { 1008 std::string msg = " while setting: "; 1009 msg += extension_id; 1010 msg += " "; 1011 msg += pref_path; 1012 msg += " = "; 1013 msg += base::IntToString(value); 1014 1015 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg); 1016 } 1017 1018 void SetPrefBool(const std::string& extension_id, 1019 const std::string& pref_path, 1020 bool value) { 1021 std::string msg = " while setting: "; 1022 msg += extension_id + " " + pref_path; 1023 msg += " = "; 1024 msg += (value ? "true" : "false"); 1025 1026 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg); 1027 } 1028 1029 void ClearPref(const std::string& extension_id, 1030 const std::string& pref_path) { 1031 std::string msg = " while clearing: "; 1032 msg += extension_id + " " + pref_path; 1033 1034 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings"); 1035 base::DictionaryValue* dict = update.Get(); 1036 ASSERT_TRUE(dict != NULL) << msg; 1037 base::DictionaryValue* pref = NULL; 1038 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; 1039 EXPECT_TRUE(pref != NULL) << msg; 1040 pref->Remove(pref_path, NULL); 1041 } 1042 1043 void SetPrefStringSet(const std::string& extension_id, 1044 const std::string& pref_path, 1045 const std::set<std::string>& value) { 1046 std::string msg = " while setting: "; 1047 msg += extension_id + " " + pref_path; 1048 1049 base::ListValue* list_value = new base::ListValue(); 1050 for (std::set<std::string>::const_iterator iter = value.begin(); 1051 iter != value.end(); ++iter) 1052 list_value->Append(new base::StringValue(*iter)); 1053 1054 SetPref(extension_id, pref_path, list_value, msg); 1055 } 1056 1057 void InitPluginService() { 1058#if defined(ENABLE_PLUGINS) 1059 PluginService::GetInstance()->Init(); 1060#endif 1061 } 1062 1063 void InitializeExtensionSyncService() { 1064 extension_sync_service_.reset(new ExtensionSyncService( 1065 profile(), ExtensionPrefs::Get(browser_context()), service())); 1066 } 1067 1068 extensions::ManagementPolicy* GetManagementPolicy() { 1069 return ExtensionSystem::Get(browser_context())->management_policy(); 1070 } 1071 1072 ExtensionSyncService* extension_sync_service() { 1073 return extension_sync_service_.get(); 1074 } 1075 1076 protected: 1077 scoped_ptr<ExtensionSyncService> extension_sync_service_; 1078 extensions::ExtensionList loaded_; 1079 std::string unloaded_id_; 1080 UnloadedExtensionInfo::Reason unloaded_reason_; 1081 const Extension* installed_; 1082 bool was_update_; 1083 std::string old_name_; 1084 FeatureSwitch::ScopedOverride override_external_install_prompt_; 1085 1086 private: 1087 // Create a CrxInstaller and install the CRX file. 1088 // Instead of calling this method yourself, use InstallCRX(), which does extra 1089 // error checking. 1090 void InstallCRXInternal(const base::FilePath& crx_path) { 1091 InstallCRXInternal(crx_path, Extension::NO_FLAGS); 1092 } 1093 1094 void InstallCRXInternal(const base::FilePath& crx_path, int creation_flags) { 1095 ASSERT_TRUE(base::PathExists(crx_path)) 1096 << "Path does not exist: "<< crx_path.value().c_str(); 1097 scoped_refptr<CrxInstaller> installer( 1098 CrxInstaller::CreateSilent(service())); 1099 installer->set_creation_flags(creation_flags); 1100 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT)) 1101 installer->set_allow_silent_install(true); 1102 1103 content::WindowedNotificationObserver observer( 1104 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 1105 content::Source<extensions::CrxInstaller>(installer)); 1106 1107 installer->InstallCrx(crx_path); 1108 1109 observer.Wait(); 1110 } 1111 1112 size_t expected_extensions_count_; 1113 content::NotificationRegistrar registrar_; 1114}; 1115 1116// Receives notifications from a PackExtensionJob, indicating either that 1117// packing succeeded or that there was some error. 1118class PackExtensionTestClient : public extensions::PackExtensionJob::Client { 1119 public: 1120 PackExtensionTestClient(const base::FilePath& expected_crx_path, 1121 const base::FilePath& expected_private_key_path); 1122 virtual void OnPackSuccess(const base::FilePath& crx_path, 1123 const base::FilePath& private_key_path) OVERRIDE; 1124 virtual void OnPackFailure(const std::string& error_message, 1125 ExtensionCreator::ErrorType type) OVERRIDE; 1126 1127 private: 1128 const base::FilePath expected_crx_path_; 1129 const base::FilePath expected_private_key_path_; 1130 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient); 1131}; 1132 1133PackExtensionTestClient::PackExtensionTestClient( 1134 const base::FilePath& expected_crx_path, 1135 const base::FilePath& expected_private_key_path) 1136 : expected_crx_path_(expected_crx_path), 1137 expected_private_key_path_(expected_private_key_path) {} 1138 1139// If packing succeeded, we make sure that the package names match our 1140// expectations. 1141void PackExtensionTestClient::OnPackSuccess( 1142 const base::FilePath& crx_path, 1143 const base::FilePath& private_key_path) { 1144 // We got the notification and processed it; we don't expect any further tasks 1145 // to be posted to the current thread, so we should stop blocking and continue 1146 // on with the rest of the test. 1147 // This call to |Quit()| matches the call to |Run()| in the 1148 // |PackPunctuatedExtension| test. 1149 base::MessageLoop::current()->Quit(); 1150 EXPECT_EQ(expected_crx_path_.value(), crx_path.value()); 1151 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value()); 1152 ASSERT_TRUE(base::PathExists(private_key_path)); 1153} 1154 1155// The tests are designed so that we never expect to see a packing error. 1156void PackExtensionTestClient::OnPackFailure(const std::string& error_message, 1157 ExtensionCreator::ErrorType type) { 1158 if (type == ExtensionCreator::kCRXExists) 1159 FAIL() << "Packing should not fail."; 1160 else 1161 FAIL() << "Existing CRX should have been overwritten."; 1162} 1163 1164// Test loading good extensions from the profile directory. 1165TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) { 1166 InitPluginService(); 1167 InitializeGoodInstalledExtensionService(); 1168 service()->Init(); 1169 1170 uint32 expected_num_extensions = 3u; 1171 ASSERT_EQ(expected_num_extensions, loaded_.size()); 1172 1173 EXPECT_EQ(std::string(good0), loaded_[0]->id()); 1174 EXPECT_EQ(std::string("My extension 1"), 1175 loaded_[0]->name()); 1176 EXPECT_EQ(std::string("The first extension that I made."), 1177 loaded_[0]->description()); 1178 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location()); 1179 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false)); 1180 EXPECT_EQ(expected_num_extensions, registry()->enabled_extensions().size()); 1181 1182 ValidatePrefKeyCount(3); 1183 ValidateIntegerPref(good0, "state", Extension::ENABLED); 1184 ValidateIntegerPref(good0, "location", Manifest::INTERNAL); 1185 ValidateIntegerPref(good1, "state", Extension::ENABLED); 1186 ValidateIntegerPref(good1, "location", Manifest::INTERNAL); 1187 ValidateIntegerPref(good2, "state", Extension::ENABLED); 1188 ValidateIntegerPref(good2, "location", Manifest::INTERNAL); 1189 1190 URLPatternSet expected_patterns; 1191 AddPattern(&expected_patterns, "file:///*"); 1192 AddPattern(&expected_patterns, "http://*.google.com/*"); 1193 AddPattern(&expected_patterns, "https://*.google.com/*"); 1194 const Extension* extension = loaded_[0].get(); 1195 const extensions::UserScriptList& scripts = 1196 extensions::ContentScriptsInfo::GetContentScripts(extension); 1197 ASSERT_EQ(2u, scripts.size()); 1198 EXPECT_EQ(expected_patterns, scripts[0].url_patterns()); 1199 EXPECT_EQ(2u, scripts[0].js_scripts().size()); 1200 ExtensionResource resource00(extension->id(), 1201 scripts[0].js_scripts()[0].extension_root(), 1202 scripts[0].js_scripts()[0].relative_path()); 1203 base::FilePath expected_path = 1204 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js")); 1205 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path)); 1206 ExtensionResource resource01(extension->id(), 1207 scripts[0].js_scripts()[1].extension_root(), 1208 scripts[0].js_scripts()[1].relative_path()); 1209 expected_path = 1210 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js")); 1211 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path)); 1212 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension)); 1213 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size()); 1214 EXPECT_EQ("http://*.news.com/*", 1215 scripts[1].url_patterns().begin()->GetAsString()); 1216 ExtensionResource resource10(extension->id(), 1217 scripts[1].js_scripts()[0].extension_root(), 1218 scripts[1].js_scripts()[0].relative_path()); 1219 expected_path = 1220 extension->path().AppendASCII("js_files").AppendASCII("script3.js"); 1221 expected_path = base::MakeAbsoluteFilePath(expected_path); 1222 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path)); 1223 1224 expected_patterns.ClearPatterns(); 1225 AddPattern(&expected_patterns, "http://*.google.com/*"); 1226 AddPattern(&expected_patterns, "https://*.google.com/*"); 1227 EXPECT_EQ( 1228 expected_patterns, 1229 extension->permissions_data()->active_permissions()->explicit_hosts()); 1230 1231 EXPECT_EQ(std::string(good1), loaded_[1]->id()); 1232 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name()); 1233 EXPECT_EQ(std::string(), loaded_[1]->description()); 1234 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"), 1235 extensions::BackgroundInfo::GetBackgroundURL(loaded_[1].get())); 1236 EXPECT_EQ(0u, 1237 extensions::ContentScriptsInfo::GetContentScripts(loaded_[1].get()) 1238 .size()); 1239 1240 // We don't parse the plugins section on Chrome OS. 1241#if defined(OS_CHROMEOS) 1242 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_[1].get())); 1243#else 1244 ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_[1].get())); 1245 const std::vector<extensions::PluginInfo>* plugins = 1246 extensions::PluginInfo::GetPlugins(loaded_[1].get()); 1247 ASSERT_TRUE(plugins); 1248 ASSERT_EQ(2u, plugins->size()); 1249 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(), 1250 plugins->at(0).path.value()); 1251 EXPECT_TRUE(plugins->at(0).is_public); 1252 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(), 1253 plugins->at(1).path.value()); 1254 EXPECT_FALSE(plugins->at(1).is_public); 1255#endif 1256 1257 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location()); 1258 1259 int index = expected_num_extensions - 1; 1260 EXPECT_EQ(std::string(good2), loaded_[index]->id()); 1261 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name()); 1262 EXPECT_EQ(std::string(), loaded_[index]->description()); 1263 EXPECT_EQ(0u, 1264 extensions::ContentScriptsInfo::GetContentScripts( 1265 loaded_[index].get()).size()); 1266 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location()); 1267}; 1268 1269// Test loading bad extensions from the profile directory. 1270TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) { 1271 // Initialize the test dir with a bad Preferences/extensions. 1272 base::FilePath source_install_dir = 1273 data_dir().AppendASCII("bad").AppendASCII("Extensions"); 1274 base::FilePath pref_path = 1275 source_install_dir.DirName().Append(chrome::kPreferencesFilename); 1276 1277 InitializeInstalledExtensionService(pref_path, source_install_dir); 1278 1279 service()->Init(); 1280 1281 ASSERT_EQ(4u, GetErrors().size()); 1282 ASSERT_EQ(0u, loaded_.size()); 1283 1284 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[0]), 1285 std::string("Could not load extension from '*'. ") + 1286 extensions::manifest_errors::kManifestUnreadable)) << 1287 base::UTF16ToUTF8(GetErrors()[0]); 1288 1289 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[1]), 1290 std::string("Could not load extension from '*'. ") + 1291 extensions::manifest_errors::kManifestUnreadable)) << 1292 base::UTF16ToUTF8(GetErrors()[1]); 1293 1294 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[2]), 1295 std::string("Could not load extension from '*'. ") + 1296 extensions::manifest_errors::kMissingFile)) << 1297 base::UTF16ToUTF8(GetErrors()[2]); 1298 1299 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[3]), 1300 std::string("Could not load extension from '*'. ") + 1301 extensions::manifest_errors::kManifestUnreadable)) << 1302 base::UTF16ToUTF8(GetErrors()[3]); 1303}; 1304 1305// Test various cases for delayed install because of missing imports. 1306TEST_F(ExtensionServiceTest, PendingImports) { 1307 InitPluginService(); 1308 1309 base::FilePath source_install_dir = 1310 data_dir().AppendASCII("pending_updates_with_imports").AppendASCII( 1311 "Extensions"); 1312 base::FilePath pref_path = 1313 source_install_dir.DirName().Append(chrome::kPreferencesFilename); 1314 1315 InitializeInstalledExtensionService(pref_path, source_install_dir); 1316 1317 // Verify there are no pending extensions initially. 1318 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions()); 1319 1320 service()->Init(); 1321 // Wait for GarbageCollectExtensions task to complete. 1322 base::RunLoop().RunUntilIdle(); 1323 1324 // These extensions are used by the extensions we test below, they must be 1325 // installed. 1326 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII( 1327 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0"))); 1328 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII( 1329 "hpiknbiabeeppbpihjehijgoemciehgk/2"))); 1330 1331 // Each of these extensions should have been rejected because of dependencies 1332 // that cannot be satisfied. 1333 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); 1334 EXPECT_FALSE( 1335 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); 1336 EXPECT_FALSE( 1337 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")); 1338 EXPECT_FALSE( 1339 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")); 1340 EXPECT_FALSE( 1341 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")); 1342 EXPECT_FALSE( 1343 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc")); 1344 EXPECT_FALSE( 1345 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc")); 1346 1347 // Make sure the import started for the extension with a dependency. 1348 EXPECT_TRUE( 1349 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj")); 1350 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS, 1351 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj")); 1352 1353 EXPECT_FALSE(base::PathExists(extensions_install_dir().AppendASCII( 1354 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0"))); 1355 1356 EXPECT_TRUE(service()->pending_extension_manager()->HasPendingExtensions()); 1357 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee"); 1358 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id)); 1359 // Remove it because we are not testing the pending extension manager's 1360 // ability to download and install extensions. 1361 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id)); 1362} 1363 1364// Test installing extensions. This test tries to install few extensions using 1365// crx files. If you need to change those crx files, feel free to repackage 1366// them, throw away the key used and change the id's above. 1367TEST_F(ExtensionServiceTest, InstallExtension) { 1368 InitializeEmptyExtensionService(); 1369 1370 // Extensions not enabled. 1371 service()->set_extensions_enabled(false); 1372 base::FilePath path = data_dir().AppendASCII("good.crx"); 1373 InstallCRX(path, INSTALL_FAILED); 1374 service()->set_extensions_enabled(true); 1375 1376 ValidatePrefKeyCount(0); 1377 1378 // A simple extension that should install without error. 1379 path = data_dir().AppendASCII("good.crx"); 1380 InstallCRX(path, INSTALL_NEW); 1381 // TODO(erikkay): verify the contents of the installed extension. 1382 1383 int pref_count = 0; 1384 ValidatePrefKeyCount(++pref_count); 1385 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 1386 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL); 1387 1388 // An extension with page actions. 1389 path = data_dir().AppendASCII("page_action.crx"); 1390 InstallCRX(path, INSTALL_NEW); 1391 ValidatePrefKeyCount(++pref_count); 1392 ValidateIntegerPref(page_action, "state", Extension::ENABLED); 1393 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL); 1394 1395 // Bad signature. 1396 path = data_dir().AppendASCII("bad_signature.crx"); 1397 InstallCRX(path, INSTALL_FAILED); 1398 ValidatePrefKeyCount(pref_count); 1399 1400 // 0-length extension file. 1401 path = data_dir().AppendASCII("not_an_extension.crx"); 1402 InstallCRX(path, INSTALL_FAILED); 1403 ValidatePrefKeyCount(pref_count); 1404 1405 // Bad magic number. 1406 path = data_dir().AppendASCII("bad_magic.crx"); 1407 InstallCRX(path, INSTALL_FAILED); 1408 ValidatePrefKeyCount(pref_count); 1409 1410 // Packed extensions may have folders or files that have underscores. 1411 // This will only cause a warning, rather than a fatal error. 1412 path = data_dir().AppendASCII("bad_underscore.crx"); 1413 InstallCRX(path, INSTALL_NEW); 1414 ValidatePrefKeyCount(++pref_count); 1415 1416 // A test for an extension with a 2048-bit public key. 1417 path = data_dir().AppendASCII("good2048.crx"); 1418 InstallCRX(path, INSTALL_NEW); 1419 ValidatePrefKeyCount(++pref_count); 1420 ValidateIntegerPref(good2048, "state", Extension::ENABLED); 1421 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL); 1422 1423 // TODO(erikkay): add more tests for many of the failure cases. 1424 // TODO(erikkay): add tests for upgrade cases. 1425} 1426 1427struct MockExtensionRegistryObserver 1428 : public extensions::ExtensionRegistryObserver { 1429 virtual void OnExtensionWillBeInstalled( 1430 content::BrowserContext* browser_context, 1431 const Extension* extension, 1432 bool is_update, 1433 bool from_ephemeral, 1434 const std::string& old_name) OVERRIDE { 1435 last_extension_installed = extension->id(); 1436 } 1437 1438 virtual void OnExtensionUninstalled(content::BrowserContext* browser_context, 1439 const Extension* extension) OVERRIDE { 1440 last_extension_uninstalled = extension->id(); 1441 } 1442 1443 std::string last_extension_installed; 1444 std::string last_extension_uninstalled; 1445}; 1446 1447// Test that correct notifications are sent to ExtensionRegistryObserver on 1448// extension install and uninstall. 1449TEST_F(ExtensionServiceTest, InstallObserverNotified) { 1450 InitializeEmptyExtensionService(); 1451 1452 extensions::ExtensionRegistry* registry( 1453 extensions::ExtensionRegistry::Get(profile())); 1454 MockExtensionRegistryObserver observer; 1455 registry->AddObserver(&observer); 1456 1457 // A simple extension that should install without error. 1458 ASSERT_TRUE(observer.last_extension_installed.empty()); 1459 base::FilePath path = data_dir().AppendASCII("good.crx"); 1460 InstallCRX(path, INSTALL_NEW); 1461 ASSERT_EQ(good_crx, observer.last_extension_installed); 1462 1463 // Uninstall the extension. 1464 ASSERT_TRUE(observer.last_extension_uninstalled.empty()); 1465 UninstallExtension(good_crx, false); 1466 ASSERT_EQ(good_crx, observer.last_extension_uninstalled); 1467 1468 registry->RemoveObserver(&observer); 1469} 1470 1471// Tests that flags passed to OnExternalExtensionFileFound() make it to the 1472// extension object. 1473TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) { 1474 const char kPrefFromBookmark[] = "from_bookmark"; 1475 1476 InitializeEmptyExtensionService(); 1477 1478 base::FilePath path = data_dir().AppendASCII("good.crx"); 1479 service()->set_extensions_enabled(true); 1480 1481 // Register and install an external extension. 1482 Version version("1.0.0.0"); 1483 content::WindowedNotificationObserver observer( 1484 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 1485 content::NotificationService::AllSources()); 1486 if (service()->OnExternalExtensionFileFound(good_crx, 1487 &version, 1488 path, 1489 Manifest::EXTERNAL_PREF, 1490 Extension::FROM_BOOKMARK, 1491 false /* mark_acknowledged */)) { 1492 observer.Wait(); 1493 } 1494 1495 const Extension* extension = service()->GetExtensionById(good_crx, false); 1496 ASSERT_TRUE(extension); 1497 ASSERT_TRUE(extension->from_bookmark()); 1498 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true)); 1499 1500 // Upgrade to version 2.0, the flag should be preserved. 1501 path = data_dir().AppendASCII("good2.crx"); 1502 UpdateExtension(good_crx, path, ENABLED); 1503 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true)); 1504 extension = service()->GetExtensionById(good_crx, false); 1505 ASSERT_TRUE(extension); 1506 ASSERT_TRUE(extension->from_bookmark()); 1507} 1508 1509// Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED 1510TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) { 1511 InitializeEmptyExtensionService(); 1512 1513 base::FilePath path = data_dir().AppendASCII("good.crx"); 1514 service()->set_extensions_enabled(true); 1515 1516 // Install an external extension. 1517 Version version("1.0.0.0"); 1518 content::WindowedNotificationObserver observer( 1519 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 1520 content::NotificationService::AllSources()); 1521 if (service()->OnExternalExtensionFileFound(good_crx, 1522 &version, 1523 path, 1524 Manifest::EXTERNAL_PREF, 1525 Extension::NO_FLAGS, 1526 false)) { 1527 observer.Wait(); 1528 } 1529 1530 ASSERT_TRUE(service()->GetExtensionById(good_crx, false)); 1531 1532 // Uninstall it and check that its killbit gets set. 1533 UninstallExtension(good_crx, false); 1534 ValidateIntegerPref(good_crx, "location", 1535 Extension::EXTERNAL_EXTENSION_UNINSTALLED); 1536 1537 // Try to re-install it externally. This should fail because of the killbit. 1538 service()->OnExternalExtensionFileFound(good_crx, 1539 &version, 1540 path, 1541 Manifest::EXTERNAL_PREF, 1542 Extension::NO_FLAGS, 1543 false); 1544 base::RunLoop().RunUntilIdle(); 1545 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false)); 1546 ValidateIntegerPref(good_crx, "location", 1547 Extension::EXTERNAL_EXTENSION_UNINSTALLED); 1548 1549 version = Version("1.0.0.1"); 1550 // Repeat the same thing with a newer version of the extension. 1551 path = data_dir().AppendASCII("good2.crx"); 1552 service()->OnExternalExtensionFileFound(good_crx, 1553 &version, 1554 path, 1555 Manifest::EXTERNAL_PREF, 1556 Extension::NO_FLAGS, 1557 false); 1558 base::RunLoop().RunUntilIdle(); 1559 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false)); 1560 ValidateIntegerPref(good_crx, "location", 1561 Extension::EXTERNAL_EXTENSION_UNINSTALLED); 1562 1563 // Try adding the same extension from an external update URL. 1564 ASSERT_FALSE(service()->pending_extension_manager()->AddFromExternalUpdateUrl( 1565 good_crx, 1566 std::string(), 1567 GURL("http:://fake.update/url"), 1568 Manifest::EXTERNAL_PREF_DOWNLOAD, 1569 Extension::NO_FLAGS, 1570 false)); 1571 1572 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx)); 1573} 1574 1575// Test that uninstalling an external extension does not crash when 1576// the extension could not be loaded. 1577// This extension shown in preferences file requires an experimental permission. 1578// It could not be loaded without such permission. 1579TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) { 1580 base::FilePath source_install_dir = 1581 data_dir().AppendASCII("good").AppendASCII("Extensions"); 1582 // The preference contains an external extension 1583 // that requires 'experimental' permission. 1584 base::FilePath pref_path = source_install_dir 1585 .DirName() 1586 .AppendASCII("PreferencesExperimental"); 1587 1588 // Aforementioned extension will not be loaded if 1589 // there is no '--enable-experimental-extension-apis' command line flag. 1590 InitializeInstalledExtensionService(pref_path, source_install_dir); 1591 1592 service()->Init(); 1593 1594 // Check and try to uninstall it. 1595 // If we don't check whether the extension is loaded before we uninstall it 1596 // in CheckExternalUninstall, a crash will happen here because we will get or 1597 // dereference a NULL pointer (extension) inside UninstallExtension. 1598 MockExtensionProvider provider(NULL, Manifest::EXTERNAL_REGISTRY); 1599 service()->OnExternalProviderReady(&provider); 1600} 1601 1602// Test that external extensions with incorrect IDs are not installed. 1603TEST_F(ExtensionServiceTest, FailOnWrongId) { 1604 InitializeEmptyExtensionService(); 1605 base::FilePath path = data_dir().AppendASCII("good.crx"); 1606 service()->set_extensions_enabled(true); 1607 1608 Version version("1.0.0.0"); 1609 1610 const std::string wrong_id = all_zero; 1611 const std::string correct_id = good_crx; 1612 ASSERT_NE(correct_id, wrong_id); 1613 1614 // Install an external extension with an ID from the external 1615 // source that is not equal to the ID in the extension manifest. 1616 content::WindowedNotificationObserver observer( 1617 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 1618 content::NotificationService::AllSources()); 1619 service()->OnExternalExtensionFileFound(wrong_id, 1620 &version, 1621 path, 1622 Manifest::EXTERNAL_PREF, 1623 Extension::NO_FLAGS, 1624 false); 1625 1626 observer.Wait(); 1627 ASSERT_FALSE(service()->GetExtensionById(good_crx, false)); 1628 1629 // Try again with the right ID. Expect success. 1630 content::WindowedNotificationObserver observer2( 1631 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 1632 content::NotificationService::AllSources()); 1633 if (service()->OnExternalExtensionFileFound(correct_id, 1634 &version, 1635 path, 1636 Manifest::EXTERNAL_PREF, 1637 Extension::NO_FLAGS, 1638 false)) { 1639 observer2.Wait(); 1640 } 1641 ASSERT_TRUE(service()->GetExtensionById(good_crx, false)); 1642} 1643 1644// Test that external extensions with incorrect versions are not installed. 1645TEST_F(ExtensionServiceTest, FailOnWrongVersion) { 1646 InitializeEmptyExtensionService(); 1647 base::FilePath path = data_dir().AppendASCII("good.crx"); 1648 service()->set_extensions_enabled(true); 1649 1650 // Install an external extension with a version from the external 1651 // source that is not equal to the version in the extension manifest. 1652 Version wrong_version("1.2.3.4"); 1653 content::WindowedNotificationObserver observer( 1654 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 1655 content::NotificationService::AllSources()); 1656 service()->OnExternalExtensionFileFound(good_crx, 1657 &wrong_version, 1658 path, 1659 Manifest::EXTERNAL_PREF, 1660 Extension::NO_FLAGS, 1661 false); 1662 1663 observer.Wait(); 1664 ASSERT_FALSE(service()->GetExtensionById(good_crx, false)); 1665 1666 // Try again with the right version. Expect success. 1667 service()->pending_extension_manager()->Remove(good_crx); 1668 Version correct_version("1.0.0.0"); 1669 content::WindowedNotificationObserver observer2( 1670 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 1671 content::NotificationService::AllSources()); 1672 if (service()->OnExternalExtensionFileFound(good_crx, 1673 &correct_version, 1674 path, 1675 Manifest::EXTERNAL_PREF, 1676 Extension::NO_FLAGS, 1677 false)) { 1678 observer2.Wait(); 1679 } 1680 ASSERT_TRUE(service()->GetExtensionById(good_crx, false)); 1681} 1682 1683// Install a user script (they get converted automatically to an extension) 1684TEST_F(ExtensionServiceTest, InstallUserScript) { 1685 // The details of script conversion are tested elsewhere, this just tests 1686 // integration with ExtensionService. 1687 InitializeEmptyExtensionService(); 1688 1689 base::FilePath path = data_dir().AppendASCII("user_script_basic.user.js"); 1690 1691 ASSERT_TRUE(base::PathExists(path)); 1692 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service())); 1693 installer->set_allow_silent_install(true); 1694 installer->InstallUserScript( 1695 path, 1696 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js")); 1697 1698 base::RunLoop().RunUntilIdle(); 1699 std::vector<base::string16> errors = GetErrors(); 1700 EXPECT_TRUE(installed_) << "Nothing was installed."; 1701 EXPECT_FALSE(was_update_) << path.value(); 1702 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded."; 1703 EXPECT_EQ(0u, errors.size()) << "There were errors: " 1704 << JoinString(errors, ','); 1705 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false)) 1706 << path.value(); 1707 1708 installed_ = NULL; 1709 was_update_ = false; 1710 loaded_.clear(); 1711 ExtensionErrorReporter::GetInstance()->ClearErrors(); 1712} 1713 1714// Extensions don't install during shutdown. 1715TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) { 1716 InitializeEmptyExtensionService(); 1717 1718 // Simulate shutdown. 1719 service()->set_browser_terminating_for_test(true); 1720 1721 base::FilePath path = data_dir().AppendASCII("good.crx"); 1722 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service())); 1723 installer->set_allow_silent_install(true); 1724 installer->InstallCrx(path); 1725 base::RunLoop().RunUntilIdle(); 1726 1727 EXPECT_FALSE(installed_) << "Extension installed during shutdown."; 1728 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown."; 1729} 1730 1731// This tests that the granted permissions preferences are correctly set when 1732// installing an extension. 1733TEST_F(ExtensionServiceTest, GrantedPermissions) { 1734 InitializeEmptyExtensionService(); 1735 base::FilePath path = data_dir().AppendASCII("permissions"); 1736 1737 base::FilePath pem_path = path.AppendASCII("unknown.pem"); 1738 path = path.AppendASCII("unknown"); 1739 1740 ASSERT_TRUE(base::PathExists(pem_path)); 1741 ASSERT_TRUE(base::PathExists(path)); 1742 1743 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); 1744 1745 APIPermissionSet expected_api_perms; 1746 URLPatternSet expected_host_perms; 1747 1748 // Make sure there aren't any granted permissions before the 1749 // extension is installed. 1750 scoped_refptr<PermissionSet> known_perms( 1751 prefs->GetGrantedPermissions(permissions_crx)); 1752 EXPECT_FALSE(known_perms.get()); 1753 1754 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW); 1755 1756 EXPECT_EQ(0u, GetErrors().size()); 1757 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 1758 EXPECT_EQ(permissions_crx, extension->id()); 1759 1760 // Verify that the valid API permissions have been recognized. 1761 expected_api_perms.insert(APIPermission::kTab); 1762 1763 AddPattern(&expected_host_perms, "http://*.google.com/*"); 1764 AddPattern(&expected_host_perms, "https://*.google.com/*"); 1765 AddPattern(&expected_host_perms, "http://*.google.com.hk/*"); 1766 AddPattern(&expected_host_perms, "http://www.example.com/*"); 1767 1768 known_perms = prefs->GetGrantedPermissions(extension->id()); 1769 EXPECT_TRUE(known_perms.get()); 1770 EXPECT_FALSE(known_perms->IsEmpty()); 1771 EXPECT_EQ(expected_api_perms, known_perms->apis()); 1772 EXPECT_FALSE(known_perms->HasEffectiveFullAccess()); 1773 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts()); 1774} 1775 1776 1777#if !defined(OS_CHROMEOS) 1778// This tests that the granted permissions preferences are correctly set for 1779// default apps. 1780TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) { 1781 InitializeEmptyExtensionService(); 1782 base::FilePath path = data_dir().AppendASCII("permissions"); 1783 1784 base::FilePath pem_path = path.AppendASCII("unknown.pem"); 1785 path = path.AppendASCII("unknown"); 1786 1787 ASSERT_TRUE(base::PathExists(pem_path)); 1788 ASSERT_TRUE(base::PathExists(path)); 1789 1790 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); 1791 1792 APIPermissionSet expected_api_perms; 1793 URLPatternSet expected_host_perms; 1794 1795 // Make sure there aren't any granted permissions before the 1796 // extension is installed. 1797 scoped_refptr<PermissionSet> known_perms( 1798 prefs->GetGrantedPermissions(permissions_crx)); 1799 EXPECT_FALSE(known_perms.get()); 1800 1801 const Extension* extension = PackAndInstallCRX( 1802 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT); 1803 1804 EXPECT_EQ(0u, GetErrors().size()); 1805 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 1806 EXPECT_EQ(permissions_crx, extension->id()); 1807 1808 // Verify that the valid API permissions have been recognized. 1809 expected_api_perms.insert(APIPermission::kTab); 1810 1811 known_perms = prefs->GetGrantedPermissions(extension->id()); 1812 EXPECT_TRUE(known_perms.get()); 1813 EXPECT_FALSE(known_perms->IsEmpty()); 1814 EXPECT_EQ(expected_api_perms, known_perms->apis()); 1815 EXPECT_FALSE(known_perms->HasEffectiveFullAccess()); 1816} 1817#endif 1818 1819#if !defined(OS_POSIX) || defined(OS_MACOSX) 1820// Tests that the granted permissions full_access bit gets set correctly when 1821// an extension contains an NPAPI plugin. 1822// Only run this on platforms that support NPAPI plugins. 1823TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) { 1824 InitPluginService(); 1825 1826 InitializeEmptyExtensionService(); 1827 1828 ASSERT_TRUE(base::PathExists(good1_path())); 1829 const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW); 1830 EXPECT_EQ(0u, GetErrors().size()); 1831 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 1832 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); 1833 1834 scoped_refptr<PermissionSet> permissions( 1835 prefs->GetGrantedPermissions(extension->id())); 1836 EXPECT_FALSE(permissions->IsEmpty()); 1837 EXPECT_TRUE(permissions->HasEffectiveFullAccess()); 1838 EXPECT_FALSE(permissions->apis().empty()); 1839 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin)); 1840 1841 // Full access implies full host access too... 1842 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts()); 1843} 1844#endif 1845 1846// Tests that the extension is disabled when permissions are missing from 1847// the extension's granted permissions preferences. (This simulates updating 1848// the browser to a version which recognizes more permissions). 1849TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) { 1850 InitializeEmptyExtensionService(); 1851 1852 base::FilePath path = 1853 data_dir().AppendASCII("permissions").AppendASCII("unknown"); 1854 1855 ASSERT_TRUE(base::PathExists(path)); 1856 1857 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW); 1858 1859 EXPECT_EQ(0u, GetErrors().size()); 1860 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 1861 std::string extension_id = extension->id(); 1862 1863 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); 1864 1865 APIPermissionSet expected_api_permissions; 1866 URLPatternSet expected_host_permissions; 1867 1868 expected_api_permissions.insert(APIPermission::kTab); 1869 AddPattern(&expected_host_permissions, "http://*.google.com/*"); 1870 AddPattern(&expected_host_permissions, "https://*.google.com/*"); 1871 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*"); 1872 AddPattern(&expected_host_permissions, "http://www.example.com/*"); 1873 1874 std::set<std::string> host_permissions; 1875 1876 // Test that the extension is disabled when an API permission is missing from 1877 // the extension's granted api permissions preference. (This simulates 1878 // updating the browser to a version which recognizes a new API permission). 1879 SetPref(extension_id, "granted_permissions.api", 1880 new base::ListValue(), "granted_permissions.api"); 1881 service()->ReloadExtensionsForTest(); 1882 1883 EXPECT_EQ(1u, registry()->disabled_extensions().size()); 1884 extension = registry()->disabled_extensions().begin()->get(); 1885 1886 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id)); 1887 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id)); 1888 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id)); 1889 1890 // Now grant and re-enable the extension, making sure the prefs are updated. 1891 service()->GrantPermissionsAndEnableExtension(extension); 1892 1893 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id)); 1894 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id)); 1895 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id)); 1896 1897 scoped_refptr<PermissionSet> current_perms( 1898 prefs->GetGrantedPermissions(extension_id)); 1899 ASSERT_TRUE(current_perms.get()); 1900 ASSERT_FALSE(current_perms->IsEmpty()); 1901 ASSERT_FALSE(current_perms->HasEffectiveFullAccess()); 1902 ASSERT_EQ(expected_api_permissions, current_perms->apis()); 1903 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts()); 1904 1905 // Tests that the extension is disabled when a host permission is missing from 1906 // the extension's granted host permissions preference. (This simulates 1907 // updating the browser to a version which recognizes additional host 1908 // permissions). 1909 host_permissions.clear(); 1910 current_perms = NULL; 1911 1912 host_permissions.insert("http://*.google.com/*"); 1913 host_permissions.insert("https://*.google.com/*"); 1914 host_permissions.insert("http://*.google.com.hk/*"); 1915 1916 base::ListValue* api_permissions = new base::ListValue(); 1917 api_permissions->Append( 1918 new base::StringValue("tabs")); 1919 SetPref(extension_id, "granted_permissions.api", 1920 api_permissions, "granted_permissions.api"); 1921 SetPrefStringSet( 1922 extension_id, "granted_permissions.scriptable_host", host_permissions); 1923 1924 service()->ReloadExtensionsForTest(); 1925 1926 EXPECT_EQ(1u, registry()->disabled_extensions().size()); 1927 extension = registry()->disabled_extensions().begin()->get(); 1928 1929 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id)); 1930 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id)); 1931 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id)); 1932 1933 // Now grant and re-enable the extension, making sure the prefs are updated. 1934 service()->GrantPermissionsAndEnableExtension(extension); 1935 1936 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id)); 1937 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id)); 1938 1939 current_perms = prefs->GetGrantedPermissions(extension_id); 1940 ASSERT_TRUE(current_perms.get()); 1941 ASSERT_FALSE(current_perms->IsEmpty()); 1942 ASSERT_FALSE(current_perms->HasEffectiveFullAccess()); 1943 ASSERT_EQ(expected_api_permissions, current_perms->apis()); 1944 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts()); 1945} 1946 1947// Test Packaging and installing an extension. 1948TEST_F(ExtensionServiceTest, PackExtension) { 1949 InitializeEmptyExtensionService(); 1950 base::FilePath input_directory = 1951 data_dir() 1952 .AppendASCII("good") 1953 .AppendASCII("Extensions") 1954 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 1955 .AppendASCII("1.0.0.0"); 1956 1957 base::ScopedTempDir temp_dir; 1958 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1959 base::FilePath output_directory = temp_dir.path(); 1960 1961 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx")); 1962 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem")); 1963 1964 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); 1965 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(), 1966 privkey_path, ExtensionCreator::kNoRunFlags)); 1967 ASSERT_TRUE(base::PathExists(crx_path)); 1968 ASSERT_TRUE(base::PathExists(privkey_path)); 1969 1970 // Repeat the run with the pem file gone, and no special flags 1971 // Should refuse to overwrite the existing crx. 1972 base::DeleteFile(privkey_path, false); 1973 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(), 1974 privkey_path, ExtensionCreator::kNoRunFlags)); 1975 1976 // OK, now try it with a flag to overwrite existing crx. Should work. 1977 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(), 1978 privkey_path, ExtensionCreator::kOverwriteCRX)); 1979 1980 // Repeat the run allowing existing crx, but the existing pem is still 1981 // an error. Should fail. 1982 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(), 1983 privkey_path, ExtensionCreator::kOverwriteCRX)); 1984 1985 ASSERT_TRUE(base::PathExists(privkey_path)); 1986 InstallCRX(crx_path, INSTALL_NEW); 1987 1988 // Try packing with invalid paths. 1989 creator.reset(new ExtensionCreator()); 1990 ASSERT_FALSE( 1991 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(), 1992 base::FilePath(), ExtensionCreator::kOverwriteCRX)); 1993 1994 // Try packing an empty directory. Should fail because an empty directory is 1995 // not a valid extension. 1996 base::ScopedTempDir temp_dir2; 1997 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir()); 1998 creator.reset(new ExtensionCreator()); 1999 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path, 2000 base::FilePath(), ExtensionCreator::kOverwriteCRX)); 2001 2002 // Try packing with an invalid manifest. 2003 std::string invalid_manifest_content = "I am not a manifest."; 2004 ASSERT_TRUE(base::WriteFile( 2005 temp_dir2.path().Append(extensions::kManifestFilename), 2006 invalid_manifest_content.c_str(), invalid_manifest_content.size())); 2007 creator.reset(new ExtensionCreator()); 2008 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path, 2009 base::FilePath(), ExtensionCreator::kOverwriteCRX)); 2010 2011 // Try packing with a private key that is a valid key, but invalid for the 2012 // extension. 2013 base::FilePath bad_private_key_dir = 2014 data_dir().AppendASCII("bad_private_key"); 2015 crx_path = output_directory.AppendASCII("bad_private_key.crx"); 2016 privkey_path = data_dir().AppendASCII("bad_private_key.pem"); 2017 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(), 2018 privkey_path, ExtensionCreator::kOverwriteCRX)); 2019} 2020 2021// Test Packaging and installing an extension whose name contains punctuation. 2022TEST_F(ExtensionServiceTest, PackPunctuatedExtension) { 2023 InitializeEmptyExtensionService(); 2024 base::FilePath input_directory = data_dir() 2025 .AppendASCII("good") 2026 .AppendASCII("Extensions") 2027 .AppendASCII(good0) 2028 .AppendASCII("1.0.0.0"); 2029 2030 base::ScopedTempDir temp_dir; 2031 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 2032 2033 // Extension names containing punctuation, and the expected names for the 2034 // packed extensions. 2035 const base::FilePath punctuated_names[] = { 2036 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")), 2037 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")), 2038 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")). 2039 NormalizePathSeparators(), 2040 }; 2041 const base::FilePath expected_crx_names[] = { 2042 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")), 2043 base::FilePath( 2044 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")), 2045 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")), 2046 }; 2047 const base::FilePath expected_private_key_names[] = { 2048 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")), 2049 base::FilePath( 2050 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")), 2051 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")), 2052 }; 2053 2054 for (size_t i = 0; i < arraysize(punctuated_names); ++i) { 2055 SCOPED_TRACE(punctuated_names[i].value().c_str()); 2056 base::FilePath output_dir = temp_dir.path().Append(punctuated_names[i]); 2057 2058 // Copy the extension into the output directory, as PackExtensionJob doesn't 2059 // let us choose where to output the packed extension. 2060 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true)); 2061 2062 base::FilePath expected_crx_path = 2063 temp_dir.path().Append(expected_crx_names[i]); 2064 base::FilePath expected_private_key_path = 2065 temp_dir.path().Append(expected_private_key_names[i]); 2066 PackExtensionTestClient pack_client(expected_crx_path, 2067 expected_private_key_path); 2068 scoped_refptr<extensions::PackExtensionJob> packer( 2069 new extensions::PackExtensionJob(&pack_client, output_dir, 2070 base::FilePath(), 2071 ExtensionCreator::kOverwriteCRX)); 2072 packer->Start(); 2073 2074 // The packer will post a notification task to the current thread's message 2075 // loop when it is finished. We manually run the loop here so that we 2076 // block and catch the notification; otherwise, the process would exit. 2077 // This call to |Run()| is matched by a call to |Quit()| in the 2078 // |PackExtensionTestClient|'s notification handling code. 2079 base::MessageLoop::current()->Run(); 2080 2081 if (HasFatalFailure()) 2082 return; 2083 2084 InstallCRX(expected_crx_path, INSTALL_NEW); 2085 } 2086} 2087 2088TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) { 2089 InitializeEmptyExtensionService(); 2090 2091 base::ScopedTempDir extension_temp_dir; 2092 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir()); 2093 base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext"); 2094 ASSERT_TRUE( 2095 base::CopyDirectory(data_dir() 2096 .AppendASCII("good") 2097 .AppendASCII("Extensions") 2098 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 2099 .AppendASCII("1.0.0.0"), 2100 input_directory, 2101 /*recursive=*/true)); 2102 2103 base::ScopedTempDir output_temp_dir; 2104 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir()); 2105 base::FilePath output_directory = output_temp_dir.path(); 2106 2107 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx")); 2108 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem")); 2109 2110 // Pack the extension once to get a private key. 2111 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); 2112 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(), 2113 privkey_path, ExtensionCreator::kNoRunFlags)) 2114 << creator->error_message(); 2115 ASSERT_TRUE(base::PathExists(crx_path)); 2116 ASSERT_TRUE(base::PathExists(privkey_path)); 2117 2118 base::DeleteFile(crx_path, false); 2119 // Move the pem file into the extension. 2120 base::Move(privkey_path, 2121 input_directory.AppendASCII("privkey.pem")); 2122 2123 // This pack should fail because of the contained private key. 2124 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(), 2125 privkey_path, ExtensionCreator::kNoRunFlags)); 2126 EXPECT_THAT(creator->error_message(), 2127 testing::ContainsRegex( 2128 "extension includes the key file.*privkey.pem")); 2129} 2130 2131// Test Packaging and installing an extension using an openssl generated key. 2132// The openssl is generated with the following: 2133// > openssl genrsa -out privkey.pem 1024 2134// > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem 2135// The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a 2136// PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects. 2137TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) { 2138 InitializeEmptyExtensionService(); 2139 base::FilePath input_directory = 2140 data_dir() 2141 .AppendASCII("good") 2142 .AppendASCII("Extensions") 2143 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 2144 .AppendASCII("1.0.0.0"); 2145 base::FilePath privkey_path( 2146 data_dir().AppendASCII("openssl_privkey_asn1.pem")); 2147 ASSERT_TRUE(base::PathExists(privkey_path)); 2148 2149 base::ScopedTempDir temp_dir; 2150 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 2151 base::FilePath output_directory = temp_dir.path(); 2152 2153 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx")); 2154 2155 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); 2156 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path, 2157 base::FilePath(), ExtensionCreator::kOverwriteCRX)); 2158 2159 InstallCRX(crx_path, INSTALL_NEW); 2160} 2161 2162#if defined(THREAD_SANITIZER) 2163// Flaky under Tsan. http://crbug.com/377702 2164#define MAYBE_InstallTheme DISABLED_InstallTheme 2165#else 2166#define MAYBE_InstallTheme InstallTheme 2167#endif 2168 2169TEST_F(ExtensionServiceTest, MAYBE_InstallTheme) { 2170 InitializeEmptyExtensionService(); 2171 service()->Init(); 2172 2173 // A theme. 2174 base::FilePath path = data_dir().AppendASCII("theme.crx"); 2175 InstallCRX(path, INSTALL_NEW); 2176 int pref_count = 0; 2177 ValidatePrefKeyCount(++pref_count); 2178 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED); 2179 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL); 2180 2181 // A theme when extensions are disabled. Themes can be installed, even when 2182 // extensions are disabled. 2183 service()->set_extensions_enabled(false); 2184 path = data_dir().AppendASCII("theme2.crx"); 2185 InstallCRX(path, INSTALL_NEW); 2186 ValidatePrefKeyCount(++pref_count); 2187 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED); 2188 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL); 2189 2190 // A theme with extension elements. Themes cannot have extension elements, 2191 // so any such elements (like content scripts) should be ignored. 2192 service()->set_extensions_enabled(true); 2193 { 2194 path = data_dir().AppendASCII("theme_with_extension.crx"); 2195 const Extension* extension = InstallCRX(path, INSTALL_NEW); 2196 ValidatePrefKeyCount(++pref_count); 2197 ASSERT_TRUE(extension); 2198 EXPECT_TRUE(extension->is_theme()); 2199 EXPECT_EQ( 2200 0u, 2201 extensions::ContentScriptsInfo::GetContentScripts(extension).size()); 2202 } 2203 2204 // A theme with image resources missing (misspelt path). 2205 path = data_dir().AppendASCII("theme_missing_image.crx"); 2206 InstallCRX(path, INSTALL_FAILED); 2207 ValidatePrefKeyCount(pref_count); 2208} 2209 2210TEST_F(ExtensionServiceTest, LoadLocalizedTheme) { 2211 // Load. 2212 InitializeEmptyExtensionService(); 2213 service()->Init(); 2214 2215 base::FilePath extension_path = data_dir().AppendASCII("theme_i18n"); 2216 2217 extensions::UnpackedInstaller::Create(service())->Load(extension_path); 2218 base::RunLoop().RunUntilIdle(); 2219 EXPECT_EQ(0u, GetErrors().size()); 2220 ASSERT_EQ(1u, loaded_.size()); 2221 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 2222 const Extension* theme = registry()->enabled_extensions().begin()->get(); 2223 EXPECT_EQ("name", theme->name()); 2224 EXPECT_EQ("description", theme->description()); 2225 2226 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a 2227 // temporary directory, but it automatically installs to the extension's 2228 // directory, and we don't want to copy the whole extension for a unittest. 2229 base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename); 2230 ASSERT_TRUE(base::PathExists(theme_file)); 2231 ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive. 2232} 2233 2234// Tests that we can change the ID of an unpacked extension by adding a key 2235// to its manifest. 2236TEST_F(ExtensionServiceTest, UnpackedExtensionCanChangeID) { 2237 InitializeEmptyExtensionService(); 2238 2239 base::ScopedTempDir temp; 2240 ASSERT_TRUE(temp.CreateUniqueTempDir()); 2241 2242 base::FilePath extension_path = temp.path(); 2243 base::FilePath manifest_path = 2244 extension_path.Append(extensions::kManifestFilename); 2245 base::FilePath manifest_no_key = 2246 data_dir().AppendASCII("unpacked").AppendASCII("manifest_no_key.json"); 2247 2248 base::FilePath manifest_with_key = 2249 data_dir().AppendASCII("unpacked").AppendASCII("manifest_with_key.json"); 2250 2251 ASSERT_TRUE(base::PathExists(manifest_no_key)); 2252 ASSERT_TRUE(base::PathExists(manifest_with_key)); 2253 2254 // Load the unpacked extension with no key. 2255 base::CopyFile(manifest_no_key, manifest_path); 2256 extensions::UnpackedInstaller::Create(service())->Load(extension_path); 2257 2258 base::RunLoop().RunUntilIdle(); 2259 EXPECT_EQ(0u, GetErrors().size()); 2260 ASSERT_EQ(1u, loaded_.size()); 2261 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 2262 2263 // Add the key to the manifest. 2264 base::CopyFile(manifest_with_key, manifest_path); 2265 loaded_.clear(); 2266 2267 // Reload the extensions. 2268 service()->ReloadExtensionsForTest(); 2269 const Extension* extension = service()->GetExtensionById(unpacked, false); 2270 EXPECT_EQ(unpacked, extension->id()); 2271 ASSERT_EQ(1u, loaded_.size()); 2272 2273 // TODO(jstritar): Right now this just makes sure we don't crash and burn, but 2274 // we should also test that preferences are preserved. 2275} 2276 2277#if defined(OS_POSIX) 2278TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) { 2279 base::FilePath source_data_dir = 2280 data_dir().AppendASCII("unpacked").AppendASCII("symlinks_allowed"); 2281 2282 // Paths to test data files. 2283 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json"); 2284 ASSERT_TRUE(base::PathExists(source_manifest)); 2285 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png"); 2286 ASSERT_TRUE(base::PathExists(source_icon)); 2287 2288 // Set up the temporary extension directory. 2289 base::ScopedTempDir temp; 2290 ASSERT_TRUE(temp.CreateUniqueTempDir()); 2291 base::FilePath extension_path = temp.path(); 2292 base::FilePath manifest = extension_path.Append( 2293 extensions::kManifestFilename); 2294 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png"); 2295 base::CopyFile(source_manifest, manifest); 2296 base::CreateSymbolicLink(source_icon, icon_symlink); 2297 2298 // Load extension. 2299 InitializeEmptyExtensionService(); 2300 extensions::UnpackedInstaller::Create(service())->Load(extension_path); 2301 base::RunLoop().RunUntilIdle(); 2302 2303 EXPECT_TRUE(GetErrors().empty()); 2304 ASSERT_EQ(1u, loaded_.size()); 2305 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 2306} 2307#endif 2308 2309TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) { 2310 InitializeEmptyExtensionService(); 2311 base::FilePath extension_path = data_dir().AppendASCII("underscore_name"); 2312 extensions::UnpackedInstaller::Create(service())->Load(extension_path); 2313 base::RunLoop().RunUntilIdle(); 2314 EXPECT_EQ(1u, GetErrors().size()); 2315 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 2316} 2317 2318TEST_F(ExtensionServiceTest, InstallLocalizedTheme) { 2319 InitializeEmptyExtensionService(); 2320 service()->Init(); 2321 2322 base::FilePath theme_path = data_dir().AppendASCII("theme_i18n"); 2323 2324 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW); 2325 2326 EXPECT_EQ(0u, GetErrors().size()); 2327 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 2328 EXPECT_EQ("name", theme->name()); 2329 EXPECT_EQ("description", theme->description()); 2330} 2331 2332TEST_F(ExtensionServiceTest, InstallApps) { 2333 InitializeEmptyExtensionService(); 2334 2335 // An empty app. 2336 const Extension* app = 2337 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW); 2338 int pref_count = 0; 2339 ValidatePrefKeyCount(++pref_count); 2340 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 2341 ValidateIntegerPref(app->id(), "state", Extension::ENABLED); 2342 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL); 2343 2344 // Another app with non-overlapping extent. Should succeed. 2345 PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW); 2346 ValidatePrefKeyCount(++pref_count); 2347 2348 // A third app whose extent overlaps the first. Should fail. 2349 PackAndInstallCRX(data_dir().AppendASCII("app3"), INSTALL_FAILED); 2350 ValidatePrefKeyCount(pref_count); 2351} 2352 2353// Tests that file access is OFF by default. 2354TEST_F(ExtensionServiceTest, DefaultFileAccess) { 2355 InitializeEmptyExtensionService(); 2356 const Extension* extension = PackAndInstallCRX( 2357 data_dir().AppendASCII("permissions").AppendASCII("files"), INSTALL_NEW); 2358 EXPECT_EQ(0u, GetErrors().size()); 2359 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 2360 EXPECT_FALSE( 2361 ExtensionPrefs::Get(profile())->AllowFileAccess(extension->id())); 2362} 2363 2364TEST_F(ExtensionServiceTest, UpdateApps) { 2365 InitializeEmptyExtensionService(); 2366 base::FilePath extensions_path = data_dir().AppendASCII("app_update"); 2367 2368 // First install v1 of a hosted app. 2369 const Extension* extension = 2370 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW); 2371 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 2372 std::string id = extension->id(); 2373 ASSERT_EQ(std::string("1"), extension->version()->GetString()); 2374 2375 // Now try updating to v2. 2376 UpdateExtension(id, 2377 extensions_path.AppendASCII("v2.crx"), 2378 ENABLED); 2379 ASSERT_EQ(std::string("2"), 2380 service()->GetExtensionById(id, false)->version()->GetString()); 2381} 2382 2383// Verifies that the NTP page and launch ordinals are kept when updating apps. 2384TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) { 2385 InitializeEmptyExtensionService(); 2386 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting(); 2387 base::FilePath extensions_path = data_dir().AppendASCII("app_update"); 2388 2389 // First install v1 of a hosted app. 2390 const Extension* extension = 2391 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW); 2392 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 2393 std::string id = extension->id(); 2394 ASSERT_EQ(std::string("1"), extension->version()->GetString()); 2395 2396 // Modify the ordinals so we can distinguish them from the defaults. 2397 syncer::StringOrdinal new_page_ordinal = 2398 sorting->GetPageOrdinal(id).CreateAfter(); 2399 syncer::StringOrdinal new_launch_ordinal = 2400 sorting->GetAppLaunchOrdinal(id).CreateBefore(); 2401 2402 sorting->SetPageOrdinal(id, new_page_ordinal); 2403 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal); 2404 2405 // Now try updating to v2. 2406 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED); 2407 ASSERT_EQ(std::string("2"), 2408 service()->GetExtensionById(id, false)->version()->GetString()); 2409 2410 // Verify that the ordinals match. 2411 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id))); 2412 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id))); 2413} 2414 2415// Ensures that the CWS has properly initialized ordinals. 2416TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) { 2417 InitializeEmptyExtensionService(); 2418 service()->component_loader()->Add( 2419 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store"))); 2420 service()->Init(); 2421 2422 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting(); 2423 EXPECT_TRUE( 2424 sorting->GetPageOrdinal(extension_misc::kWebStoreAppId).IsValid()); 2425 EXPECT_TRUE( 2426 sorting->GetAppLaunchOrdinal(extension_misc::kWebStoreAppId).IsValid()); 2427} 2428 2429TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) { 2430 InitializeEmptyExtensionService(); 2431 EXPECT_TRUE(registry()->enabled_extensions().is_empty()); 2432 2433 int pref_count = 0; 2434 2435 // Install app1 with unlimited storage. 2436 const Extension* extension = 2437 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW); 2438 ValidatePrefKeyCount(++pref_count); 2439 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 2440 const std::string id1 = extension->id(); 2441 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission( 2442 APIPermission::kUnlimitedStorage)); 2443 EXPECT_TRUE(extension->web_extent().MatchesURL( 2444 extensions::AppLaunchInfo::GetFullLaunchURL(extension))); 2445 const GURL origin1( 2446 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin()); 2447 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 2448 origin1)); 2449 2450 // Install app2 from the same origin with unlimited storage. 2451 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW); 2452 ValidatePrefKeyCount(++pref_count); 2453 ASSERT_EQ(2u, registry()->enabled_extensions().size()); 2454 const std::string id2 = extension->id(); 2455 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission( 2456 APIPermission::kUnlimitedStorage)); 2457 EXPECT_TRUE(extension->web_extent().MatchesURL( 2458 extensions::AppLaunchInfo::GetFullLaunchURL(extension))); 2459 const GURL origin2( 2460 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin()); 2461 EXPECT_EQ(origin1, origin2); 2462 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 2463 origin2)); 2464 2465 // Uninstall one of them, unlimited storage should still be granted 2466 // to the origin. 2467 UninstallExtension(id1, false); 2468 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 2469 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 2470 origin1)); 2471 2472 // Uninstall the other, unlimited storage should be revoked. 2473 UninstallExtension(id2, false); 2474 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 2475 EXPECT_FALSE( 2476 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 2477 origin2)); 2478} 2479 2480TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) { 2481 InitializeEmptyExtensionService(); 2482 EXPECT_TRUE(registry()->enabled_extensions().is_empty()); 2483 2484 int pref_count = 0; 2485 2486 const Extension* extension = 2487 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW); 2488 ValidatePrefKeyCount(++pref_count); 2489 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 2490 EXPECT_TRUE(extension->is_app()); 2491 const std::string id1 = extension->id(); 2492 const GURL origin1( 2493 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin()); 2494 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected( 2495 origin1)); 2496 2497 // App 4 has a different origin (maps.google.com). 2498 extension = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW); 2499 ValidatePrefKeyCount(++pref_count); 2500 ASSERT_EQ(2u, registry()->enabled_extensions().size()); 2501 const std::string id2 = extension->id(); 2502 const GURL origin2( 2503 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin()); 2504 ASSERT_NE(origin1, origin2); 2505 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected( 2506 origin2)); 2507 2508 UninstallExtension(id1, false); 2509 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 2510 2511 UninstallExtension(id2, false); 2512 2513 EXPECT_TRUE(registry()->enabled_extensions().is_empty()); 2514 EXPECT_FALSE( 2515 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected( 2516 origin1)); 2517 EXPECT_FALSE( 2518 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected( 2519 origin2)); 2520} 2521 2522// Test that when an extension version is reinstalled, nothing happens. 2523TEST_F(ExtensionServiceTest, Reinstall) { 2524 InitializeEmptyExtensionService(); 2525 2526 // A simple extension that should install without error. 2527 base::FilePath path = data_dir().AppendASCII("good.crx"); 2528 InstallCRX(path, INSTALL_NEW); 2529 2530 ValidatePrefKeyCount(1); 2531 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 2532 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL); 2533 2534 // Reinstall the same version, it should overwrite the previous one. 2535 InstallCRX(path, INSTALL_UPDATED); 2536 2537 ValidatePrefKeyCount(1); 2538 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 2539 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL); 2540} 2541 2542// Test that we can determine if extensions came from the 2543// Chrome web store. 2544TEST_F(ExtensionServiceTest, FromWebStore) { 2545 InitializeEmptyExtensionService(); 2546 2547 // A simple extension that should install without error. 2548 base::FilePath path = data_dir().AppendASCII("good.crx"); 2549 // Not from web store. 2550 const Extension* extension = InstallCRX(path, INSTALL_NEW); 2551 std::string id = extension->id(); 2552 2553 ValidatePrefKeyCount(1); 2554 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false)); 2555 ASSERT_FALSE(extension->from_webstore()); 2556 2557 // Test install from web store. 2558 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store. 2559 2560 ValidatePrefKeyCount(1); 2561 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true)); 2562 2563 // Reload so extension gets reinitialized with new value. 2564 service()->ReloadExtensionsForTest(); 2565 extension = service()->GetExtensionById(id, false); 2566 ASSERT_TRUE(extension->from_webstore()); 2567 2568 // Upgrade to version 2.0 2569 path = data_dir().AppendASCII("good2.crx"); 2570 UpdateExtension(good_crx, path, ENABLED); 2571 ValidatePrefKeyCount(1); 2572 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true)); 2573} 2574 2575// Test upgrading a signed extension. 2576TEST_F(ExtensionServiceTest, UpgradeSignedGood) { 2577 InitializeEmptyExtensionService(); 2578 2579 base::FilePath path = data_dir().AppendASCII("good.crx"); 2580 const Extension* extension = InstallCRX(path, INSTALL_NEW); 2581 std::string id = extension->id(); 2582 2583 ASSERT_EQ("1.0.0.0", extension->version()->GetString()); 2584 ASSERT_EQ(0u, GetErrors().size()); 2585 2586 // Upgrade to version 1.0.0.1. 2587 // Also test that the extension's old and new title are correctly retrieved. 2588 path = data_dir().AppendASCII("good2.crx"); 2589 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1"); 2590 extension = service()->GetExtensionById(id, false); 2591 2592 ASSERT_EQ("1.0.0.1", extension->version()->GetString()); 2593 ASSERT_EQ("My updated extension 1", extension->name()); 2594 ASSERT_EQ(0u, GetErrors().size()); 2595} 2596 2597// Test upgrading a signed extension with a bad signature. 2598TEST_F(ExtensionServiceTest, UpgradeSignedBad) { 2599 InitializeEmptyExtensionService(); 2600 2601 base::FilePath path = data_dir().AppendASCII("good.crx"); 2602 InstallCRX(path, INSTALL_NEW); 2603 2604 // Try upgrading with a bad signature. This should fail during the unpack, 2605 // because the key will not match the signature. 2606 path = data_dir().AppendASCII("bad_signature.crx"); 2607 InstallCRX(path, INSTALL_FAILED); 2608} 2609 2610// Test a normal update via the UpdateExtension API 2611TEST_F(ExtensionServiceTest, UpdateExtension) { 2612 InitializeEmptyExtensionService(); 2613 2614 base::FilePath path = data_dir().AppendASCII("good.crx"); 2615 2616 const Extension* good = InstallCRX(path, INSTALL_NEW); 2617 ASSERT_EQ("1.0.0.0", good->VersionString()); 2618 ASSERT_EQ(good_crx, good->id()); 2619 2620 path = data_dir().AppendASCII("good2.crx"); 2621 UpdateExtension(good_crx, path, ENABLED); 2622 ASSERT_EQ( 2623 "1.0.0.1", 2624 service()->GetExtensionById(good_crx, false)->version()->GetString()); 2625} 2626 2627// Extensions should not be updated during browser shutdown. 2628TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) { 2629 InitializeEmptyExtensionService(); 2630 2631 // Install an extension. 2632 base::FilePath path = data_dir().AppendASCII("good.crx"); 2633 const Extension* good = InstallCRX(path, INSTALL_NEW); 2634 ASSERT_EQ(good_crx, good->id()); 2635 2636 // Simulate shutdown. 2637 service()->set_browser_terminating_for_test(true); 2638 2639 // Update should fail and extension should not be updated. 2640 path = data_dir().AppendASCII("good2.crx"); 2641 bool updated = service()->UpdateExtension(good_crx, path, true, NULL); 2642 ASSERT_FALSE(updated); 2643 ASSERT_EQ( 2644 "1.0.0.0", 2645 service()->GetExtensionById(good_crx, false)->version()->GetString()); 2646} 2647 2648// Test updating a not-already-installed extension - this should fail 2649TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) { 2650 InitializeEmptyExtensionService(); 2651 2652 base::FilePath path = data_dir().AppendASCII("good.crx"); 2653 UpdateExtension(good_crx, path, UPDATED); 2654 base::RunLoop().RunUntilIdle(); 2655 2656 ASSERT_EQ(0u, registry()->enabled_extensions().size()); 2657 ASSERT_FALSE(installed_); 2658 ASSERT_EQ(0u, loaded_.size()); 2659} 2660 2661// Makes sure you can't downgrade an extension via UpdateExtension 2662TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) { 2663 InitializeEmptyExtensionService(); 2664 2665 base::FilePath path = data_dir().AppendASCII("good2.crx"); 2666 2667 const Extension* good = InstallCRX(path, INSTALL_NEW); 2668 ASSERT_EQ("1.0.0.1", good->VersionString()); 2669 ASSERT_EQ(good_crx, good->id()); 2670 2671 // Change path from good2.crx -> good.crx 2672 path = data_dir().AppendASCII("good.crx"); 2673 UpdateExtension(good_crx, path, FAILED); 2674 ASSERT_EQ( 2675 "1.0.0.1", 2676 service()->GetExtensionById(good_crx, false)->version()->GetString()); 2677} 2678 2679// Make sure calling update with an identical version does nothing 2680TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) { 2681 InitializeEmptyExtensionService(); 2682 2683 base::FilePath path = data_dir().AppendASCII("good.crx"); 2684 2685 const Extension* good = InstallCRX(path, INSTALL_NEW); 2686 ASSERT_EQ(good_crx, good->id()); 2687 UpdateExtension(good_crx, path, FAILED_SILENTLY); 2688} 2689 2690// Tests that updating an extension does not clobber old state. 2691TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) { 2692 InitializeEmptyExtensionService(); 2693 2694 base::FilePath path = data_dir().AppendASCII("good.crx"); 2695 2696 const Extension* good = InstallCRX(path, INSTALL_NEW); 2697 ASSERT_EQ("1.0.0.0", good->VersionString()); 2698 ASSERT_EQ(good_crx, good->id()); 2699 2700 // Disable it and allow it to run in incognito. These settings should carry 2701 // over to the updated version. 2702 service()->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION); 2703 extensions::util::SetIsIncognitoEnabled(good->id(), profile(), true); 2704 ExtensionPrefs::Get(profile()) 2705 ->SetDidExtensionEscalatePermissions(good, true); 2706 2707 path = data_dir().AppendASCII("good2.crx"); 2708 UpdateExtension(good_crx, path, INSTALLED); 2709 ASSERT_EQ(1u, registry()->disabled_extensions().size()); 2710 const Extension* good2 = service()->GetExtensionById(good_crx, true); 2711 ASSERT_EQ("1.0.0.1", good2->version()->GetString()); 2712 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good2->id(), profile())); 2713 EXPECT_TRUE(ExtensionPrefs::Get(profile()) 2714 ->DidExtensionEscalatePermissions(good2->id())); 2715} 2716 2717// Tests that updating preserves extension location. 2718TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) { 2719 InitializeEmptyExtensionService(); 2720 2721 base::FilePath path = data_dir().AppendASCII("good.crx"); 2722 2723 const Extension* good = 2724 InstallCRXWithLocation(path, Manifest::EXTERNAL_PREF, INSTALL_NEW); 2725 2726 ASSERT_EQ("1.0.0.0", good->VersionString()); 2727 ASSERT_EQ(good_crx, good->id()); 2728 2729 path = data_dir().AppendASCII("good2.crx"); 2730 UpdateExtension(good_crx, path, ENABLED); 2731 const Extension* good2 = service()->GetExtensionById(good_crx, false); 2732 ASSERT_EQ("1.0.0.1", good2->version()->GetString()); 2733 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF); 2734} 2735 2736// Makes sure that LOAD extension types can downgrade. 2737TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) { 2738 InitializeEmptyExtensionService(); 2739 2740 base::ScopedTempDir temp; 2741 ASSERT_TRUE(temp.CreateUniqueTempDir()); 2742 2743 // We'll write the extension manifest dynamically to a temporary path 2744 // to make it easier to change the version number. 2745 base::FilePath extension_path = temp.path(); 2746 base::FilePath manifest_path = 2747 extension_path.Append(extensions::kManifestFilename); 2748 ASSERT_FALSE(base::PathExists(manifest_path)); 2749 2750 // Start with version 2.0. 2751 base::DictionaryValue manifest; 2752 manifest.SetString("version", "2.0"); 2753 manifest.SetString("name", "LOAD Downgrade Test"); 2754 manifest.SetInteger("manifest_version", 2); 2755 2756 JSONFileValueSerializer serializer(manifest_path); 2757 ASSERT_TRUE(serializer.Serialize(manifest)); 2758 2759 extensions::UnpackedInstaller::Create(service())->Load(extension_path); 2760 base::RunLoop().RunUntilIdle(); 2761 2762 EXPECT_EQ(0u, GetErrors().size()); 2763 ASSERT_EQ(1u, loaded_.size()); 2764 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location()); 2765 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 2766 EXPECT_EQ("2.0", loaded_[0]->VersionString()); 2767 2768 // Now set the version number to 1.0, reload the extensions and verify that 2769 // the downgrade was accepted. 2770 manifest.SetString("version", "1.0"); 2771 ASSERT_TRUE(serializer.Serialize(manifest)); 2772 2773 extensions::UnpackedInstaller::Create(service())->Load(extension_path); 2774 base::RunLoop().RunUntilIdle(); 2775 2776 EXPECT_EQ(0u, GetErrors().size()); 2777 ASSERT_EQ(1u, loaded_.size()); 2778 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location()); 2779 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 2780 EXPECT_EQ("1.0", loaded_[0]->VersionString()); 2781} 2782 2783#if !defined(OS_POSIX) || defined(OS_MACOSX) 2784// LOAD extensions with plugins require approval. 2785// Only run this on platforms that support NPAPI plugins. 2786TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) { 2787 base::FilePath extension_with_plugin_path = good1_path(); 2788 base::FilePath extension_no_plugin_path = good2_path(); 2789 2790 InitPluginService(); 2791 InitializeEmptyExtensionService(); 2792 InitializeProcessManager(); 2793 service()->set_show_extensions_prompts(true); 2794 2795 // Start by canceling any install prompts. 2796 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 2797 switches::kAppsGalleryInstallAutoConfirmForTests, 2798 "cancel"); 2799 2800 // The extension that has a plugin should not install. 2801 extensions::UnpackedInstaller::Create(service()) 2802 ->Load(extension_with_plugin_path); 2803 base::RunLoop().RunUntilIdle(); 2804 EXPECT_EQ(0u, GetErrors().size()); 2805 EXPECT_EQ(0u, loaded_.size()); 2806 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 2807 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 2808 2809 // But the extension with no plugin should since there's no prompt. 2810 ExtensionErrorReporter::GetInstance()->ClearErrors(); 2811 extensions::UnpackedInstaller::Create(service()) 2812 ->Load(extension_no_plugin_path); 2813 base::RunLoop().RunUntilIdle(); 2814 EXPECT_EQ(0u, GetErrors().size()); 2815 EXPECT_EQ(1u, loaded_.size()); 2816 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 2817 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 2818 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2)); 2819 2820 // The plugin extension should install if we accept the dialog. 2821 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 2822 switches::kAppsGalleryInstallAutoConfirmForTests, 2823 "accept"); 2824 2825 ExtensionErrorReporter::GetInstance()->ClearErrors(); 2826 extensions::UnpackedInstaller::Create(service()) 2827 ->Load(extension_with_plugin_path); 2828 base::RunLoop().RunUntilIdle(); 2829 EXPECT_EQ(0u, GetErrors().size()); 2830 EXPECT_EQ(2u, loaded_.size()); 2831 EXPECT_EQ(2u, registry()->enabled_extensions().size()); 2832 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 2833 EXPECT_TRUE(registry()->enabled_extensions().Contains(good1)); 2834 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2)); 2835 2836 // Make sure the granted permissions have been setup. 2837 scoped_refptr<PermissionSet> permissions( 2838 ExtensionPrefs::Get(profile())->GetGrantedPermissions(good1)); 2839 EXPECT_FALSE(permissions->IsEmpty()); 2840 EXPECT_TRUE(permissions->HasEffectiveFullAccess()); 2841 EXPECT_FALSE(permissions->apis().empty()); 2842 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin)); 2843 2844 // We should be able to reload the extension without getting another prompt. 2845 loaded_.clear(); 2846 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 2847 switches::kAppsGalleryInstallAutoConfirmForTests, 2848 "cancel"); 2849 2850 service()->ReloadExtension(good1); 2851 base::RunLoop().RunUntilIdle(); 2852 EXPECT_EQ(1u, loaded_.size()); 2853 EXPECT_EQ(2u, registry()->enabled_extensions().size()); 2854 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 2855} 2856#endif // !defined(OS_POSIX) || defined(OS_MACOSX) 2857 2858namespace { 2859 2860bool IsExtension(const Extension* extension) { 2861 return extension->GetType() == Manifest::TYPE_EXTENSION; 2862} 2863 2864#if defined(ENABLE_BLACKLIST_TESTS) 2865std::set<std::string> StringSet(const std::string& s) { 2866 std::set<std::string> set; 2867 set.insert(s); 2868 return set; 2869} 2870std::set<std::string> StringSet(const std::string& s1, const std::string& s2) { 2871 std::set<std::string> set = StringSet(s1); 2872 set.insert(s2); 2873 return set; 2874} 2875#endif // defined(ENABLE_BLACKLIST_TESTS) 2876 2877} // namespace 2878 2879// Test adding a pending extension. 2880TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) { 2881 InitializeEmptyExtensionService(); 2882 2883 const std::string kFakeId(all_zero); 2884 const GURL kFakeUpdateURL("http:://fake.update/url"); 2885 const bool kFakeInstallSilently(true); 2886 const bool kFakeRemoteInstall(false); 2887 const bool kFakeInstalledByCustodian(false); 2888 2889 EXPECT_TRUE( 2890 service()->pending_extension_manager()->AddFromSync( 2891 kFakeId, 2892 kFakeUpdateURL, 2893 &IsExtension, 2894 kFakeInstallSilently, 2895 kFakeRemoteInstall, 2896 kFakeInstalledByCustodian)); 2897 2898 const extensions::PendingExtensionInfo* pending_extension_info; 2899 ASSERT_TRUE((pending_extension_info = 2900 service()->pending_extension_manager()->GetById(kFakeId))); 2901 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url()); 2902 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_); 2903 EXPECT_EQ(kFakeInstallSilently, pending_extension_info->install_silently()); 2904 // Use 2905 // EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install()) 2906 // instead of 2907 // EXPECT_EQ(kFakeRemoteInstall, pending_extension_info->remote_install()) 2908 // as gcc 4.7 issues the following warning on EXPECT_EQ(false, x), which is 2909 // turned into an error with -Werror=conversion-null: 2910 // converting 'false' to pointer type for argument 1 of 2911 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)' 2912 // https://code.google.com/p/googletest/issues/detail?id=458 2913 EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install()); 2914} 2915 2916namespace { 2917const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; 2918const char kGoodUpdateURL[] = "http://good.update/url"; 2919const bool kGoodIsFromSync = true; 2920const bool kGoodInstallSilently = true; 2921const bool kGoodRemoteInstall = false; 2922const bool kGoodInstalledByCustodian = false; 2923} // namespace 2924 2925// Test updating a pending extension. 2926TEST_F(ExtensionServiceTest, UpdatePendingExtension) { 2927 InitializeEmptyExtensionService(); 2928 EXPECT_TRUE( 2929 service()->pending_extension_manager()->AddFromSync( 2930 kGoodId, 2931 GURL(kGoodUpdateURL), 2932 &IsExtension, 2933 kGoodInstallSilently, 2934 kGoodRemoteInstall, 2935 kGoodInstalledByCustodian)); 2936 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId)); 2937 2938 base::FilePath path = data_dir().AppendASCII("good.crx"); 2939 UpdateExtension(kGoodId, path, ENABLED); 2940 2941 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId)); 2942 2943 const Extension* extension = service()->GetExtensionById(kGoodId, true); 2944 ASSERT_TRUE(extension); 2945} 2946 2947namespace { 2948 2949bool IsTheme(const Extension* extension) { 2950 return extension->is_theme(); 2951} 2952 2953} // namespace 2954 2955// Test updating a pending theme. 2956// Disabled due to ASAN failure. http://crbug.com/108320 2957TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) { 2958 InitializeEmptyExtensionService(); 2959 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync( 2960 theme_crx, GURL(), &IsTheme, false, false, false)); 2961 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx)); 2962 2963 base::FilePath path = data_dir().AppendASCII("theme.crx"); 2964 UpdateExtension(theme_crx, path, ENABLED); 2965 2966 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx)); 2967 2968 const Extension* extension = service()->GetExtensionById(theme_crx, true); 2969 ASSERT_TRUE(extension); 2970 2971 EXPECT_FALSE( 2972 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id())); 2973 EXPECT_TRUE(service()->IsExtensionEnabled(theme_crx)); 2974} 2975 2976#if defined(OS_CHROMEOS) 2977// Always fails on ChromeOS: http://crbug.com/79737 2978#define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx 2979#else 2980#define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx 2981#endif 2982// Test updating a pending CRX as if the source is an external extension 2983// with an update URL. In this case we don't know if the CRX is a theme 2984// or not. 2985TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) { 2986 InitializeEmptyExtensionService(); 2987 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl( 2988 theme_crx, 2989 std::string(), 2990 GURL(), 2991 Manifest::EXTERNAL_PREF_DOWNLOAD, 2992 Extension::NO_FLAGS, 2993 false)); 2994 2995 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx)); 2996 2997 base::FilePath path = data_dir().AppendASCII("theme.crx"); 2998 UpdateExtension(theme_crx, path, ENABLED); 2999 3000 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx)); 3001 3002 const Extension* extension = service()->GetExtensionById(theme_crx, true); 3003 ASSERT_TRUE(extension); 3004 3005 EXPECT_FALSE( 3006 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id())); 3007 EXPECT_TRUE(service()->IsExtensionEnabled(extension->id())); 3008 EXPECT_FALSE( 3009 extensions::util::IsIncognitoEnabled(extension->id(), profile())); 3010} 3011 3012// Test updating a pending CRX as if the source is an external extension 3013// with an update URL. The external update should overwrite a sync update, 3014// but a sync update should not overwrite a non-sync update. 3015TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) { 3016 InitializeEmptyExtensionService(); 3017 3018 // Add a crx to be installed from the update mechanism. 3019 EXPECT_TRUE( 3020 service()->pending_extension_manager()->AddFromSync( 3021 kGoodId, 3022 GURL(kGoodUpdateURL), 3023 &IsExtension, 3024 kGoodInstallSilently, 3025 kGoodRemoteInstall, 3026 kGoodInstalledByCustodian)); 3027 3028 // Check that there is a pending crx, with is_from_sync set to true. 3029 const extensions::PendingExtensionInfo* pending_extension_info; 3030 ASSERT_TRUE((pending_extension_info = 3031 service()->pending_extension_manager()->GetById(kGoodId))); 3032 EXPECT_TRUE(pending_extension_info->is_from_sync()); 3033 3034 // Add a crx to be updated, with the same ID, from a non-sync source. 3035 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl( 3036 kGoodId, 3037 std::string(), 3038 GURL(kGoodUpdateURL), 3039 Manifest::EXTERNAL_PREF_DOWNLOAD, 3040 Extension::NO_FLAGS, 3041 false)); 3042 3043 // Check that there is a pending crx, with is_from_sync set to false. 3044 ASSERT_TRUE((pending_extension_info = 3045 service()->pending_extension_manager()->GetById(kGoodId))); 3046 EXPECT_FALSE(pending_extension_info->is_from_sync()); 3047 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, 3048 pending_extension_info->install_source()); 3049 3050 // Add a crx to be installed from the update mechanism. 3051 EXPECT_FALSE( 3052 service()->pending_extension_manager()->AddFromSync( 3053 kGoodId, 3054 GURL(kGoodUpdateURL), 3055 &IsExtension, 3056 kGoodInstallSilently, 3057 kGoodRemoteInstall, 3058 kGoodInstalledByCustodian)); 3059 3060 // Check that the external, non-sync update was not overridden. 3061 ASSERT_TRUE((pending_extension_info = 3062 service()->pending_extension_manager()->GetById(kGoodId))); 3063 EXPECT_FALSE(pending_extension_info->is_from_sync()); 3064 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, 3065 pending_extension_info->install_source()); 3066} 3067 3068// Updating a theme should fail if the updater is explicitly told that 3069// the CRX is not a theme. 3070TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) { 3071 InitializeEmptyExtensionService(); 3072 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync( 3073 theme_crx, GURL(), &IsExtension, true, false, false)); 3074 3075 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx)); 3076 3077 base::FilePath path = data_dir().AppendASCII("theme.crx"); 3078 UpdateExtension(theme_crx, path, FAILED_SILENTLY); 3079 3080 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx)); 3081 3082 const Extension* extension = service()->GetExtensionById(theme_crx, true); 3083 ASSERT_FALSE(extension); 3084} 3085 3086// TODO(akalin): Test updating a pending extension non-silently once 3087// we can mock out ExtensionInstallUI and inject our version into 3088// UpdateExtension(). 3089 3090// Test updating a pending extension which fails the should-install test. 3091TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) { 3092 InitializeEmptyExtensionService(); 3093 // Add pending extension with a flipped is_theme. 3094 EXPECT_TRUE( 3095 service()->pending_extension_manager()->AddFromSync( 3096 kGoodId, 3097 GURL(kGoodUpdateURL), 3098 &IsTheme, 3099 kGoodInstallSilently, 3100 kGoodRemoteInstall, 3101 kGoodInstalledByCustodian)); 3102 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId)); 3103 3104 base::FilePath path = data_dir().AppendASCII("good.crx"); 3105 UpdateExtension(kGoodId, path, UPDATED); 3106 3107 // TODO(akalin): Figure out how to check that the extensions 3108 // directory is cleaned up properly in OnExtensionInstalled(). 3109 3110 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId)); 3111} 3112 3113// TODO(akalin): Figure out how to test that installs of pending 3114// unsyncable extensions are blocked. 3115 3116// Test updating a pending extension for one that is not pending. 3117TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) { 3118 InitializeEmptyExtensionService(); 3119 3120 base::FilePath path = data_dir().AppendASCII("good.crx"); 3121 UpdateExtension(kGoodId, path, UPDATED); 3122 3123 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId)); 3124} 3125 3126// Test updating a pending extension for one that is already 3127// installed. 3128TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) { 3129 InitializeEmptyExtensionService(); 3130 3131 base::FilePath path = data_dir().AppendASCII("good.crx"); 3132 const Extension* good = InstallCRX(path, INSTALL_NEW); 3133 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 3134 3135 EXPECT_FALSE(good->is_theme()); 3136 3137 // Use AddExtensionImpl() as AddFrom*() would balk. 3138 service()->pending_extension_manager()->AddExtensionImpl( 3139 good->id(), 3140 std::string(), 3141 extensions::ManifestURL::GetUpdateURL(good), 3142 Version(), 3143 &IsExtension, 3144 kGoodIsFromSync, 3145 kGoodInstallSilently, 3146 Manifest::INTERNAL, 3147 Extension::NO_FLAGS, 3148 false, 3149 kGoodRemoteInstall); 3150 UpdateExtension(good->id(), path, ENABLED); 3151 3152 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId)); 3153} 3154 3155#if defined(ENABLE_BLACKLIST_TESTS) 3156// Tests blacklisting then unblacklisting extensions after the service has been 3157// initialized. 3158TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) { 3159 extensions::TestBlacklist test_blacklist; 3160 // A profile with 3 extensions installed: good0, good1, and good2. 3161 InitializeGoodInstalledExtensionService(); 3162 test_blacklist.Attach(service()->blacklist_); 3163 service()->Init(); 3164 3165 const extensions::ExtensionSet& enabled_extensions = 3166 registry()->enabled_extensions(); 3167 const extensions::ExtensionSet& blacklisted_extensions = 3168 registry()->blacklisted_extensions(); 3169 3170 EXPECT_TRUE(enabled_extensions.Contains(good0) && 3171 !blacklisted_extensions.Contains(good0)); 3172 EXPECT_TRUE(enabled_extensions.Contains(good1) && 3173 !blacklisted_extensions.Contains(good1)); 3174 EXPECT_TRUE(enabled_extensions.Contains(good2) && 3175 !blacklisted_extensions.Contains(good2)); 3176 3177 EXPECT_FALSE(IsPrefExist(good0, "blacklist")); 3178 EXPECT_FALSE(IsPrefExist(good1, "blacklist")); 3179 EXPECT_FALSE(IsPrefExist(good2, "blacklist")); 3180 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist")); 3181 3182 // Blacklist good0 and good1 (and an invalid extension ID). 3183 test_blacklist.SetBlacklistState( 3184 good0, extensions::BLACKLISTED_MALWARE, true); 3185 test_blacklist.SetBlacklistState( 3186 good1, extensions::BLACKLISTED_MALWARE, true); 3187 test_blacklist.SetBlacklistState( 3188 "invalid_id", extensions::BLACKLISTED_MALWARE, true); 3189 base::RunLoop().RunUntilIdle(); 3190 3191 EXPECT_TRUE(!enabled_extensions.Contains(good0) && 3192 blacklisted_extensions.Contains(good0)); 3193 EXPECT_TRUE(!enabled_extensions.Contains(good1) && 3194 blacklisted_extensions.Contains(good1)); 3195 EXPECT_TRUE(enabled_extensions.Contains(good2) && 3196 !blacklisted_extensions.Contains(good2)); 3197 3198 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true)); 3199 EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true)); 3200 EXPECT_FALSE(IsPrefExist(good2, "blacklist")); 3201 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist")); 3202 3203 // Un-blacklist good1 and blacklist good2. 3204 test_blacklist.Clear(false); 3205 test_blacklist.SetBlacklistState( 3206 good0, extensions::BLACKLISTED_MALWARE, true); 3207 test_blacklist.SetBlacklistState( 3208 good2, extensions::BLACKLISTED_MALWARE, true); 3209 test_blacklist.SetBlacklistState( 3210 "invalid_id", extensions::BLACKLISTED_MALWARE, true); 3211 base::RunLoop().RunUntilIdle(); 3212 3213 EXPECT_TRUE(!enabled_extensions.Contains(good0) && 3214 blacklisted_extensions.Contains(good0)); 3215 EXPECT_TRUE(enabled_extensions.Contains(good1) && 3216 !blacklisted_extensions.Contains(good1)); 3217 EXPECT_TRUE(!enabled_extensions.Contains(good2) && 3218 blacklisted_extensions.Contains(good2)); 3219 3220 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true)); 3221 EXPECT_FALSE(IsPrefExist(good1, "blacklist")); 3222 EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true)); 3223 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist")); 3224} 3225#endif // defined(ENABLE_BLACKLIST_TESTS) 3226 3227#if defined(ENABLE_BLACKLIST_TESTS) 3228// Tests trying to install a blacklisted extension. 3229TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) { 3230 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db( 3231 new FakeSafeBrowsingDatabaseManager(true)); 3232 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db); 3233 3234 InitializeEmptyExtensionService(); 3235 service()->Init(); 3236 3237 // After blacklisting good_crx, we cannot install it. 3238 blacklist_db->SetUnsafe(good_crx).NotifyUpdate(); 3239 base::RunLoop().RunUntilIdle(); 3240 3241 base::FilePath path = data_dir().AppendASCII("good.crx"); 3242 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't 3243 // decide to install this silently. Somebody should fix these tests, all 3244 // 6,000 lines of them. Hah! 3245 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT); 3246 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3247} 3248#endif // defined(ENABLE_BLACKLIST_TESTS) 3249 3250#if defined(ENABLE_BLACKLIST_TESTS) 3251// Unload blacklisted extension on policy change. 3252TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) { 3253 extensions::TestBlacklist test_blacklist; 3254 3255 // A profile with no extensions installed. 3256 InitializeEmptyExtensionService(); 3257 test_blacklist.Attach(service()->blacklist_); 3258 3259 base::FilePath path = data_dir().AppendASCII("good.crx"); 3260 3261 const Extension* good = InstallCRX(path, INSTALL_NEW); 3262 EXPECT_EQ(good_crx, good->id()); 3263 UpdateExtension(good_crx, path, FAILED_SILENTLY); 3264 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3265 3266 base::ListValue whitelist; 3267 PrefService* prefs = ExtensionPrefs::Get(profile())->pref_service(); 3268 whitelist.Append(new base::StringValue(good_crx)); 3269 prefs->Set(extensions::pref_names::kInstallAllowList, whitelist); 3270 3271 test_blacklist.SetBlacklistState( 3272 good_crx, extensions::BLACKLISTED_MALWARE, true); 3273 base::RunLoop().RunUntilIdle(); 3274 3275 // The good_crx is blacklisted and the whitelist doesn't negate it. 3276 ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true)); 3277 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3278} 3279#endif // defined(ENABLE_BLACKLIST_TESTS) 3280 3281#if defined(ENABLE_BLACKLIST_TESTS) 3282// Tests that a blacklisted extension is eventually unloaded on startup, if it 3283// wasn't already. 3284TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) { 3285 extensions::TestBlacklist test_blacklist; 3286 3287 // A profile with 3 extensions installed: good0, good1, and good2. 3288 InitializeGoodInstalledExtensionService(); 3289 test_blacklist.Attach(service()->blacklist_); 3290 3291 // Blacklist good1 before the service initializes. 3292 test_blacklist.SetBlacklistState( 3293 good1, extensions::BLACKLISTED_MALWARE, false); 3294 3295 // Load extensions. 3296 service()->Init(); 3297 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet 3298 3299 base::RunLoop().RunUntilIdle(); 3300 3301 ASSERT_EQ(1u, registry()->blacklisted_extensions().size()); 3302 ASSERT_EQ(2u, registry()->enabled_extensions().size()); 3303 3304 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0)); 3305 ASSERT_TRUE(registry()->blacklisted_extensions().Contains(good1)); 3306 ASSERT_TRUE(registry()->enabled_extensions().Contains(good2)); 3307} 3308#endif // defined(ENABLE_BLACKLIST_TESTS) 3309 3310#if defined(ENABLE_BLACKLIST_TESTS) 3311// Tests extensions blacklisted in prefs on startup; one still blacklisted by 3312// safe browsing, the other not. The not-blacklisted one should recover. 3313TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) { 3314 extensions::TestBlacklist test_blacklist; 3315 3316 InitializeGoodInstalledExtensionService(); 3317 test_blacklist.Attach(service()->blacklist_); 3318 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good0, true); 3319 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good1, true); 3320 3321 test_blacklist.SetBlacklistState( 3322 good1, extensions::BLACKLISTED_MALWARE, false); 3323 3324 // Extension service hasn't loaded yet, but IsExtensionEnabled reads out of 3325 // prefs. Ensure it takes into account the blacklist state (crbug.com/373842). 3326 EXPECT_FALSE(service()->IsExtensionEnabled(good0)); 3327 EXPECT_FALSE(service()->IsExtensionEnabled(good1)); 3328 EXPECT_TRUE(service()->IsExtensionEnabled(good2)); 3329 3330 service()->Init(); 3331 3332 EXPECT_EQ(2u, registry()->blacklisted_extensions().size()); 3333 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3334 3335 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good0)); 3336 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1)); 3337 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2)); 3338 3339 // Give time for the blacklist to update. 3340 base::RunLoop().RunUntilIdle(); 3341 3342 EXPECT_EQ(1u, registry()->blacklisted_extensions().size()); 3343 EXPECT_EQ(2u, registry()->enabled_extensions().size()); 3344 3345 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0)); 3346 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1)); 3347 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2)); 3348} 3349#endif // defined(ENABLE_BLACKLIST_TESTS) 3350 3351#if defined(ENABLE_BLACKLIST_TESTS) 3352// Extension is added to blacklist with BLACKLISTED_POTENTIALLY_UNWANTED state 3353// after it is installed. It is then successfully re-enabled by the user. 3354TEST_F(ExtensionServiceTest, GreylistedExtensionDisabled) { 3355 extensions::TestBlacklist test_blacklist; 3356 // A profile with 3 extensions installed: good0, good1, and good2. 3357 InitializeGoodInstalledExtensionService(); 3358 test_blacklist.Attach(service()->blacklist_); 3359 service()->Init(); 3360 3361 const extensions::ExtensionSet& enabled_extensions = 3362 registry()->enabled_extensions(); 3363 const extensions::ExtensionSet& disabled_extensions = 3364 registry()->disabled_extensions(); 3365 3366 EXPECT_TRUE(enabled_extensions.Contains(good0)); 3367 EXPECT_TRUE(enabled_extensions.Contains(good1)); 3368 EXPECT_TRUE(enabled_extensions.Contains(good2)); 3369 3370 // Blacklist good0 and good1 (and an invalid extension ID). 3371 test_blacklist.SetBlacklistState( 3372 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true); 3373 test_blacklist.SetBlacklistState( 3374 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true); 3375 test_blacklist.SetBlacklistState( 3376 "invalid_id", extensions::BLACKLISTED_MALWARE, true); 3377 base::RunLoop().RunUntilIdle(); 3378 3379 EXPECT_FALSE(enabled_extensions.Contains(good0)); 3380 EXPECT_TRUE(disabled_extensions.Contains(good0)); 3381 EXPECT_FALSE(enabled_extensions.Contains(good1)); 3382 EXPECT_TRUE(disabled_extensions.Contains(good1)); 3383 EXPECT_TRUE(enabled_extensions.Contains(good2)); 3384 EXPECT_FALSE(disabled_extensions.Contains(good2)); 3385 3386 ValidateIntegerPref( 3387 good0, "blacklist_state", extensions::BLACKLISTED_CWS_POLICY_VIOLATION); 3388 ValidateIntegerPref( 3389 good1, "blacklist_state", extensions::BLACKLISTED_POTENTIALLY_UNWANTED); 3390 3391 // Now user enables good0. 3392 service()->EnableExtension(good0); 3393 3394 EXPECT_TRUE(enabled_extensions.Contains(good0)); 3395 EXPECT_FALSE(disabled_extensions.Contains(good0)); 3396 EXPECT_FALSE(enabled_extensions.Contains(good1)); 3397 EXPECT_TRUE(disabled_extensions.Contains(good1)); 3398 3399 // Remove extensions from blacklist. 3400 test_blacklist.SetBlacklistState( 3401 good0, extensions::NOT_BLACKLISTED, true); 3402 test_blacklist.SetBlacklistState( 3403 good1, extensions::NOT_BLACKLISTED, true); 3404 base::RunLoop().RunUntilIdle(); 3405 3406 // All extensions are enabled. 3407 EXPECT_TRUE(enabled_extensions.Contains(good0)); 3408 EXPECT_FALSE(disabled_extensions.Contains(good0)); 3409 EXPECT_TRUE(enabled_extensions.Contains(good1)); 3410 EXPECT_FALSE(disabled_extensions.Contains(good1)); 3411 EXPECT_TRUE(enabled_extensions.Contains(good2)); 3412 EXPECT_FALSE(disabled_extensions.Contains(good2)); 3413} 3414#endif // defined(ENABLE_BLACKLIST_TESTS) 3415 3416#if defined(ENABLE_BLACKLIST_TESTS) 3417// When extension is removed from greylist, do not re-enable it if it is 3418// disabled by user. 3419TEST_F(ExtensionServiceTest, GreylistDontEnableManuallyDisabled) { 3420 extensions::TestBlacklist test_blacklist; 3421 // A profile with 3 extensions installed: good0, good1, and good2. 3422 InitializeGoodInstalledExtensionService(); 3423 test_blacklist.Attach(service()->blacklist_); 3424 service()->Init(); 3425 3426 const extensions::ExtensionSet& enabled_extensions = 3427 registry()->enabled_extensions(); 3428 const extensions::ExtensionSet& disabled_extensions = 3429 registry()->disabled_extensions(); 3430 3431 // Manually disable. 3432 service()->DisableExtension(good0, 3433 extensions::Extension::DISABLE_USER_ACTION); 3434 3435 test_blacklist.SetBlacklistState( 3436 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true); 3437 test_blacklist.SetBlacklistState( 3438 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true); 3439 test_blacklist.SetBlacklistState( 3440 good2, extensions::BLACKLISTED_SECURITY_VULNERABILITY, true); 3441 base::RunLoop().RunUntilIdle(); 3442 3443 // All extensions disabled. 3444 EXPECT_FALSE(enabled_extensions.Contains(good0)); 3445 EXPECT_TRUE(disabled_extensions.Contains(good0)); 3446 EXPECT_FALSE(enabled_extensions.Contains(good1)); 3447 EXPECT_TRUE(disabled_extensions.Contains(good1)); 3448 EXPECT_FALSE(enabled_extensions.Contains(good2)); 3449 EXPECT_TRUE(disabled_extensions.Contains(good2)); 3450 3451 // Greylisted extension can be enabled. 3452 service()->EnableExtension(good1); 3453 EXPECT_TRUE(enabled_extensions.Contains(good1)); 3454 EXPECT_FALSE(disabled_extensions.Contains(good1)); 3455 3456 // good1 is now manually disabled. 3457 service()->DisableExtension(good1, 3458 extensions::Extension::DISABLE_USER_ACTION); 3459 EXPECT_FALSE(enabled_extensions.Contains(good1)); 3460 EXPECT_TRUE(disabled_extensions.Contains(good1)); 3461 3462 // Remove extensions from blacklist. 3463 test_blacklist.SetBlacklistState( 3464 good0, extensions::NOT_BLACKLISTED, true); 3465 test_blacklist.SetBlacklistState( 3466 good1, extensions::NOT_BLACKLISTED, true); 3467 test_blacklist.SetBlacklistState( 3468 good2, extensions::NOT_BLACKLISTED, true); 3469 base::RunLoop().RunUntilIdle(); 3470 3471 // good0 and good1 remain disabled. 3472 EXPECT_FALSE(enabled_extensions.Contains(good0)); 3473 EXPECT_TRUE(disabled_extensions.Contains(good0)); 3474 EXPECT_FALSE(enabled_extensions.Contains(good1)); 3475 EXPECT_TRUE(disabled_extensions.Contains(good1)); 3476 EXPECT_TRUE(enabled_extensions.Contains(good2)); 3477 EXPECT_FALSE(disabled_extensions.Contains(good2)); 3478} 3479#endif // defined(ENABLE_BLACKLIST_TESTS) 3480 3481#if defined(ENABLE_BLACKLIST_TESTS) 3482// Blacklisted extension with unknown state are not enabled/disabled. 3483TEST_F(ExtensionServiceTest, GreylistUnknownDontChange) { 3484 extensions::TestBlacklist test_blacklist; 3485 // A profile with 3 extensions installed: good0, good1, and good2. 3486 InitializeGoodInstalledExtensionService(); 3487 test_blacklist.Attach(service()->blacklist_); 3488 service()->Init(); 3489 3490 const extensions::ExtensionSet& enabled_extensions = 3491 registry()->enabled_extensions(); 3492 const extensions::ExtensionSet& disabled_extensions = 3493 registry()->disabled_extensions(); 3494 3495 test_blacklist.SetBlacklistState( 3496 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true); 3497 test_blacklist.SetBlacklistState( 3498 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true); 3499 base::RunLoop().RunUntilIdle(); 3500 3501 EXPECT_FALSE(enabled_extensions.Contains(good0)); 3502 EXPECT_TRUE(disabled_extensions.Contains(good0)); 3503 EXPECT_FALSE(enabled_extensions.Contains(good1)); 3504 EXPECT_TRUE(disabled_extensions.Contains(good1)); 3505 EXPECT_TRUE(enabled_extensions.Contains(good2)); 3506 EXPECT_FALSE(disabled_extensions.Contains(good2)); 3507 3508 test_blacklist.SetBlacklistState( 3509 good0, extensions::NOT_BLACKLISTED, true); 3510 test_blacklist.SetBlacklistState( 3511 good1, extensions::BLACKLISTED_UNKNOWN, true); 3512 test_blacklist.SetBlacklistState( 3513 good2, extensions::BLACKLISTED_UNKNOWN, true); 3514 base::RunLoop().RunUntilIdle(); 3515 3516 // good0 re-enabled, other remain as they were. 3517 EXPECT_TRUE(enabled_extensions.Contains(good0)); 3518 EXPECT_FALSE(disabled_extensions.Contains(good0)); 3519 EXPECT_FALSE(enabled_extensions.Contains(good1)); 3520 EXPECT_TRUE(disabled_extensions.Contains(good1)); 3521 EXPECT_TRUE(enabled_extensions.Contains(good2)); 3522 EXPECT_FALSE(disabled_extensions.Contains(good2)); 3523} 3524 3525// Tests that blacklisted extensions cannot be reloaded, both those loaded 3526// before and after extension service startup. 3527TEST_F(ExtensionServiceTest, ReloadBlacklistedExtension) { 3528 extensions::TestBlacklist test_blacklist; 3529 3530 InitializeGoodInstalledExtensionService(); 3531 test_blacklist.Attach(service()->blacklist_); 3532 3533 test_blacklist.SetBlacklistState( 3534 good1, extensions::BLACKLISTED_MALWARE, false); 3535 service()->Init(); 3536 test_blacklist.SetBlacklistState( 3537 good2, extensions::BLACKLISTED_MALWARE, false); 3538 base::RunLoop().RunUntilIdle(); 3539 3540 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs()); 3541 EXPECT_EQ(StringSet(good1, good2), 3542 registry()->blacklisted_extensions().GetIDs()); 3543 3544 service()->ReloadExtension(good1); 3545 service()->ReloadExtension(good2); 3546 base::RunLoop().RunUntilIdle(); 3547 3548 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs()); 3549 EXPECT_EQ(StringSet(good1, good2), 3550 registry()->blacklisted_extensions().GetIDs()); 3551} 3552 3553#endif // defined(ENABLE_BLACKLIST_TESTS) 3554 3555// Will not install extension blacklisted by policy. 3556TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) { 3557 InitializeEmptyExtensionService(); 3558 3559 // Blacklist everything. 3560 { 3561 ListPrefUpdate update(profile()->GetPrefs(), 3562 extensions::pref_names::kInstallDenyList); 3563 base::ListValue* blacklist = update.Get(); 3564 blacklist->Append(new base::StringValue("*")); 3565 } 3566 3567 // Blacklist prevents us from installing good_crx. 3568 base::FilePath path = data_dir().AppendASCII("good.crx"); 3569 InstallCRX(path, INSTALL_FAILED); 3570 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3571 3572 // Now whitelist this particular extension. 3573 { 3574 ListPrefUpdate update(profile()->GetPrefs(), 3575 extensions::pref_names::kInstallAllowList); 3576 base::ListValue* whitelist = update.Get(); 3577 whitelist->Append(new base::StringValue(good_crx)); 3578 } 3579 3580 // Ensure we can now install good_crx. 3581 InstallCRX(path, INSTALL_NEW); 3582 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3583} 3584 3585// Extension blacklisted by policy get unloaded after installing. 3586TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) { 3587 InitializeEmptyExtensionService(); 3588 3589 // Install good_crx. 3590 base::FilePath path = data_dir().AppendASCII("good.crx"); 3591 InstallCRX(path, INSTALL_NEW); 3592 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3593 3594 { // Scope for pref update notification. 3595 PrefService* prefs = profile()->GetPrefs(); 3596 ListPrefUpdate update(prefs, extensions::pref_names::kInstallDenyList); 3597 base::ListValue* blacklist = update.Get(); 3598 ASSERT_TRUE(blacklist != NULL); 3599 3600 // Blacklist this extension. 3601 blacklist->Append(new base::StringValue(good_crx)); 3602 } 3603 3604 // Extension should not be running now. 3605 base::RunLoop().RunUntilIdle(); 3606 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3607} 3608 3609// Tests that component extensions are not blacklisted by policy. 3610TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) { 3611 InitializeEmptyExtensionService(); 3612 3613 // Blacklist everything. 3614 { 3615 ListPrefUpdate update(profile()->GetPrefs(), 3616 extensions::pref_names::kInstallDenyList); 3617 base::ListValue* blacklist = update.Get(); 3618 blacklist->Append(new base::StringValue("*")); 3619 } 3620 3621 // Install a component extension. 3622 base::FilePath path = data_dir() 3623 .AppendASCII("good") 3624 .AppendASCII("Extensions") 3625 .AppendASCII(good0) 3626 .AppendASCII("1.0.0.0"); 3627 std::string manifest; 3628 ASSERT_TRUE(base::ReadFileToString( 3629 path.Append(extensions::kManifestFilename), &manifest)); 3630 service()->component_loader()->Add(manifest, path); 3631 service()->Init(); 3632 3633 // Extension should be installed despite blacklist. 3634 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 3635 EXPECT_TRUE(service()->GetExtensionById(good0, false)); 3636 3637 // Poke external providers and make sure the extension is still present. 3638 service()->CheckForExternalUpdates(); 3639 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 3640 EXPECT_TRUE(service()->GetExtensionById(good0, false)); 3641 3642 // Extension should not be uninstalled on blacklist changes. 3643 { 3644 ListPrefUpdate update(profile()->GetPrefs(), 3645 extensions::pref_names::kInstallDenyList); 3646 base::ListValue* blacklist = update.Get(); 3647 blacklist->Append(new base::StringValue(good0)); 3648 } 3649 base::RunLoop().RunUntilIdle(); 3650 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 3651 EXPECT_TRUE(service()->GetExtensionById(good0, false)); 3652} 3653 3654// Tests that policy-installed extensions are not blacklisted by policy. 3655TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) { 3656 InitializeEmptyExtensionService(); 3657 3658 { 3659 // Blacklist everything. 3660 ListPrefUpdate blacklist_update(profile()->GetPrefs(), 3661 extensions::pref_names::kInstallDenyList); 3662 base::ListValue* blacklist = blacklist_update.Get(); 3663 blacklist->AppendString("*"); 3664 3665 // Mark good.crx for force-installation. 3666 DictionaryPrefUpdate forcelist_update( 3667 profile()->GetPrefs(), extensions::pref_names::kInstallForceList); 3668 extensions::ExternalPolicyLoader::AddExtension( 3669 forcelist_update.Get(), good_crx, "http://example.com/update_url"); 3670 } 3671 3672 // Have policy force-install an extension. 3673 MockExtensionProvider* provider = 3674 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD); 3675 AddMockExternalProvider(provider); 3676 provider->UpdateOrAddExtension( 3677 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx")); 3678 3679 // Reloading extensions should find our externally registered extension 3680 // and install it. 3681 content::WindowedNotificationObserver observer( 3682 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 3683 content::NotificationService::AllSources()); 3684 service()->CheckForExternalUpdates(); 3685 observer.Wait(); 3686 3687 // Extension should be installed despite blacklist. 3688 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 3689 EXPECT_TRUE(service()->GetExtensionById(good_crx, false)); 3690 3691 // Blacklist update should not uninstall the extension. 3692 { 3693 ListPrefUpdate update(profile()->GetPrefs(), 3694 extensions::pref_names::kInstallDenyList); 3695 base::ListValue* blacklist = update.Get(); 3696 blacklist->Append(new base::StringValue(good0)); 3697 } 3698 base::RunLoop().RunUntilIdle(); 3699 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 3700 EXPECT_TRUE(service()->GetExtensionById(good_crx, false)); 3701} 3702 3703// Tests that extensions cannot be installed if the policy provider prohibits 3704// it. This functionality is implemented in CrxInstaller::ConfirmInstall(). 3705TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) { 3706 InitializeEmptyExtensionService(); 3707 3708 GetManagementPolicy()->UnregisterAllProviders(); 3709 extensions::TestManagementPolicyProvider provider_( 3710 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD); 3711 GetManagementPolicy()->RegisterProvider(&provider_); 3712 3713 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_FAILED); 3714 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3715} 3716 3717// Tests that extensions cannot be loaded from prefs if the policy provider 3718// prohibits it. This functionality is implemented in InstalledLoader::Load(). 3719TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) { 3720 InitializeEmptyExtensionService(); 3721 3722 // Create a fake extension to be loaded as though it were read from prefs. 3723 base::FilePath path = 3724 data_dir().AppendASCII("management").AppendASCII("simple_extension"); 3725 base::DictionaryValue manifest; 3726 manifest.SetString(keys::kName, "simple_extension"); 3727 manifest.SetString(keys::kVersion, "1"); 3728 // UNPACKED is for extensions loaded from a directory. We use it here, even 3729 // though we're testing loading from prefs, so that we don't need to provide 3730 // an extension key. 3731 extensions::ExtensionInfo extension_info( 3732 &manifest, std::string(), path, Manifest::UNPACKED); 3733 3734 // Ensure we can load it with no management policy in place. 3735 GetManagementPolicy()->UnregisterAllProviders(); 3736 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3737 extensions::InstalledLoader(service()).Load(extension_info, false); 3738 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3739 3740 const Extension* extension = 3741 (registry()->enabled_extensions().begin())->get(); 3742 EXPECT_TRUE(service()->UninstallExtension( 3743 extension->id(), ExtensionService::UNINSTALL_REASON_FOR_TESTING, NULL)); 3744 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3745 3746 // Ensure we cannot load it if management policy prohibits installation. 3747 extensions::TestManagementPolicyProvider provider_( 3748 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD); 3749 GetManagementPolicy()->RegisterProvider(&provider_); 3750 3751 extensions::InstalledLoader(service()).Load(extension_info, false); 3752 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3753} 3754 3755// Tests disabling an extension when prohibited by the ManagementPolicy. 3756TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) { 3757 InitializeEmptyExtensionService(); 3758 3759 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 3760 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3761 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 3762 3763 GetManagementPolicy()->UnregisterAllProviders(); 3764 extensions::TestManagementPolicyProvider provider( 3765 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS); 3766 GetManagementPolicy()->RegisterProvider(&provider); 3767 3768 // Attempt to disable it. 3769 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION); 3770 3771 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3772 EXPECT_TRUE(service()->GetExtensionById(good_crx, false)); 3773 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 3774} 3775 3776// Tests uninstalling an extension when prohibited by the ManagementPolicy. 3777TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) { 3778 InitializeEmptyExtensionService(); 3779 3780 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 3781 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3782 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 3783 3784 GetManagementPolicy()->UnregisterAllProviders(); 3785 extensions::TestManagementPolicyProvider provider( 3786 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS); 3787 GetManagementPolicy()->RegisterProvider(&provider); 3788 3789 // Attempt to uninstall it. 3790 EXPECT_FALSE(service()->UninstallExtension( 3791 good_crx, ExtensionService::UNINSTALL_REASON_FOR_TESTING, NULL)); 3792 3793 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3794 EXPECT_TRUE(service()->GetExtensionById(good_crx, false)); 3795} 3796 3797// Tests that previously installed extensions that are now prohibited from 3798// being installed are removed. 3799TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) { 3800 InitializeEmptyExtensionService(); 3801 3802 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 3803 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW); 3804 EXPECT_EQ(2u, registry()->enabled_extensions().size()); 3805 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 3806 3807 GetManagementPolicy()->UnregisterAllProviders(); 3808 extensions::TestManagementPolicyProvider provider( 3809 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD); 3810 GetManagementPolicy()->RegisterProvider(&provider); 3811 3812 // Run the policy check. 3813 service()->CheckManagementPolicy(); 3814 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3815 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 3816} 3817 3818// Tests that previously disabled extensions that are now required to be 3819// enabled are re-enabled on reinstall. 3820TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) { 3821 InitializeEmptyExtensionService(); 3822 3823 // Install, then disable, an extension. 3824 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 3825 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3826 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION); 3827 EXPECT_EQ(1u, registry()->disabled_extensions().size()); 3828 3829 // Register an ExtensionMnagementPolicy that requires the extension to remain 3830 // enabled. 3831 GetManagementPolicy()->UnregisterAllProviders(); 3832 extensions::TestManagementPolicyProvider provider( 3833 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED); 3834 GetManagementPolicy()->RegisterProvider(&provider); 3835 3836 // Reinstall the extension. 3837 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_UPDATED); 3838 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3839 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 3840} 3841 3842// Flaky on windows; http://crbug.com/309833 3843#if defined(OS_WIN) 3844#define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement 3845#else 3846#define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement 3847#endif 3848TEST_F(ExtensionServiceTest, MAYBE_ExternalExtensionAutoAcknowledgement) { 3849 InitializeEmptyExtensionService(); 3850 service()->set_extensions_enabled(true); 3851 3852 { 3853 // Register and install an external extension. 3854 MockExtensionProvider* provider = 3855 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF); 3856 AddMockExternalProvider(provider); 3857 provider->UpdateOrAddExtension( 3858 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx")); 3859 } 3860 { 3861 // Have policy force-install an extension. 3862 MockExtensionProvider* provider = new MockExtensionProvider( 3863 service(), Manifest::EXTERNAL_POLICY_DOWNLOAD); 3864 AddMockExternalProvider(provider); 3865 provider->UpdateOrAddExtension( 3866 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx")); 3867 } 3868 3869 // Providers are set up. Let them run. 3870 int count = 2; 3871 content::WindowedNotificationObserver observer( 3872 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 3873 base::Bind(&WaitForCountNotificationsCallback, &count)); 3874 service()->CheckForExternalUpdates(); 3875 3876 observer.Wait(); 3877 3878 ASSERT_EQ(2u, registry()->enabled_extensions().size()); 3879 EXPECT_TRUE(service()->GetExtensionById(good_crx, false)); 3880 EXPECT_TRUE(service()->GetExtensionById(page_action, false)); 3881 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile()); 3882 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx)); 3883 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action)); 3884} 3885 3886#if !defined(OS_CHROMEOS) 3887// This tests if default apps are installed correctly. 3888TEST_F(ExtensionServiceTest, DefaultAppsInstall) { 3889 InitializeEmptyExtensionService(); 3890 service()->set_extensions_enabled(true); 3891 3892 { 3893 std::string json_data = 3894 "{" 3895 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {" 3896 " \"external_crx\": \"good.crx\"," 3897 " \"external_version\": \"1.0.0.0\"," 3898 " \"is_bookmark_app\": false" 3899 " }" 3900 "}"; 3901 default_apps::Provider* provider = new default_apps::Provider( 3902 profile(), 3903 service(), 3904 new extensions::ExternalTestingLoader(json_data, data_dir()), 3905 Manifest::INTERNAL, 3906 Manifest::INVALID_LOCATION, 3907 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT); 3908 3909 AddMockExternalProvider(provider); 3910 } 3911 3912 ASSERT_EQ(0u, registry()->enabled_extensions().size()); 3913 content::WindowedNotificationObserver observer( 3914 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 3915 content::NotificationService::AllSources()); 3916 service()->CheckForExternalUpdates(); 3917 observer.Wait(); 3918 3919 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 3920 EXPECT_TRUE(service()->GetExtensionById(good_crx, false)); 3921 const Extension* extension = service()->GetExtensionById(good_crx, false); 3922 EXPECT_TRUE(extension->from_webstore()); 3923 EXPECT_TRUE(extension->was_installed_by_default()); 3924} 3925#endif 3926 3927// Tests disabling extensions 3928TEST_F(ExtensionServiceTest, DisableExtension) { 3929 InitializeEmptyExtensionService(); 3930 3931 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 3932 EXPECT_TRUE(service()->GetExtensionById(good_crx, true)); 3933 EXPECT_TRUE(service()->GetExtensionById(good_crx, false)); 3934 3935 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3936 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 3937 EXPECT_EQ(0u, registry()->terminated_extensions().size()); 3938 EXPECT_EQ(0u, registry()->blacklisted_extensions().size()); 3939 3940 // Disable it. 3941 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION); 3942 3943 EXPECT_TRUE(service()->GetExtensionById(good_crx, true)); 3944 EXPECT_FALSE(service()->GetExtensionById(good_crx, false)); 3945 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3946 EXPECT_EQ(1u, registry()->disabled_extensions().size()); 3947 EXPECT_EQ(0u, registry()->terminated_extensions().size()); 3948 EXPECT_EQ(0u, registry()->blacklisted_extensions().size()); 3949} 3950 3951TEST_F(ExtensionServiceTest, TerminateExtension) { 3952 InitializeEmptyExtensionService(); 3953 3954 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 3955 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3956 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 3957 EXPECT_EQ(0u, registry()->terminated_extensions().size()); 3958 EXPECT_EQ(0u, registry()->blacklisted_extensions().size()); 3959 3960 TerminateExtension(good_crx); 3961 3962 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3963 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 3964 EXPECT_EQ(1u, registry()->terminated_extensions().size()); 3965 EXPECT_EQ(0u, registry()->blacklisted_extensions().size()); 3966} 3967 3968TEST_F(ExtensionServiceTest, DisableTerminatedExtension) { 3969 InitializeEmptyExtensionService(); 3970 3971 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 3972 TerminateExtension(good_crx); 3973 EXPECT_TRUE(registry()->GetExtensionById( 3974 good_crx, extensions::ExtensionRegistry::TERMINATED)); 3975 3976 // Disable it. 3977 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION); 3978 3979 EXPECT_FALSE(registry()->GetExtensionById( 3980 good_crx, extensions::ExtensionRegistry::TERMINATED)); 3981 EXPECT_TRUE(service()->GetExtensionById(good_crx, true)); 3982 3983 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 3984 EXPECT_EQ(1u, registry()->disabled_extensions().size()); 3985 EXPECT_EQ(0u, registry()->terminated_extensions().size()); 3986 EXPECT_EQ(0u, registry()->blacklisted_extensions().size()); 3987} 3988 3989// Tests disabling all extensions (simulating --disable-extensions flag). 3990TEST_F(ExtensionServiceTest, DisableAllExtensions) { 3991 InitializeEmptyExtensionService(); 3992 3993 base::FilePath path = data_dir().AppendASCII("good.crx"); 3994 InstallCRX(path, INSTALL_NEW); 3995 3996 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 3997 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 3998 3999 // Disable extensions. 4000 service()->set_extensions_enabled(false); 4001 service()->ReloadExtensionsForTest(); 4002 4003 // There shouldn't be extensions in either list. 4004 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 4005 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 4006 4007 // This shouldn't do anything when all extensions are disabled. 4008 service()->EnableExtension(good_crx); 4009 service()->ReloadExtensionsForTest(); 4010 4011 // There still shouldn't be extensions in either list. 4012 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 4013 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 4014 4015 // And then re-enable the extensions. 4016 service()->set_extensions_enabled(true); 4017 service()->ReloadExtensionsForTest(); 4018 4019 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 4020 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 4021} 4022 4023// Tests reloading extensions. 4024TEST_F(ExtensionServiceTest, ReloadExtensions) { 4025 InitializeEmptyExtensionService(); 4026 4027 // Simple extension that should install without error. 4028 base::FilePath path = data_dir().AppendASCII("good.crx"); 4029 InstallCRX(path, INSTALL_NEW, 4030 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT); 4031 const char* extension_id = good_crx; 4032 service()->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION); 4033 4034 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 4035 EXPECT_EQ(1u, registry()->disabled_extensions().size()); 4036 4037 service()->ReloadExtensionsForTest(); 4038 4039 // The creation flags should not change when reloading the extension. 4040 const Extension* extension = service()->GetExtensionById(good_crx, true); 4041 EXPECT_TRUE(extension->from_webstore()); 4042 EXPECT_TRUE(extension->was_installed_by_default()); 4043 EXPECT_FALSE(extension->from_bookmark()); 4044 4045 // Extension counts shouldn't change. 4046 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 4047 EXPECT_EQ(1u, registry()->disabled_extensions().size()); 4048 4049 service()->EnableExtension(extension_id); 4050 4051 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 4052 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 4053 4054 // Need to clear |loaded_| manually before reloading as the 4055 // EnableExtension() call above inserted into it and 4056 // UnloadAllExtensions() doesn't send out notifications. 4057 loaded_.clear(); 4058 service()->ReloadExtensionsForTest(); 4059 4060 // Extension counts shouldn't change. 4061 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 4062 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 4063} 4064 4065// Tests reloading an extension. 4066TEST_F(ExtensionServiceTest, ReloadExtension) { 4067 InitializeEmptyExtensionService(); 4068 InitializeProcessManager(); 4069 4070 // Simple extension that should install without error. 4071 const char* extension_id = "behllobkkfkfnphdnhnkndlbkcpglgmj"; 4072 base::FilePath ext = data_dir() 4073 .AppendASCII("good") 4074 .AppendASCII("Extensions") 4075 .AppendASCII(extension_id) 4076 .AppendASCII("1.0.0.0"); 4077 extensions::UnpackedInstaller::Create(service())->Load(ext); 4078 base::RunLoop().RunUntilIdle(); 4079 4080 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 4081 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 4082 4083 service()->ReloadExtension(extension_id); 4084 4085 // Extension should be disabled now, waiting to be reloaded. 4086 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 4087 EXPECT_EQ(1u, registry()->disabled_extensions().size()); 4088 EXPECT_EQ(Extension::DISABLE_RELOAD, 4089 ExtensionPrefs::Get(profile())->GetDisableReasons(extension_id)); 4090 4091 // Reloading again should not crash. 4092 service()->ReloadExtension(extension_id); 4093 4094 // Finish reloading 4095 base::RunLoop().RunUntilIdle(); 4096 4097 // Extension should be enabled again. 4098 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 4099 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 4100} 4101 4102TEST_F(ExtensionServiceTest, UninstallExtension) { 4103 InitializeEmptyExtensionService(); 4104 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 4105 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 4106 UninstallExtension(good_crx, false); 4107 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 4108 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_); 4109} 4110 4111TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) { 4112 InitializeEmptyExtensionService(); 4113 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 4114 TerminateExtension(good_crx); 4115 UninstallExtension(good_crx, false); 4116 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_); 4117} 4118 4119// Tests the uninstaller helper. 4120TEST_F(ExtensionServiceTest, UninstallExtensionHelper) { 4121 InitializeEmptyExtensionService(); 4122 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 4123 UninstallExtension(good_crx, true); 4124 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_); 4125} 4126 4127TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) { 4128 InitializeEmptyExtensionService(); 4129 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 4130 TerminateExtension(good_crx); 4131 UninstallExtension(good_crx, true); 4132 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_); 4133} 4134 4135// An extension disabled because of unsupported requirements should re-enabled 4136// if updated to a version with supported requirements as long as there are no 4137// other disable reasons. 4138TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) { 4139 InitializeEmptyExtensionService(); 4140 BlackListWebGL(); 4141 4142 base::FilePath path = data_dir().AppendASCII("requirements"); 4143 base::FilePath pem_path = 4144 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem"); 4145 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"), 4146 pem_path, 4147 INSTALL_NEW); 4148 std::string id = extension_v1->id(); 4149 EXPECT_TRUE(service()->IsExtensionEnabled(id)); 4150 4151 base::FilePath v2_bad_requirements_crx = GetTemporaryFile(); 4152 4153 PackCRX(path.AppendASCII("v2_bad_requirements"), 4154 pem_path, 4155 v2_bad_requirements_crx); 4156 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED); 4157 EXPECT_FALSE(service()->IsExtensionEnabled(id)); 4158 4159 base::FilePath v3_good_crx = GetTemporaryFile(); 4160 4161 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx); 4162 UpdateExtension(id, v3_good_crx, ENABLED); 4163 EXPECT_TRUE(service()->IsExtensionEnabled(id)); 4164} 4165 4166// Extensions disabled through user action should stay disabled. 4167TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) { 4168 InitializeEmptyExtensionService(); 4169 BlackListWebGL(); 4170 4171 base::FilePath path = data_dir().AppendASCII("requirements"); 4172 base::FilePath pem_path = 4173 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem"); 4174 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"), 4175 pem_path, 4176 INSTALL_NEW); 4177 std::string id = extension_v1->id(); 4178 service()->DisableExtension(id, Extension::DISABLE_USER_ACTION); 4179 EXPECT_FALSE(service()->IsExtensionEnabled(id)); 4180 4181 base::FilePath v2_bad_requirements_crx = GetTemporaryFile(); 4182 4183 PackCRX(path.AppendASCII("v2_bad_requirements"), 4184 pem_path, 4185 v2_bad_requirements_crx); 4186 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED); 4187 EXPECT_FALSE(service()->IsExtensionEnabled(id)); 4188 4189 base::FilePath v3_good_crx = GetTemporaryFile(); 4190 4191 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx); 4192 UpdateExtension(id, v3_good_crx, INSTALLED); 4193 EXPECT_FALSE(service()->IsExtensionEnabled(id)); 4194} 4195 4196// The extension should not re-enabled because it was disabled from a 4197// permission increase. 4198TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) { 4199 InitializeEmptyExtensionService(); 4200 BlackListWebGL(); 4201 4202 base::FilePath path = data_dir().AppendASCII("requirements"); 4203 base::FilePath pem_path = 4204 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem"); 4205 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"), 4206 pem_path, 4207 INSTALL_NEW); 4208 std::string id = extension_v1->id(); 4209 EXPECT_TRUE(service()->IsExtensionEnabled(id)); 4210 4211 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile(); 4212 4213 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"), 4214 pem_path, 4215 v2_bad_requirements_and_permissions_crx); 4216 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED); 4217 EXPECT_FALSE(service()->IsExtensionEnabled(id)); 4218 4219 base::FilePath v3_bad_permissions_crx = GetTemporaryFile(); 4220 4221 PackCRX(path.AppendASCII("v3_bad_permissions"), 4222 pem_path, 4223 v3_bad_permissions_crx); 4224 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED); 4225 EXPECT_FALSE(service()->IsExtensionEnabled(id)); 4226} 4227 4228// Unpacked extensions are not allowed to be installed if they have unsupported 4229// requirements. 4230TEST_F(ExtensionServiceTest, UnpackedRequirements) { 4231 InitializeEmptyExtensionService(); 4232 BlackListWebGL(); 4233 4234 base::FilePath path = 4235 data_dir().AppendASCII("requirements").AppendASCII("v2_bad_requirements"); 4236 extensions::UnpackedInstaller::Create(service())->Load(path); 4237 base::RunLoop().RunUntilIdle(); 4238 EXPECT_EQ(1u, GetErrors().size()); 4239 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 4240} 4241 4242class ExtensionCookieCallback { 4243 public: 4244 ExtensionCookieCallback() 4245 : result_(false), 4246 weak_factory_(base::MessageLoop::current()) {} 4247 4248 void SetCookieCallback(bool result) { 4249 base::MessageLoop::current()->PostTask(FROM_HERE, 4250 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr())); 4251 result_ = result; 4252 } 4253 4254 void GetAllCookiesCallback(const net::CookieList& list) { 4255 base::MessageLoop::current()->PostTask(FROM_HERE, 4256 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr())); 4257 list_ = list; 4258 } 4259 net::CookieList list_; 4260 bool result_; 4261 base::WeakPtrFactory<base::MessageLoop> weak_factory_; 4262}; 4263 4264// Verifies extension state is removed upon uninstall. 4265TEST_F(ExtensionServiceTest, ClearExtensionData) { 4266 InitializeEmptyExtensionService(); 4267 ExtensionCookieCallback callback; 4268 4269 // Load a test extension. 4270 base::FilePath path = data_dir(); 4271 path = path.AppendASCII("good.crx"); 4272 const Extension* extension = InstallCRX(path, INSTALL_NEW); 4273 ASSERT_TRUE(extension); 4274 GURL ext_url(extension->url()); 4275 std::string origin_id = webkit_database::GetIdentifierFromOrigin(ext_url); 4276 4277 // Set a cookie for the extension. 4278 net::CookieMonster* cookie_monster = profile() 4279 ->GetRequestContextForExtensions() 4280 ->GetURLRequestContext() 4281 ->cookie_store() 4282 ->GetCookieMonster(); 4283 ASSERT_TRUE(cookie_monster); 4284 net::CookieOptions options; 4285 cookie_monster->SetCookieWithOptionsAsync( 4286 ext_url, "dummy=value", options, 4287 base::Bind(&ExtensionCookieCallback::SetCookieCallback, 4288 base::Unretained(&callback))); 4289 base::RunLoop().RunUntilIdle(); 4290 EXPECT_TRUE(callback.result_); 4291 4292 cookie_monster->GetAllCookiesForURLAsync( 4293 ext_url, 4294 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback, 4295 base::Unretained(&callback))); 4296 base::RunLoop().RunUntilIdle(); 4297 EXPECT_EQ(1U, callback.list_.size()); 4298 4299 // Open a database. 4300 webkit_database::DatabaseTracker* db_tracker = 4301 BrowserContext::GetDefaultStoragePartition(profile()) 4302 ->GetDatabaseTracker(); 4303 base::string16 db_name = base::UTF8ToUTF16("db"); 4304 base::string16 description = base::UTF8ToUTF16("db_description"); 4305 int64 size; 4306 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size); 4307 db_tracker->DatabaseClosed(origin_id, db_name); 4308 std::vector<webkit_database::OriginInfo> origins; 4309 db_tracker->GetAllOriginsInfo(&origins); 4310 EXPECT_EQ(1U, origins.size()); 4311 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier()); 4312 4313 // Create local storage. We only simulate this by creating the backing files. 4314 // Note: This test depends on details of how the dom_storage library 4315 // stores data in the host file system. 4316 base::FilePath lso_dir_path = 4317 profile()->GetPath().AppendASCII("Local Storage"); 4318 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id) 4319 .AddExtension(FILE_PATH_LITERAL(".localstorage")); 4320 EXPECT_TRUE(base::CreateDirectory(lso_dir_path)); 4321 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0)); 4322 EXPECT_TRUE(base::PathExists(lso_file_path)); 4323 4324 // Create indexed db. Similarly, it is enough to only simulate this by 4325 // creating the directory on the disk. 4326 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition( 4327 profile())->GetIndexedDBContext(); 4328 idb_context->SetTaskRunnerForTesting( 4329 base::MessageLoop::current()->message_loop_proxy().get()); 4330 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id); 4331 EXPECT_TRUE(base::CreateDirectory(idb_path)); 4332 EXPECT_TRUE(base::DirectoryExists(idb_path)); 4333 4334 // Uninstall the extension. 4335 service()->UninstallExtension( 4336 good_crx, ExtensionService::UNINSTALL_REASON_FOR_TESTING, NULL); 4337 base::RunLoop().RunUntilIdle(); 4338 4339 // Check that the cookie is gone. 4340 cookie_monster->GetAllCookiesForURLAsync( 4341 ext_url, 4342 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback, 4343 base::Unretained(&callback))); 4344 base::RunLoop().RunUntilIdle(); 4345 EXPECT_EQ(0U, callback.list_.size()); 4346 4347 // The database should have vanished as well. 4348 origins.clear(); 4349 db_tracker->GetAllOriginsInfo(&origins); 4350 EXPECT_EQ(0U, origins.size()); 4351 4352 // Check that the LSO file has been removed. 4353 EXPECT_FALSE(base::PathExists(lso_file_path)); 4354 4355 // Check if the indexed db has disappeared too. 4356 EXPECT_FALSE(base::DirectoryExists(idb_path)); 4357} 4358 4359// Verifies app state is removed upon uninstall. 4360TEST_F(ExtensionServiceTest, ClearAppData) { 4361 InitializeEmptyExtensionService(); 4362 ExtensionCookieCallback callback; 4363 4364 int pref_count = 0; 4365 4366 // Install app1 with unlimited storage. 4367 const Extension* extension = 4368 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW); 4369 ValidatePrefKeyCount(++pref_count); 4370 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 4371 const std::string id1 = extension->id(); 4372 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission( 4373 APIPermission::kUnlimitedStorage)); 4374 const GURL origin1( 4375 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin()); 4376 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 4377 origin1)); 4378 std::string origin_id = webkit_database::GetIdentifierFromOrigin(origin1); 4379 4380 // Install app2 from the same origin with unlimited storage. 4381 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW); 4382 ValidatePrefKeyCount(++pref_count); 4383 ASSERT_EQ(2u, registry()->enabled_extensions().size()); 4384 const std::string id2 = extension->id(); 4385 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission( 4386 APIPermission::kUnlimitedStorage)); 4387 EXPECT_TRUE(extension->web_extent().MatchesURL( 4388 extensions::AppLaunchInfo::GetFullLaunchURL(extension))); 4389 const GURL origin2( 4390 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin()); 4391 EXPECT_EQ(origin1, origin2); 4392 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 4393 origin2)); 4394 4395 // Set a cookie for the extension. 4396 net::CookieMonster* cookie_monster = profile() 4397 ->GetRequestContext() 4398 ->GetURLRequestContext() 4399 ->cookie_store() 4400 ->GetCookieMonster(); 4401 ASSERT_TRUE(cookie_monster); 4402 net::CookieOptions options; 4403 cookie_monster->SetCookieWithOptionsAsync( 4404 origin1, "dummy=value", options, 4405 base::Bind(&ExtensionCookieCallback::SetCookieCallback, 4406 base::Unretained(&callback))); 4407 base::RunLoop().RunUntilIdle(); 4408 EXPECT_TRUE(callback.result_); 4409 4410 cookie_monster->GetAllCookiesForURLAsync( 4411 origin1, 4412 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback, 4413 base::Unretained(&callback))); 4414 base::RunLoop().RunUntilIdle(); 4415 EXPECT_EQ(1U, callback.list_.size()); 4416 4417 // Open a database. 4418 webkit_database::DatabaseTracker* db_tracker = 4419 BrowserContext::GetDefaultStoragePartition(profile()) 4420 ->GetDatabaseTracker(); 4421 base::string16 db_name = base::UTF8ToUTF16("db"); 4422 base::string16 description = base::UTF8ToUTF16("db_description"); 4423 int64 size; 4424 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size); 4425 db_tracker->DatabaseClosed(origin_id, db_name); 4426 std::vector<webkit_database::OriginInfo> origins; 4427 db_tracker->GetAllOriginsInfo(&origins); 4428 EXPECT_EQ(1U, origins.size()); 4429 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier()); 4430 4431 // Create local storage. We only simulate this by creating the backing files. 4432 // Note: This test depends on details of how the dom_storage library 4433 // stores data in the host file system. 4434 base::FilePath lso_dir_path = 4435 profile()->GetPath().AppendASCII("Local Storage"); 4436 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id) 4437 .AddExtension(FILE_PATH_LITERAL(".localstorage")); 4438 EXPECT_TRUE(base::CreateDirectory(lso_dir_path)); 4439 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0)); 4440 EXPECT_TRUE(base::PathExists(lso_file_path)); 4441 4442 // Create indexed db. Similarly, it is enough to only simulate this by 4443 // creating the directory on the disk. 4444 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition( 4445 profile())->GetIndexedDBContext(); 4446 idb_context->SetTaskRunnerForTesting( 4447 base::MessageLoop::current()->message_loop_proxy().get()); 4448 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id); 4449 EXPECT_TRUE(base::CreateDirectory(idb_path)); 4450 EXPECT_TRUE(base::DirectoryExists(idb_path)); 4451 4452 // Uninstall one of them, unlimited storage should still be granted 4453 // to the origin. 4454 UninstallExtension(id1, false); 4455 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 4456 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 4457 origin1)); 4458 4459 // Check that the cookie is still there. 4460 cookie_monster->GetAllCookiesForURLAsync( 4461 origin1, 4462 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback, 4463 base::Unretained(&callback))); 4464 base::RunLoop().RunUntilIdle(); 4465 EXPECT_EQ(1U, callback.list_.size()); 4466 4467 // Now uninstall the other. Storage should be cleared for the apps. 4468 UninstallExtension(id2, false); 4469 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 4470 EXPECT_FALSE( 4471 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 4472 origin1)); 4473 4474 // Check that the cookie is gone. 4475 cookie_monster->GetAllCookiesForURLAsync( 4476 origin1, 4477 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback, 4478 base::Unretained(&callback))); 4479 base::RunLoop().RunUntilIdle(); 4480 EXPECT_EQ(0U, callback.list_.size()); 4481 4482 // The database should have vanished as well. 4483 origins.clear(); 4484 db_tracker->GetAllOriginsInfo(&origins); 4485 EXPECT_EQ(0U, origins.size()); 4486 4487 // Check that the LSO file has been removed. 4488 EXPECT_FALSE(base::PathExists(lso_file_path)); 4489 4490 // Check if the indexed db has disappeared too. 4491 EXPECT_FALSE(base::DirectoryExists(idb_path)); 4492} 4493 4494// Tests loading single extensions (like --load-extension) 4495// Flaky crashes. http://crbug.com/231806 4496TEST_F(ExtensionServiceTest, DISABLED_LoadExtension) { 4497 InitializeEmptyExtensionService(); 4498 4499 base::FilePath ext1 = data_dir() 4500 .AppendASCII("good") 4501 .AppendASCII("Extensions") 4502 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 4503 .AppendASCII("1.0.0.0"); 4504 extensions::UnpackedInstaller::Create(service())->Load(ext1); 4505 base::RunLoop().RunUntilIdle(); 4506 EXPECT_EQ(0u, GetErrors().size()); 4507 ASSERT_EQ(1u, loaded_.size()); 4508 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location()); 4509 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 4510 4511 ValidatePrefKeyCount(1); 4512 4513 base::FilePath no_manifest = 4514 data_dir() 4515 .AppendASCII("bad") 4516 // .AppendASCII("Extensions") 4517 .AppendASCII("cccccccccccccccccccccccccccccccc") 4518 .AppendASCII("1"); 4519 extensions::UnpackedInstaller::Create(service())->Load(no_manifest); 4520 base::RunLoop().RunUntilIdle(); 4521 EXPECT_EQ(1u, GetErrors().size()); 4522 ASSERT_EQ(1u, loaded_.size()); 4523 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 4524 4525 // Test uninstall. 4526 std::string id = loaded_[0]->id(); 4527 EXPECT_FALSE(unloaded_id_.length()); 4528 service()->UninstallExtension( 4529 id, ExtensionService::UNINSTALL_REASON_FOR_TESTING, NULL); 4530 base::RunLoop().RunUntilIdle(); 4531 EXPECT_EQ(id, unloaded_id_); 4532 ASSERT_EQ(0u, loaded_.size()); 4533 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 4534} 4535 4536// Tests that we generate IDs when they are not specified in the manifest for 4537// --load-extension. 4538TEST_F(ExtensionServiceTest, GenerateID) { 4539 InitializeEmptyExtensionService(); 4540 4541 base::FilePath no_id_ext = data_dir().AppendASCII("no_id"); 4542 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext); 4543 base::RunLoop().RunUntilIdle(); 4544 EXPECT_EQ(0u, GetErrors().size()); 4545 ASSERT_EQ(1u, loaded_.size()); 4546 ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id())); 4547 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED); 4548 4549 ValidatePrefKeyCount(1); 4550 4551 std::string previous_id = loaded_[0]->id(); 4552 4553 // If we reload the same path, we should get the same extension ID. 4554 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext); 4555 base::RunLoop().RunUntilIdle(); 4556 ASSERT_EQ(1u, loaded_.size()); 4557 ASSERT_EQ(previous_id, loaded_[0]->id()); 4558} 4559 4560TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) { 4561 InitializeEmptyExtensionService(); 4562 4563 base::FilePath bad_locale = 4564 data_dir().AppendASCII("unpacked").AppendASCII("bad_messages_file"); 4565 extensions::UnpackedInstaller::Create(service())->Load(bad_locale); 4566 base::RunLoop().RunUntilIdle(); 4567 EXPECT_EQ(1u, GetErrors().size()); 4568 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales") 4569 .AppendASCII("ms") 4570 .AppendASCII("messages.json"); 4571 EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]), testing::AllOf( 4572 testing::HasSubstr( 4573 base::UTF16ToUTF8(ms_messages_file.LossyDisplayName())), 4574 testing::HasSubstr("Dictionary keys must be quoted."))); 4575 ASSERT_EQ(0u, loaded_.size()); 4576} 4577 4578void ExtensionServiceTest::TestExternalProvider( 4579 MockExtensionProvider* provider, Manifest::Location location) { 4580 // Verify that starting with no providers loads no extensions. 4581 service()->Init(); 4582 ASSERT_EQ(0u, loaded_.size()); 4583 4584 provider->set_visit_count(0); 4585 4586 // Register a test extension externally using the mock registry provider. 4587 base::FilePath source_path = data_dir().AppendASCII("good.crx"); 4588 4589 // Add the extension. 4590 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path); 4591 4592 // Reloading extensions should find our externally registered extension 4593 // and install it. 4594 content::WindowedNotificationObserver observer( 4595 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 4596 content::NotificationService::AllSources()); 4597 service()->CheckForExternalUpdates(); 4598 observer.Wait(); 4599 4600 ASSERT_EQ(0u, GetErrors().size()); 4601 ASSERT_EQ(1u, loaded_.size()); 4602 ASSERT_EQ(location, loaded_[0]->location()); 4603 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString()); 4604 ValidatePrefKeyCount(1); 4605 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 4606 ValidateIntegerPref(good_crx, "location", location); 4607 4608 // Reload extensions without changing anything. The extension should be 4609 // loaded again. 4610 loaded_.clear(); 4611 service()->ReloadExtensionsForTest(); 4612 base::RunLoop().RunUntilIdle(); 4613 ASSERT_EQ(0u, GetErrors().size()); 4614 ASSERT_EQ(1u, loaded_.size()); 4615 ValidatePrefKeyCount(1); 4616 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 4617 ValidateIntegerPref(good_crx, "location", location); 4618 4619 // Now update the extension with a new version. We should get upgraded. 4620 source_path = source_path.DirName().AppendASCII("good2.crx"); 4621 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path); 4622 4623 loaded_.clear(); 4624 content::WindowedNotificationObserver observer_2( 4625 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 4626 content::NotificationService::AllSources()); 4627 service()->CheckForExternalUpdates(); 4628 observer_2.Wait(); 4629 ASSERT_EQ(0u, GetErrors().size()); 4630 ASSERT_EQ(1u, loaded_.size()); 4631 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString()); 4632 ValidatePrefKeyCount(1); 4633 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 4634 ValidateIntegerPref(good_crx, "location", location); 4635 4636 // Uninstall the extension and reload. Nothing should happen because the 4637 // preference should prevent us from reinstalling. 4638 std::string id = loaded_[0]->id(); 4639 bool no_uninstall = 4640 GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL); 4641 service()->UninstallExtension( 4642 id, ExtensionService::UNINSTALL_REASON_FOR_TESTING, NULL); 4643 base::RunLoop().RunUntilIdle(); 4644 4645 base::FilePath install_path = extensions_install_dir().AppendASCII(id); 4646 if (no_uninstall) { 4647 // Policy controlled extensions should not have been touched by uninstall. 4648 ASSERT_TRUE(base::PathExists(install_path)); 4649 } else { 4650 // The extension should also be gone from the install directory. 4651 ASSERT_FALSE(base::PathExists(install_path)); 4652 loaded_.clear(); 4653 service()->CheckForExternalUpdates(); 4654 base::RunLoop().RunUntilIdle(); 4655 ASSERT_EQ(0u, loaded_.size()); 4656 ValidatePrefKeyCount(1); 4657 ValidateIntegerPref(good_crx, "state", 4658 Extension::EXTERNAL_EXTENSION_UNINSTALLED); 4659 ValidateIntegerPref(good_crx, "location", location); 4660 4661 // Now clear the preference and reinstall. 4662 SetPrefInteg(good_crx, "state", Extension::ENABLED); 4663 4664 loaded_.clear(); 4665 content::WindowedNotificationObserver observer( 4666 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 4667 content::NotificationService::AllSources()); 4668 service()->CheckForExternalUpdates(); 4669 observer.Wait(); 4670 ASSERT_EQ(1u, loaded_.size()); 4671 } 4672 ValidatePrefKeyCount(1); 4673 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 4674 ValidateIntegerPref(good_crx, "location", location); 4675 4676 if (GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL)) { 4677 EXPECT_EQ(2, provider->visit_count()); 4678 } else { 4679 // Now test an externally triggered uninstall (deleting the registry key or 4680 // the pref entry). 4681 provider->RemoveExtension(good_crx); 4682 4683 loaded_.clear(); 4684 service()->OnExternalProviderReady(provider); 4685 base::RunLoop().RunUntilIdle(); 4686 ASSERT_EQ(0u, loaded_.size()); 4687 ValidatePrefKeyCount(0); 4688 4689 // The extension should also be gone from the install directory. 4690 ASSERT_FALSE(base::PathExists(install_path)); 4691 4692 // Now test the case where user uninstalls and then the extension is removed 4693 // from the external provider. 4694 content::WindowedNotificationObserver observer( 4695 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 4696 content::NotificationService::AllSources()); 4697 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path); 4698 service()->CheckForExternalUpdates(); 4699 observer.Wait(); 4700 4701 ASSERT_EQ(1u, loaded_.size()); 4702 ASSERT_EQ(0u, GetErrors().size()); 4703 4704 // User uninstalls. 4705 loaded_.clear(); 4706 service()->UninstallExtension( 4707 id, ExtensionService::UNINSTALL_REASON_FOR_TESTING, NULL); 4708 base::RunLoop().RunUntilIdle(); 4709 ASSERT_EQ(0u, loaded_.size()); 4710 4711 // Then remove the extension from the extension provider. 4712 provider->RemoveExtension(good_crx); 4713 4714 // Should still be at 0. 4715 loaded_.clear(); 4716 extensions::InstalledLoader(service()).LoadAllExtensions(); 4717 base::RunLoop().RunUntilIdle(); 4718 ASSERT_EQ(0u, loaded_.size()); 4719 ValidatePrefKeyCount(1); 4720 4721 EXPECT_EQ(5, provider->visit_count()); 4722 } 4723} 4724 4725// Tests the external installation feature 4726#if defined(OS_WIN) 4727TEST_F(ExtensionServiceTest, ExternalInstallRegistry) { 4728 // This should all work, even when normal extension installation is disabled. 4729 InitializeEmptyExtensionService(); 4730 service()->set_extensions_enabled(false); 4731 4732 // Now add providers. Extension system takes ownership of the objects. 4733 MockExtensionProvider* reg_provider = 4734 new MockExtensionProvider(service(), Manifest::EXTERNAL_REGISTRY); 4735 AddMockExternalProvider(reg_provider); 4736 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY); 4737} 4738#endif 4739 4740TEST_F(ExtensionServiceTest, ExternalInstallPref) { 4741 InitializeEmptyExtensionService(); 4742 4743 // Now add providers. Extension system takes ownership of the objects. 4744 MockExtensionProvider* pref_provider = 4745 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF); 4746 4747 AddMockExternalProvider(pref_provider); 4748 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF); 4749} 4750 4751TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) { 4752 // This should all work, even when normal extension installation is disabled. 4753 InitializeEmptyExtensionService(); 4754 service()->set_extensions_enabled(false); 4755 4756 // TODO(skerner): The mock provider is not a good model of a provider 4757 // that works with update URLs, because it adds file and version info. 4758 // Extend the mock to work with update URLs. This test checks the 4759 // behavior that is common to all external extension visitors. The 4760 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that 4761 // what the visitor does results in an extension being downloaded and 4762 // installed. 4763 MockExtensionProvider* pref_provider = 4764 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF_DOWNLOAD); 4765 AddMockExternalProvider(pref_provider); 4766 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD); 4767} 4768 4769TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) { 4770 // This should all work, even when normal extension installation is disabled. 4771 InitializeEmptyExtensionService(); 4772 service()->set_extensions_enabled(false); 4773 4774 // TODO(skerner): The mock provider is not a good model of a provider 4775 // that works with update URLs, because it adds file and version info. 4776 // Extend the mock to work with update URLs. This test checks the 4777 // behavior that is common to all external extension visitors. The 4778 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that 4779 // what the visitor does results in an extension being downloaded and 4780 // installed. 4781 MockExtensionProvider* pref_provider = 4782 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD); 4783 AddMockExternalProvider(pref_provider); 4784 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD); 4785} 4786 4787// Tests that external extensions get uninstalled when the external extension 4788// providers can't account for them. 4789TEST_F(ExtensionServiceTest, ExternalUninstall) { 4790 // Start the extensions service with one external extension already installed. 4791 base::FilePath source_install_dir = 4792 data_dir().AppendASCII("good").AppendASCII("Extensions"); 4793 base::FilePath pref_path = source_install_dir 4794 .DirName() 4795 .AppendASCII("PreferencesExternal"); 4796 4797 // This initializes the extensions service with no ExternalProviders. 4798 InitializeInstalledExtensionService(pref_path, source_install_dir); 4799 service()->set_extensions_enabled(false); 4800 4801 service()->Init(); 4802 4803 ASSERT_EQ(0u, GetErrors().size()); 4804 ASSERT_EQ(0u, loaded_.size()); 4805 4806 // Verify that it's not the disabled extensions flag causing it not to load. 4807 service()->set_extensions_enabled(true); 4808 service()->ReloadExtensionsForTest(); 4809 base::RunLoop().RunUntilIdle(); 4810 4811 ASSERT_EQ(0u, GetErrors().size()); 4812 ASSERT_EQ(0u, loaded_.size()); 4813} 4814 4815// Test that running multiple update checks simultaneously does not 4816// keep the update from succeeding. 4817TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) { 4818 InitializeEmptyExtensionService(); 4819 4820 MockExtensionProvider* provider = 4821 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF); 4822 AddMockExternalProvider(provider); 4823 4824 // Verify that starting with no providers loads no extensions. 4825 service()->Init(); 4826 ASSERT_EQ(0u, loaded_.size()); 4827 4828 // Start two checks for updates. 4829 provider->set_visit_count(0); 4830 service()->CheckForExternalUpdates(); 4831 service()->CheckForExternalUpdates(); 4832 base::RunLoop().RunUntilIdle(); 4833 4834 // Two calls should cause two checks for external extensions. 4835 EXPECT_EQ(2, provider->visit_count()); 4836 EXPECT_EQ(0u, GetErrors().size()); 4837 EXPECT_EQ(0u, loaded_.size()); 4838 4839 // Register a test extension externally using the mock registry provider. 4840 base::FilePath source_path = data_dir().AppendASCII("good.crx"); 4841 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path); 4842 4843 // Two checks for external updates should find the extension, and install it 4844 // once. 4845 content::WindowedNotificationObserver observer( 4846 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 4847 content::NotificationService::AllSources()); 4848 provider->set_visit_count(0); 4849 service()->CheckForExternalUpdates(); 4850 service()->CheckForExternalUpdates(); 4851 observer.Wait(); 4852 EXPECT_EQ(2, provider->visit_count()); 4853 ASSERT_EQ(0u, GetErrors().size()); 4854 ASSERT_EQ(1u, loaded_.size()); 4855 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location()); 4856 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString()); 4857 ValidatePrefKeyCount(1); 4858 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 4859 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF); 4860 4861 provider->RemoveExtension(good_crx); 4862 provider->set_visit_count(0); 4863 service()->CheckForExternalUpdates(); 4864 service()->CheckForExternalUpdates(); 4865 base::RunLoop().RunUntilIdle(); 4866 4867 // Two calls should cause two checks for external extensions. 4868 // Because the external source no longer includes good_crx, 4869 // good_crx will be uninstalled. So, expect that no extensions 4870 // are loaded. 4871 EXPECT_EQ(2, provider->visit_count()); 4872 EXPECT_EQ(0u, GetErrors().size()); 4873 EXPECT_EQ(0u, loaded_.size()); 4874} 4875 4876TEST_F(ExtensionServiceTest, ExternalPrefProvider) { 4877 InitializeEmptyExtensionService(); 4878 4879 // Test some valid extension records. 4880 // Set a base path to avoid erroring out on relative paths. 4881 // Paths starting with // are absolute on every platform we support. 4882 base::FilePath base_path(FILE_PATH_LITERAL("//base/path")); 4883 ASSERT_TRUE(base_path.IsAbsolute()); 4884 MockProviderVisitor visitor(base_path); 4885 std::string json_data = 4886 "{" 4887 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 4888 " \"external_crx\": \"RandomExtension.crx\"," 4889 " \"external_version\": \"1.0\"" 4890 " }," 4891 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" 4892 " \"external_crx\": \"RandomExtension2.crx\"," 4893 " \"external_version\": \"2.0\"" 4894 " }," 4895 " \"cccccccccccccccccccccccccccccccc\": {" 4896 " \"external_update_url\": \"http:\\\\foo.com/update\"," 4897 " \"install_parameter\": \"id\"" 4898 " }" 4899 "}"; 4900 EXPECT_EQ(3, visitor.Visit(json_data)); 4901 4902 // Simulate an external_extensions.json file that contains seven invalid 4903 // records: 4904 // - One that is missing the 'external_crx' key. 4905 // - One that is missing the 'external_version' key. 4906 // - One that is specifying .. in the path. 4907 // - One that specifies both a file and update URL. 4908 // - One that specifies no file or update URL. 4909 // - One that has an update URL that is not well formed. 4910 // - One that contains a malformed version. 4911 // - One that has an invalid id. 4912 // - One that has a non-dictionary value. 4913 // - One that has an integer 'external_version' instead of a string. 4914 // The final extension is valid, and we check that it is read to make sure 4915 // failures don't stop valid records from being read. 4916 json_data = 4917 "{" 4918 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 4919 " \"external_version\": \"1.0\"" 4920 " }," 4921 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" 4922 " \"external_crx\": \"RandomExtension.crx\"" 4923 " }," 4924 " \"cccccccccccccccccccccccccccccccc\": {" 4925 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\"," 4926 " \"external_version\": \"2.0\"" 4927 " }," 4928 " \"dddddddddddddddddddddddddddddddd\": {" 4929 " \"external_crx\": \"RandomExtension2.crx\"," 4930 " \"external_version\": \"2.0\"," 4931 " \"external_update_url\": \"http:\\\\foo.com/update\"" 4932 " }," 4933 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {" 4934 " }," 4935 " \"ffffffffffffffffffffffffffffffff\": {" 4936 " \"external_update_url\": \"This string is not a valid URL\"" 4937 " }," 4938 " \"gggggggggggggggggggggggggggggggg\": {" 4939 " \"external_crx\": \"RandomExtension3.crx\"," 4940 " \"external_version\": \"This is not a valid version!\"" 4941 " }," 4942 " \"This is not a valid id!\": {}," 4943 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true," 4944 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {" 4945 " \"external_crx\": \"RandomExtension4.crx\"," 4946 " \"external_version\": 1.0" 4947 " }," 4948 " \"pppppppppppppppppppppppppppppppp\": {" 4949 " \"external_crx\": \"RandomValidExtension.crx\"," 4950 " \"external_version\": \"1.0\"" 4951 " }" 4952 "}"; 4953 EXPECT_EQ(1, visitor.Visit(json_data)); 4954 4955 // Check that if a base path is not provided, use of a relative 4956 // path fails. 4957 base::FilePath empty; 4958 MockProviderVisitor visitor_no_relative_paths(empty); 4959 4960 // Use absolute paths. Expect success. 4961 json_data = 4962 "{" 4963 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 4964 " \"external_crx\": \"//RandomExtension1.crx\"," 4965 " \"external_version\": \"3.0\"" 4966 " }," 4967 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" 4968 " \"external_crx\": \"//path/to/RandomExtension2.crx\"," 4969 " \"external_version\": \"3.0\"" 4970 " }" 4971 "}"; 4972 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data)); 4973 4974 // Use a relative path. Expect that it will error out. 4975 json_data = 4976 "{" 4977 " \"cccccccccccccccccccccccccccccccc\": {" 4978 " \"external_crx\": \"RandomExtension2.crx\"," 4979 " \"external_version\": \"3.0\"" 4980 " }" 4981 "}"; 4982 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data)); 4983 4984 // Test supported_locales. 4985 json_data = 4986 "{" 4987 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 4988 " \"external_crx\": \"RandomExtension.crx\"," 4989 " \"external_version\": \"1.0\"," 4990 " \"supported_locales\": [ \"en\" ]" 4991 " }," 4992 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" 4993 " \"external_crx\": \"RandomExtension2.crx\"," 4994 " \"external_version\": \"2.0\"," 4995 " \"supported_locales\": [ \"en-GB\" ]" 4996 " }," 4997 " \"cccccccccccccccccccccccccccccccc\": {" 4998 " \"external_crx\": \"RandomExtension2.crx\"," 4999 " \"external_version\": \"3.0\"," 5000 " \"supported_locales\": [ \"en_US\", \"fr\" ]" 5001 " }" 5002 "}"; 5003 { 5004 ScopedBrowserLocale guard("en-US"); 5005 EXPECT_EQ(2, visitor.Visit(json_data)); 5006 } 5007 5008 // Test keep_if_present. 5009 json_data = 5010 "{" 5011 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 5012 " \"external_crx\": \"RandomExtension.crx\"," 5013 " \"external_version\": \"1.0\"," 5014 " \"keep_if_present\": true" 5015 " }" 5016 "}"; 5017 { 5018 EXPECT_EQ(0, visitor.Visit(json_data)); 5019 } 5020 5021 // Test is_bookmark_app. 5022 MockProviderVisitor from_bookmark_visitor( 5023 base_path, Extension::FROM_BOOKMARK); 5024 json_data = 5025 "{" 5026 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 5027 " \"external_crx\": \"RandomExtension.crx\"," 5028 " \"external_version\": \"1.0\"," 5029 " \"is_bookmark_app\": true" 5030 " }" 5031 "}"; 5032 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data)); 5033 5034 // Test is_from_webstore. 5035 MockProviderVisitor from_webstore_visitor( 5036 base_path, Extension::FROM_WEBSTORE); 5037 json_data = 5038 "{" 5039 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 5040 " \"external_crx\": \"RandomExtension.crx\"," 5041 " \"external_version\": \"1.0\"," 5042 " \"is_from_webstore\": true" 5043 " }" 5044 "}"; 5045 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data)); 5046 5047 // Test was_installed_by_eom. 5048 MockProviderVisitor was_installed_by_eom_visitor( 5049 base_path, Extension::WAS_INSTALLED_BY_OEM); 5050 json_data = 5051 "{" 5052 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 5053 " \"external_crx\": \"RandomExtension.crx\"," 5054 " \"external_version\": \"1.0\"," 5055 " \"was_installed_by_oem\": true" 5056 " }" 5057 "}"; 5058 EXPECT_EQ(1, was_installed_by_eom_visitor.Visit(json_data)); 5059} 5060 5061// Test loading good extensions from the profile directory. 5062TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) { 5063 // Ensure we're testing in "en" and leave global state untouched. 5064 extension_l10n_util::ScopedLocaleForTest testLocale("en"); 5065 5066 // Initialize the test dir with a good Preferences/extensions. 5067 base::FilePath source_install_dir = data_dir().AppendASCII("l10n"); 5068 base::FilePath pref_path = 5069 source_install_dir.Append(chrome::kPreferencesFilename); 5070 InitializeInstalledExtensionService(pref_path, source_install_dir); 5071 5072 service()->Init(); 5073 5074 ASSERT_EQ(3u, loaded_.size()); 5075 5076 // This was equal to "sr" on load. 5077 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en"); 5078 5079 // These are untouched by re-localization. 5080 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en"); 5081 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale)); 5082 5083 // This one starts with Serbian name, and gets re-localized into English. 5084 EXPECT_EQ("My name is simple.", loaded_[0]->name()); 5085 5086 // These are untouched by re-localization. 5087 EXPECT_EQ("My name is simple.", loaded_[1]->name()); 5088 EXPECT_EQ("no l10n", loaded_[2]->name()); 5089} 5090 5091class ExtensionsReadyRecorder : public content::NotificationObserver { 5092 public: 5093 ExtensionsReadyRecorder() : ready_(false) { 5094 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY, 5095 content::NotificationService::AllSources()); 5096 } 5097 5098 void set_ready(bool value) { ready_ = value; } 5099 bool ready() { return ready_; } 5100 5101 private: 5102 virtual void Observe(int type, 5103 const content::NotificationSource& source, 5104 const content::NotificationDetails& details) OVERRIDE { 5105 switch (type) { 5106 case chrome::NOTIFICATION_EXTENSIONS_READY: 5107 ready_ = true; 5108 break; 5109 default: 5110 NOTREACHED(); 5111 } 5112 } 5113 5114 content::NotificationRegistrar registrar_; 5115 bool ready_; 5116}; 5117 5118// Test that we get enabled/disabled correctly for all the pref/command-line 5119// combinations. We don't want to derive from the ExtensionServiceTest class 5120// for this test, so we use ExtensionServiceTestSimple. 5121// 5122// Also tests that we always fire EXTENSIONS_READY, no matter whether we are 5123// enabled or not. 5124TEST(ExtensionServiceTestSimple, Enabledness) { 5125 // Make sure the PluginService singleton is destroyed at the end of the test. 5126 base::ShadowingAtExitManager at_exit_manager; 5127#if defined(ENABLE_PLUGINS) 5128 content::PluginService::GetInstance()->Init(); 5129 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting(); 5130#endif 5131 5132 ExtensionErrorReporter::Init(false); // no noisy errors 5133 ExtensionsReadyRecorder recorder; 5134 scoped_ptr<TestingProfile> profile(new TestingProfile()); 5135 content::TestBrowserThreadBundle thread_bundle_; 5136#if defined OS_CHROMEOS 5137 chromeos::ScopedTestDeviceSettingsService device_settings_service; 5138 chromeos::ScopedTestCrosSettings cros_settings; 5139 scoped_ptr<chromeos::ScopedTestUserManager> user_manager( 5140 new chromeos::ScopedTestUserManager); 5141#endif 5142 scoped_ptr<CommandLine> command_line; 5143 base::FilePath install_dir = profile->GetPath() 5144 .AppendASCII(extensions::kInstallDirectoryName); 5145 5146 // By default, we are enabled. 5147 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM)); 5148 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>( 5149 ExtensionSystem::Get(profile.get()))-> 5150 CreateExtensionService( 5151 command_line.get(), 5152 install_dir, 5153 false); 5154 EXPECT_TRUE(service->extensions_enabled()); 5155 service->Init(); 5156 base::RunLoop().RunUntilIdle(); 5157 EXPECT_TRUE(recorder.ready()); 5158#if defined OS_CHROMEOS 5159 user_manager.reset(); 5160#endif 5161 5162 // If either the command line or pref is set, we are disabled. 5163 recorder.set_ready(false); 5164 profile.reset(new TestingProfile()); 5165 command_line->AppendSwitch(switches::kDisableExtensions); 5166 service = static_cast<extensions::TestExtensionSystem*>( 5167 ExtensionSystem::Get(profile.get()))-> 5168 CreateExtensionService( 5169 command_line.get(), 5170 install_dir, 5171 false); 5172 EXPECT_FALSE(service->extensions_enabled()); 5173 service->Init(); 5174 base::RunLoop().RunUntilIdle(); 5175 EXPECT_TRUE(recorder.ready()); 5176 5177 recorder.set_ready(false); 5178 profile.reset(new TestingProfile()); 5179 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true); 5180 service = static_cast<extensions::TestExtensionSystem*>( 5181 ExtensionSystem::Get(profile.get()))-> 5182 CreateExtensionService( 5183 command_line.get(), 5184 install_dir, 5185 false); 5186 EXPECT_FALSE(service->extensions_enabled()); 5187 service->Init(); 5188 base::RunLoop().RunUntilIdle(); 5189 EXPECT_TRUE(recorder.ready()); 5190 5191 recorder.set_ready(false); 5192 profile.reset(new TestingProfile()); 5193 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true); 5194 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM)); 5195 service = static_cast<extensions::TestExtensionSystem*>( 5196 ExtensionSystem::Get(profile.get()))-> 5197 CreateExtensionService( 5198 command_line.get(), 5199 install_dir, 5200 false); 5201 EXPECT_FALSE(service->extensions_enabled()); 5202 service->Init(); 5203 base::RunLoop().RunUntilIdle(); 5204 EXPECT_TRUE(recorder.ready()); 5205 5206 // Explicitly delete all the resources used in this test. 5207 profile.reset(); 5208 service = NULL; 5209 // Execute any pending deletion tasks. 5210 base::RunLoop().RunUntilIdle(); 5211} 5212 5213// Test loading extensions that require limited and unlimited storage quotas. 5214TEST_F(ExtensionServiceTest, StorageQuota) { 5215 InitializeEmptyExtensionService(); 5216 5217 base::FilePath extensions_path = data_dir().AppendASCII("storage_quota"); 5218 5219 base::FilePath limited_quota_ext = 5220 extensions_path.AppendASCII("limited_quota") 5221 .AppendASCII("1.0"); 5222 5223 // The old permission name for unlimited quota was "unlimited_storage", but 5224 // we changed it to "unlimitedStorage". This tests both versions. 5225 base::FilePath unlimited_quota_ext = 5226 extensions_path.AppendASCII("unlimited_quota") 5227 .AppendASCII("1.0"); 5228 base::FilePath unlimited_quota_ext2 = 5229 extensions_path.AppendASCII("unlimited_quota") 5230 .AppendASCII("2.0"); 5231 extensions::UnpackedInstaller::Create(service())->Load(limited_quota_ext); 5232 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext); 5233 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext2); 5234 base::RunLoop().RunUntilIdle(); 5235 5236 ASSERT_EQ(3u, loaded_.size()); 5237 EXPECT_TRUE(profile()); 5238 EXPECT_FALSE(profile()->IsOffTheRecord()); 5239 EXPECT_FALSE( 5240 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 5241 loaded_[0]->url())); 5242 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 5243 loaded_[1]->url())); 5244 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited( 5245 loaded_[2]->url())); 5246} 5247 5248// Tests ComponentLoader::Add(). 5249TEST_F(ExtensionServiceTest, ComponentExtensions) { 5250 InitializeEmptyExtensionService(); 5251 5252 // Component extensions should work even when extensions are disabled. 5253 service()->set_extensions_enabled(false); 5254 5255 base::FilePath path = data_dir() 5256 .AppendASCII("good") 5257 .AppendASCII("Extensions") 5258 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 5259 .AppendASCII("1.0.0.0"); 5260 5261 std::string manifest; 5262 ASSERT_TRUE(base::ReadFileToString( 5263 path.Append(extensions::kManifestFilename), &manifest)); 5264 5265 service()->component_loader()->Add(manifest, path); 5266 service()->Init(); 5267 5268 // Note that we do not pump messages -- the extension should be loaded 5269 // immediately. 5270 5271 EXPECT_EQ(0u, GetErrors().size()); 5272 ASSERT_EQ(1u, loaded_.size()); 5273 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location()); 5274 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 5275 5276 // Component extensions get a prefs entry on first install. 5277 ValidatePrefKeyCount(1); 5278 5279 // Reload all extensions, and make sure it comes back. 5280 std::string extension_id = (*registry()->enabled_extensions().begin())->id(); 5281 loaded_.clear(); 5282 service()->ReloadExtensionsForTest(); 5283 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 5284 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id()); 5285} 5286 5287TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) { 5288 InitializeEmptyExtensionService(); 5289 InitializeExtensionSyncService(); 5290 5291 bool flare_was_called = false; 5292 syncer::ModelType triggered_type(syncer::UNSPECIFIED); 5293 base::WeakPtrFactory<ExtensionServiceTest> factory(this); 5294 extension_sync_service()->SetSyncStartFlare( 5295 base::Bind(&ExtensionServiceTest::MockSyncStartFlare, 5296 factory.GetWeakPtr(), 5297 &flare_was_called, // Safe due to WeakPtrFactory scope. 5298 &triggered_type)); // Safe due to WeakPtrFactory scope. 5299 5300 // Install a component extension. 5301 std::string manifest; 5302 ASSERT_TRUE(base::ReadFileToString( 5303 good0_path().Append(extensions::kManifestFilename), &manifest)); 5304 service()->component_loader()->Add(manifest, good0_path()); 5305 ASSERT_FALSE(service()->is_ready()); 5306 service()->Init(); 5307 ASSERT_TRUE(service()->is_ready()); 5308 5309 // Extensions added before service is_ready() don't trigger sync startup. 5310 EXPECT_FALSE(flare_was_called); 5311 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type); 5312} 5313 5314TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) { 5315 InitializeGoodInstalledExtensionService(); 5316 InitializeExtensionSyncService(); 5317 5318 bool flare_was_called = false; 5319 syncer::ModelType triggered_type(syncer::UNSPECIFIED); 5320 base::WeakPtrFactory<ExtensionServiceTest> factory(this); 5321 extension_sync_service()->SetSyncStartFlare( 5322 base::Bind(&ExtensionServiceTest::MockSyncStartFlare, 5323 factory.GetWeakPtr(), 5324 &flare_was_called, // Safe due to WeakPtrFactory scope. 5325 &triggered_type)); // Safe due to WeakPtrFactory scope. 5326 5327 ASSERT_FALSE(service()->is_ready()); 5328 service()->Init(); 5329 ASSERT_EQ(3u, loaded_.size()); 5330 ASSERT_TRUE(service()->is_ready()); 5331 5332 // Extensions added before service is_ready() don't trigger sync startup. 5333 EXPECT_FALSE(flare_was_called); 5334 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type); 5335} 5336 5337TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) { 5338 InitializeEmptyExtensionService(); 5339 InitializeExtensionSyncService(); 5340 service()->Init(); 5341 ASSERT_TRUE(service()->is_ready()); 5342 5343 bool flare_was_called = false; 5344 syncer::ModelType triggered_type(syncer::UNSPECIFIED); 5345 base::WeakPtrFactory<ExtensionServiceTest> factory(this); 5346 extension_sync_service()->SetSyncStartFlare( 5347 base::Bind(&ExtensionServiceTest::MockSyncStartFlare, 5348 factory.GetWeakPtr(), 5349 &flare_was_called, // Safe due to WeakPtrFactory scope. 5350 &triggered_type)); // Safe due to WeakPtrFactory scope. 5351 5352 base::FilePath path = data_dir().AppendASCII("good.crx"); 5353 InstallCRX(path, INSTALL_NEW); 5354 5355 EXPECT_TRUE(flare_was_called); 5356 EXPECT_EQ(syncer::EXTENSIONS, triggered_type); 5357 5358 // Reset. 5359 flare_was_called = false; 5360 triggered_type = syncer::UNSPECIFIED; 5361 5362 // Once sync starts, flare should no longer be invoked. 5363 extension_sync_service()->MergeDataAndStartSyncing( 5364 syncer::EXTENSIONS, 5365 syncer::SyncDataList(), 5366 scoped_ptr<syncer::SyncChangeProcessor>( 5367 new syncer::FakeSyncChangeProcessor), 5368 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5369 path = data_dir().AppendASCII("page_action.crx"); 5370 InstallCRX(path, INSTALL_NEW); 5371 EXPECT_FALSE(flare_was_called); 5372 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type); 5373} 5374 5375TEST_F(ExtensionServiceTest, DisableExtensionFromSync) { 5376 // Start the extensions service with one external extension already installed. 5377 base::FilePath source_install_dir = 5378 data_dir().AppendASCII("good").AppendASCII("Extensions"); 5379 base::FilePath pref_path = 5380 source_install_dir.DirName().Append(chrome::kPreferencesFilename); 5381 5382 InitializeInstalledExtensionService(pref_path, source_install_dir); 5383 InitializeExtensionSyncService(); 5384 5385 // The user has enabled sync. 5386 ProfileSyncService* sync_service = 5387 ProfileSyncServiceFactory::GetForProfile(profile()); 5388 sync_service->SetSyncSetupCompleted(); 5389 5390 service()->Init(); 5391 ASSERT_TRUE(service()->is_ready()); 5392 5393 ASSERT_EQ(3u, loaded_.size()); 5394 5395 // We start enabled. 5396 const Extension* extension = service()->GetExtensionById(good0, true); 5397 ASSERT_TRUE(extension); 5398 ASSERT_TRUE(service()->IsExtensionEnabled(good0)); 5399 extensions::ExtensionSyncData disable_good_crx( 5400 *extension, false, false, false); 5401 5402 // Then sync data arrives telling us to disable |good0|. 5403 syncer::SyncDataList sync_data; 5404 sync_data.push_back(disable_good_crx.GetSyncData()); 5405 extension_sync_service()->MergeDataAndStartSyncing( 5406 syncer::EXTENSIONS, 5407 sync_data, 5408 scoped_ptr<syncer::SyncChangeProcessor>( 5409 new syncer::FakeSyncChangeProcessor), 5410 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5411 ASSERT_FALSE(service()->IsExtensionEnabled(good0)); 5412} 5413 5414TEST_F(ExtensionServiceTest, DontDisableExtensionWithPendingEnableFromSync) { 5415 // Start the extensions service with one external extension already installed. 5416 base::FilePath source_install_dir = 5417 data_dir().AppendASCII("good").AppendASCII("Extensions"); 5418 base::FilePath pref_path = 5419 source_install_dir.DirName().Append(chrome::kPreferencesFilename); 5420 5421 InitializeInstalledExtensionService(pref_path, source_install_dir); 5422 InitializeExtensionSyncService(); 5423 5424 // The user has enabled sync. 5425 ProfileSyncService* sync_service = 5426 ProfileSyncServiceFactory::GetForProfile(profile()); 5427 sync_service->SetSyncSetupCompleted(); 5428 5429 service()->Init(); 5430 ASSERT_TRUE(service()->is_ready()); 5431 ASSERT_EQ(3u, loaded_.size()); 5432 5433 const Extension* extension = service()->GetExtensionById(good0, true); 5434 ASSERT_TRUE(service()->IsExtensionEnabled(good0)); 5435 5436 // Disable extension before first sync data arrives. 5437 service()->DisableExtension(good0, Extension::DISABLE_USER_ACTION); 5438 ASSERT_FALSE(service()->IsExtensionEnabled(good0)); 5439 5440 // Enable extension - this is now the most recent state. 5441 service()->EnableExtension(good0); 5442 ASSERT_TRUE(service()->IsExtensionEnabled(good0)); 5443 5444 // Now sync data comes in that says to disable good0. This should be 5445 // ignored. 5446 extensions::ExtensionSyncData disable_good_crx( 5447 *extension, false, false, false); 5448 syncer::SyncDataList sync_data; 5449 sync_data.push_back(disable_good_crx.GetSyncData()); 5450 extension_sync_service()->MergeDataAndStartSyncing( 5451 syncer::EXTENSIONS, 5452 sync_data, 5453 scoped_ptr<syncer::SyncChangeProcessor>( 5454 new syncer::FakeSyncChangeProcessor), 5455 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5456 5457 // The extension was enabled locally before the sync data arrived, so it 5458 // should still be enabled now. 5459 ASSERT_TRUE(service()->IsExtensionEnabled(good0)); 5460} 5461 5462TEST_F(ExtensionServiceTest, GetSyncData) { 5463 InitializeEmptyExtensionService(); 5464 InitializeExtensionSyncService(); 5465 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 5466 const Extension* extension = service()->GetInstalledExtension(good_crx); 5467 ASSERT_TRUE(extension); 5468 5469 extension_sync_service()->MergeDataAndStartSyncing( 5470 syncer::EXTENSIONS, 5471 syncer::SyncDataList(), 5472 scoped_ptr<syncer::SyncChangeProcessor>( 5473 new syncer::FakeSyncChangeProcessor), 5474 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5475 5476 syncer::SyncDataList list = 5477 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS); 5478 ASSERT_EQ(list.size(), 1U); 5479 extensions::ExtensionSyncData data(list[0]); 5480 EXPECT_EQ(extension->id(), data.id()); 5481 EXPECT_FALSE(data.uninstalled()); 5482 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data.enabled()); 5483 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()), 5484 data.incognito_enabled()); 5485 EXPECT_TRUE(data.version().Equals(*extension->version())); 5486 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension), 5487 data.update_url()); 5488 EXPECT_EQ(extension->name(), data.name()); 5489} 5490 5491TEST_F(ExtensionServiceTest, GetSyncDataTerminated) { 5492 InitializeEmptyExtensionService(); 5493 InitializeExtensionSyncService(); 5494 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 5495 TerminateExtension(good_crx); 5496 const Extension* extension = service()->GetInstalledExtension(good_crx); 5497 ASSERT_TRUE(extension); 5498 5499 syncer::FakeSyncChangeProcessor processor; 5500 extension_sync_service()->MergeDataAndStartSyncing( 5501 syncer::EXTENSIONS, 5502 syncer::SyncDataList(), 5503 scoped_ptr<syncer::SyncChangeProcessor>( 5504 new syncer::FakeSyncChangeProcessor), 5505 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5506 5507 syncer::SyncDataList list = 5508 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS); 5509 ASSERT_EQ(list.size(), 1U); 5510 extensions::ExtensionSyncData data(list[0]); 5511 EXPECT_EQ(extension->id(), data.id()); 5512 EXPECT_FALSE(data.uninstalled()); 5513 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data.enabled()); 5514 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()), 5515 data.incognito_enabled()); 5516 EXPECT_TRUE(data.version().Equals(*extension->version())); 5517 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension), 5518 data.update_url()); 5519 EXPECT_EQ(extension->name(), data.name()); 5520} 5521 5522TEST_F(ExtensionServiceTest, GetSyncDataFilter) { 5523 InitializeEmptyExtensionService(); 5524 InitializeExtensionSyncService(); 5525 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 5526 const Extension* extension = service()->GetInstalledExtension(good_crx); 5527 ASSERT_TRUE(extension); 5528 5529 syncer::FakeSyncChangeProcessor processor; 5530 extension_sync_service()->MergeDataAndStartSyncing( 5531 syncer::APPS, 5532 syncer::SyncDataList(), 5533 scoped_ptr<syncer::SyncChangeProcessor>( 5534 new syncer::FakeSyncChangeProcessor), 5535 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5536 5537 syncer::SyncDataList list = 5538 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS); 5539 ASSERT_EQ(list.size(), 0U); 5540} 5541 5542TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) { 5543 InitializeEmptyExtensionService(); 5544 InitializeProcessManager(); 5545 InitializeExtensionSyncService(); 5546 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 5547 const Extension* extension = service()->GetInstalledExtension(good_crx); 5548 ASSERT_TRUE(extension); 5549 5550 syncer::FakeSyncChangeProcessor processor; 5551 extension_sync_service()->MergeDataAndStartSyncing( 5552 syncer::EXTENSIONS, 5553 syncer::SyncDataList(), 5554 scoped_ptr<syncer::SyncChangeProcessor>( 5555 new syncer::FakeSyncChangeProcessor), 5556 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5557 5558 { 5559 syncer::SyncDataList list = 5560 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS); 5561 ASSERT_EQ(list.size(), 1U); 5562 extensions::ExtensionSyncData data(list[0]); 5563 EXPECT_TRUE(data.enabled()); 5564 EXPECT_FALSE(data.incognito_enabled()); 5565 } 5566 5567 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION); 5568 { 5569 syncer::SyncDataList list = 5570 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS); 5571 ASSERT_EQ(list.size(), 1U); 5572 extensions::ExtensionSyncData data(list[0]); 5573 EXPECT_FALSE(data.enabled()); 5574 EXPECT_FALSE(data.incognito_enabled()); 5575 } 5576 5577 extensions::util::SetIsIncognitoEnabled(good_crx, profile(), true); 5578 { 5579 syncer::SyncDataList list = 5580 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS); 5581 ASSERT_EQ(list.size(), 1U); 5582 extensions::ExtensionSyncData data(list[0]); 5583 EXPECT_FALSE(data.enabled()); 5584 EXPECT_TRUE(data.incognito_enabled()); 5585 } 5586 5587 service()->EnableExtension(good_crx); 5588 { 5589 syncer::SyncDataList list = 5590 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS); 5591 ASSERT_EQ(list.size(), 1U); 5592 extensions::ExtensionSyncData data(list[0]); 5593 EXPECT_TRUE(data.enabled()); 5594 EXPECT_TRUE(data.incognito_enabled()); 5595 } 5596} 5597 5598TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) { 5599 InitializeEmptyExtensionService(); 5600 InitializeExtensionSyncService(); 5601 InstallCRXWithLocation( 5602 data_dir().AppendASCII("good.crx"), Manifest::EXTERNAL_PREF, INSTALL_NEW); 5603 const Extension* extension = service()->GetInstalledExtension(good_crx); 5604 ASSERT_TRUE(extension); 5605 5606 syncer::FakeSyncChangeProcessor processor; 5607 extension_sync_service()->MergeDataAndStartSyncing( 5608 syncer::EXTENSIONS, 5609 syncer::SyncDataList(), 5610 scoped_ptr<syncer::SyncChangeProcessor>( 5611 new syncer::FakeSyncChangeProcessor), 5612 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5613 5614 UninstallExtension(good_crx, false); 5615 EXPECT_TRUE( 5616 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx)); 5617 5618 sync_pb::EntitySpecifics specifics; 5619 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app(); 5620 sync_pb::ExtensionSpecifics* extension_specifics = 5621 app_specifics->mutable_extension(); 5622 extension_specifics->set_id(good_crx); 5623 extension_specifics->set_version("1.0"); 5624 extension_specifics->set_enabled(true); 5625 5626 syncer::SyncData sync_data = 5627 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 5628 syncer::SyncChange sync_change(FROM_HERE, 5629 syncer::SyncChange::ACTION_UPDATE, 5630 sync_data); 5631 syncer::SyncChangeList list(1); 5632 list[0] = sync_change; 5633 5634 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 5635 EXPECT_TRUE( 5636 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx)); 5637} 5638 5639TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) { 5640 InitializeEmptyExtensionService(); 5641 InitializeExtensionSyncService(); 5642 const Extension* app = 5643 PackAndInstallCRX(data_dir().AppendASCII("app"), INSTALL_NEW); 5644 ASSERT_TRUE(app); 5645 ASSERT_TRUE(app->is_app()); 5646 5647 syncer::FakeSyncChangeProcessor processor; 5648 extension_sync_service()->MergeDataAndStartSyncing( 5649 syncer::APPS, 5650 syncer::SyncDataList(), 5651 scoped_ptr<syncer::SyncChangeProcessor>( 5652 new syncer::FakeSyncChangeProcessor), 5653 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5654 5655 syncer::StringOrdinal initial_ordinal = 5656 syncer::StringOrdinal::CreateInitialOrdinal(); 5657 { 5658 syncer::SyncDataList list = 5659 extension_sync_service()->GetAllSyncData(syncer::APPS); 5660 ASSERT_EQ(list.size(), 1U); 5661 5662 extensions::AppSyncData app_sync_data(list[0]); 5663 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.app_launch_ordinal())); 5664 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal())); 5665 } 5666 5667 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting(); 5668 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter()); 5669 { 5670 syncer::SyncDataList list = 5671 extension_sync_service()->GetAllSyncData(syncer::APPS); 5672 ASSERT_EQ(list.size(), 1U); 5673 5674 extensions::AppSyncData app_sync_data(list[0]); 5675 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal())); 5676 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal())); 5677 } 5678 5679 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter()); 5680 { 5681 syncer::SyncDataList list = 5682 extension_sync_service()->GetAllSyncData(syncer::APPS); 5683 ASSERT_EQ(list.size(), 1U); 5684 5685 extensions::AppSyncData app_sync_data(list[0]); 5686 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal())); 5687 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.page_ordinal())); 5688 } 5689} 5690 5691// TODO (rdevlin.cronin): The OnExtensionMoved() method has been removed from 5692// ExtensionService, so this test probably needs a new home. Unfortunately, it 5693// relies pretty heavily on things like InitializeExtension[Sync]Service() and 5694// PackAndInstallCRX(). When we clean up a bit more, this should move out. 5695TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) { 5696 InitializeEmptyExtensionService(); 5697 InitializeExtensionSyncService(); 5698 const size_t kAppCount = 3; 5699 const Extension* apps[kAppCount]; 5700 apps[0] = PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW); 5701 apps[1] = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW); 5702 apps[2] = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW); 5703 for (size_t i = 0; i < kAppCount; ++i) { 5704 ASSERT_TRUE(apps[i]); 5705 ASSERT_TRUE(apps[i]->is_app()); 5706 } 5707 5708 syncer::FakeSyncChangeProcessor processor; 5709 extension_sync_service()->MergeDataAndStartSyncing( 5710 syncer::APPS, 5711 syncer::SyncDataList(), 5712 scoped_ptr<syncer::SyncChangeProcessor>( 5713 new syncer::FakeSyncChangeProcessor), 5714 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5715 5716 ExtensionPrefs::Get(service()->GetBrowserContext()) 5717 ->app_sorting() 5718 ->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id()); 5719 { 5720 syncer::SyncDataList list = 5721 extension_sync_service()->GetAllSyncData(syncer::APPS); 5722 ASSERT_EQ(list.size(), 3U); 5723 5724 extensions::AppSyncData data[kAppCount]; 5725 for (size_t i = 0; i < kAppCount; ++i) { 5726 data[i] = extensions::AppSyncData(list[i]); 5727 } 5728 5729 // The sync data is not always in the same order our apps were installed in, 5730 // so we do that sorting here so we can make sure the values are changed as 5731 // expected. 5732 syncer::StringOrdinal app_launch_ordinals[kAppCount]; 5733 for (size_t i = 0; i < kAppCount; ++i) { 5734 for (size_t j = 0; j < kAppCount; ++j) { 5735 if (apps[i]->id() == data[j].id()) 5736 app_launch_ordinals[i] = data[j].app_launch_ordinal(); 5737 } 5738 } 5739 5740 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0])); 5741 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2])); 5742 } 5743} 5744 5745TEST_F(ExtensionServiceTest, GetSyncDataList) { 5746 InitializeEmptyExtensionService(); 5747 InitializeExtensionSyncService(); 5748 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 5749 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW); 5750 InstallCRX(data_dir().AppendASCII("theme.crx"), INSTALL_NEW); 5751 InstallCRX(data_dir().AppendASCII("theme2.crx"), INSTALL_NEW); 5752 5753 syncer::FakeSyncChangeProcessor processor; 5754 extension_sync_service()->MergeDataAndStartSyncing( 5755 syncer::APPS, 5756 syncer::SyncDataList(), 5757 scoped_ptr<syncer::SyncChangeProcessor>( 5758 new syncer::FakeSyncChangeProcessor), 5759 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5760 extension_sync_service()->MergeDataAndStartSyncing( 5761 syncer::EXTENSIONS, 5762 syncer::SyncDataList(), 5763 scoped_ptr<syncer::SyncChangeProcessor>( 5764 new syncer::FakeSyncChangeProcessor), 5765 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5766 5767 service()->DisableExtension(page_action, Extension::DISABLE_USER_ACTION); 5768 TerminateExtension(theme2_crx); 5769 5770 EXPECT_EQ(0u, extension_sync_service()->GetAllSyncData(syncer::APPS).size()); 5771 EXPECT_EQ( 5772 2u, extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS).size()); 5773} 5774 5775TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) { 5776 InitializeEmptyExtensionService(); 5777 InitializeExtensionSyncService(); 5778 syncer::FakeSyncChangeProcessor processor; 5779 extension_sync_service()->MergeDataAndStartSyncing( 5780 syncer::EXTENSIONS, 5781 syncer::SyncDataList(), 5782 scoped_ptr<syncer::SyncChangeProcessor>( 5783 new syncer::FakeSyncChangeProcessor), 5784 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5785 5786 sync_pb::EntitySpecifics specifics; 5787 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension(); 5788 ext_specifics->set_id(good_crx); 5789 ext_specifics->set_version("1.0"); 5790 syncer::SyncData sync_data = 5791 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 5792 syncer::SyncChange sync_change(FROM_HERE, 5793 syncer::SyncChange::ACTION_DELETE, 5794 sync_data); 5795 syncer::SyncChangeList list(1); 5796 list[0] = sync_change; 5797 5798 // Should do nothing. 5799 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 5800 EXPECT_FALSE(service()->GetExtensionById(good_crx, true)); 5801 5802 // Install the extension. 5803 base::FilePath extension_path = data_dir().AppendASCII("good.crx"); 5804 InstallCRX(extension_path, INSTALL_NEW); 5805 EXPECT_TRUE(service()->GetExtensionById(good_crx, true)); 5806 5807 // Should uninstall the extension. 5808 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 5809 EXPECT_FALSE(service()->GetExtensionById(good_crx, true)); 5810 5811 // Should again do nothing. 5812 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 5813 EXPECT_FALSE(service()->GetExtensionById(good_crx, true)); 5814} 5815 5816TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) { 5817 InitializeEmptyExtensionService(); 5818 InitializeExtensionSyncService(); 5819 5820 // Install the extension. 5821 base::FilePath extension_path = data_dir().AppendASCII("good.crx"); 5822 InstallCRX(extension_path, INSTALL_NEW); 5823 EXPECT_TRUE(service()->GetExtensionById(good_crx, true)); 5824 5825 sync_pb::EntitySpecifics specifics; 5826 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app(); 5827 sync_pb::ExtensionSpecifics* extension_specifics = 5828 app_specifics->mutable_extension(); 5829 extension_specifics->set_id(good_crx); 5830 extension_specifics->set_version( 5831 service()->GetInstalledExtension(good_crx)->version()->GetString()); 5832 5833 { 5834 extension_specifics->set_enabled(true); 5835 syncer::SyncData sync_data = 5836 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 5837 syncer::SyncChange sync_change(FROM_HERE, 5838 syncer::SyncChange::ACTION_DELETE, 5839 sync_data); 5840 syncer::SyncChangeList list(1); 5841 list[0] = sync_change; 5842 5843 // Should do nothing 5844 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 5845 EXPECT_TRUE(service()->GetExtensionById(good_crx, true)); 5846 } 5847 5848 { 5849 extension_specifics->set_enabled(false); 5850 syncer::SyncData sync_data = 5851 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 5852 syncer::SyncChange sync_change(FROM_HERE, 5853 syncer::SyncChange::ACTION_UPDATE, 5854 sync_data); 5855 syncer::SyncChangeList list(1); 5856 list[0] = sync_change; 5857 5858 // Should again do nothing. 5859 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 5860 EXPECT_TRUE(service()->GetExtensionById(good_crx, false)); 5861 } 5862} 5863 5864TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) { 5865 InitializeEmptyExtensionService(); 5866 InitializeProcessManager(); 5867 InitializeExtensionSyncService(); 5868 syncer::FakeSyncChangeProcessor processor; 5869 extension_sync_service()->MergeDataAndStartSyncing( 5870 syncer::EXTENSIONS, 5871 syncer::SyncDataList(), 5872 scoped_ptr<syncer::SyncChangeProcessor>( 5873 new syncer::FakeSyncChangeProcessor), 5874 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5875 5876 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 5877 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx)); 5878 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile())); 5879 5880 sync_pb::EntitySpecifics specifics; 5881 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension(); 5882 ext_specifics->set_id(good_crx); 5883 ext_specifics->set_version( 5884 service()->GetInstalledExtension(good_crx)->version()->GetString()); 5885 ext_specifics->set_enabled(false); 5886 5887 { 5888 syncer::SyncData sync_data = 5889 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 5890 syncer::SyncChange sync_change(FROM_HERE, 5891 syncer::SyncChange::ACTION_UPDATE, 5892 sync_data); 5893 syncer::SyncChangeList list(1); 5894 list[0] = sync_change; 5895 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 5896 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx)); 5897 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile())); 5898 } 5899 5900 { 5901 ext_specifics->set_enabled(true); 5902 ext_specifics->set_incognito_enabled(true); 5903 syncer::SyncData sync_data = 5904 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 5905 syncer::SyncChange sync_change(FROM_HERE, 5906 syncer::SyncChange::ACTION_UPDATE, 5907 sync_data); 5908 syncer::SyncChangeList list(1); 5909 list[0] = sync_change; 5910 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 5911 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx)); 5912 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile())); 5913 } 5914 5915 { 5916 ext_specifics->set_enabled(false); 5917 ext_specifics->set_incognito_enabled(true); 5918 syncer::SyncData sync_data = 5919 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 5920 syncer::SyncChange sync_change(FROM_HERE, 5921 syncer::SyncChange::ACTION_UPDATE, 5922 sync_data); 5923 syncer::SyncChangeList list(1); 5924 list[0] = sync_change; 5925 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 5926 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx)); 5927 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile())); 5928 } 5929 5930 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx)); 5931} 5932 5933TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) { 5934 InitializeExtensionServiceWithUpdater(); 5935 InitializeExtensionSyncService(); 5936 syncer::FakeSyncChangeProcessor processor; 5937 extension_sync_service()->MergeDataAndStartSyncing( 5938 syncer::EXTENSIONS, 5939 syncer::SyncDataList(), 5940 scoped_ptr<syncer::SyncChangeProcessor>( 5941 new syncer::FakeSyncChangeProcessor), 5942 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5943 5944 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 5945 TerminateExtension(good_crx); 5946 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx)); 5947 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile())); 5948 5949 sync_pb::EntitySpecifics specifics; 5950 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension(); 5951 ext_specifics->set_id(good_crx); 5952 ext_specifics->set_version( 5953 service()->GetInstalledExtension(good_crx)->version()->GetString()); 5954 ext_specifics->set_enabled(false); 5955 ext_specifics->set_incognito_enabled(true); 5956 syncer::SyncData sync_data = 5957 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 5958 syncer::SyncChange sync_change(FROM_HERE, 5959 syncer::SyncChange::ACTION_UPDATE, 5960 sync_data); 5961 syncer::SyncChangeList list(1); 5962 list[0] = sync_change; 5963 5964 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 5965 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx)); 5966 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile())); 5967 5968 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx)); 5969} 5970 5971TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) { 5972 InitializeExtensionServiceWithUpdater(); 5973 InitializeExtensionSyncService(); 5974 syncer::FakeSyncChangeProcessor processor; 5975 extension_sync_service()->MergeDataAndStartSyncing( 5976 syncer::EXTENSIONS, 5977 syncer::SyncDataList(), 5978 scoped_ptr<syncer::SyncChangeProcessor>( 5979 new syncer::FakeSyncChangeProcessor), 5980 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 5981 5982 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 5983 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx)); 5984 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile())); 5985 5986 sync_pb::EntitySpecifics specifics; 5987 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension(); 5988 ext_specifics->set_id(good_crx); 5989 ext_specifics->set_enabled(true); 5990 5991 { 5992 ext_specifics->set_version( 5993 service()->GetInstalledExtension(good_crx)->version()->GetString()); 5994 syncer::SyncData sync_data = 5995 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 5996 syncer::SyncChange sync_change(FROM_HERE, 5997 syncer::SyncChange::ACTION_UPDATE, 5998 sync_data); 5999 syncer::SyncChangeList list(1); 6000 list[0] = sync_change; 6001 6002 // Should do nothing if extension version == sync version. 6003 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 6004 EXPECT_FALSE(service()->updater()->WillCheckSoon()); 6005 } 6006 6007 // Should do nothing if extension version > sync version (but see 6008 // the TODO in ProcessExtensionSyncData). 6009 { 6010 ext_specifics->set_version("0.0.0.0"); 6011 syncer::SyncData sync_data = 6012 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 6013 syncer::SyncChange sync_change(FROM_HERE, 6014 syncer::SyncChange::ACTION_UPDATE, 6015 sync_data); 6016 syncer::SyncChangeList list(1); 6017 list[0] = sync_change; 6018 6019 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 6020 EXPECT_FALSE(service()->updater()->WillCheckSoon()); 6021 } 6022 6023 // Should kick off an update if extension version < sync version. 6024 { 6025 ext_specifics->set_version("9.9.9.9"); 6026 syncer::SyncData sync_data = 6027 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 6028 syncer::SyncChange sync_change(FROM_HERE, 6029 syncer::SyncChange::ACTION_UPDATE, 6030 sync_data); 6031 syncer::SyncChangeList list(1); 6032 list[0] = sync_change; 6033 6034 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 6035 EXPECT_TRUE(service()->updater()->WillCheckSoon()); 6036 } 6037 6038 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx)); 6039} 6040 6041TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) { 6042 InitializeExtensionServiceWithUpdater(); 6043 InitializeExtensionSyncService(); 6044 syncer::FakeSyncChangeProcessor processor; 6045 extension_sync_service()->MergeDataAndStartSyncing( 6046 syncer::EXTENSIONS, 6047 syncer::SyncDataList(), 6048 scoped_ptr<syncer::SyncChangeProcessor>( 6049 new syncer::FakeSyncChangeProcessor), 6050 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock())); 6051 6052 sync_pb::EntitySpecifics specifics; 6053 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension(); 6054 ext_specifics->set_id(good_crx); 6055 ext_specifics->set_enabled(false); 6056 ext_specifics->set_incognito_enabled(true); 6057 ext_specifics->set_update_url("http://www.google.com/"); 6058 ext_specifics->set_version("1.2.3.4"); 6059 syncer::SyncData sync_data = 6060 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics); 6061 syncer::SyncChange sync_change(FROM_HERE, 6062 syncer::SyncChange::ACTION_UPDATE, 6063 sync_data); 6064 syncer::SyncChangeList list(1); 6065 list[0] = sync_change; 6066 6067 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx)); 6068 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile())); 6069 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list); 6070 EXPECT_TRUE(service()->updater()->WillCheckSoon()); 6071 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx)); 6072 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile())); 6073 6074 const extensions::PendingExtensionInfo* info; 6075 EXPECT_TRUE( 6076 (info = service()->pending_extension_manager()->GetById(good_crx))); 6077 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec()); 6078 EXPECT_TRUE(info->is_from_sync()); 6079 EXPECT_TRUE(info->install_silently()); 6080 EXPECT_EQ(Manifest::INTERNAL, info->install_source()); 6081 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|. 6082} 6083 6084TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) { 6085 InitializeEmptyExtensionService(); 6086 6087 base::FilePath path = data_dir().AppendASCII("good.crx"); 6088 InstallCRX(path, INSTALL_NEW); 6089 ValidatePrefKeyCount(1u); 6090 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 6091 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL); 6092 6093 extensions::PendingExtensionManager* pending = 6094 service()->pending_extension_manager(); 6095 EXPECT_FALSE(pending->IsIdPending(kGoodId)); 6096 6097 // Skip install when the location is the same. 6098 EXPECT_FALSE( 6099 service()->OnExternalExtensionUpdateUrlFound(kGoodId, 6100 std::string(), 6101 GURL(kGoodUpdateURL), 6102 Manifest::INTERNAL, 6103 Extension::NO_FLAGS, 6104 false)); 6105 EXPECT_FALSE(pending->IsIdPending(kGoodId)); 6106 6107 // Install when the location has higher priority. 6108 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound( 6109 kGoodId, 6110 std::string(), 6111 GURL(kGoodUpdateURL), 6112 Manifest::EXTERNAL_POLICY_DOWNLOAD, 6113 Extension::NO_FLAGS, 6114 false)); 6115 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6116 6117 // Try the low priority again. Should be rejected. 6118 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound( 6119 kGoodId, 6120 std::string(), 6121 GURL(kGoodUpdateURL), 6122 Manifest::EXTERNAL_PREF_DOWNLOAD, 6123 Extension::NO_FLAGS, 6124 false)); 6125 // The existing record should still be present in the pending extension 6126 // manager. 6127 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6128 6129 pending->Remove(kGoodId); 6130 6131 // Skip install when the location has the same priority as the installed 6132 // location. 6133 EXPECT_FALSE( 6134 service()->OnExternalExtensionUpdateUrlFound(kGoodId, 6135 std::string(), 6136 GURL(kGoodUpdateURL), 6137 Manifest::INTERNAL, 6138 Extension::NO_FLAGS, 6139 false)); 6140 6141 EXPECT_FALSE(pending->IsIdPending(kGoodId)); 6142} 6143 6144TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) { 6145 Version older_version("0.1.0.0"); 6146 Version newer_version("2.0.0.0"); 6147 6148 // We don't want the extension to be installed. A path that doesn't 6149 // point to a valid CRX ensures this. 6150 const base::FilePath kInvalidPathToCrx = base::FilePath(); 6151 6152 const int kCreationFlags = 0; 6153 const bool kDontMarkAcknowledged = false; 6154 6155 InitializeEmptyExtensionService(); 6156 6157 // The test below uses install source constants to test that 6158 // priority is enforced. It assumes a specific ranking of install 6159 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref 6160 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL). 6161 // The following assertions verify these assumptions: 6162 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY, 6163 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY, 6164 Manifest::EXTERNAL_PREF)); 6165 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY, 6166 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY, 6167 Manifest::INTERNAL)); 6168 ASSERT_EQ(Manifest::EXTERNAL_PREF, 6169 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF, 6170 Manifest::INTERNAL)); 6171 6172 extensions::PendingExtensionManager* pending = 6173 service()->pending_extension_manager(); 6174 EXPECT_FALSE(pending->IsIdPending(kGoodId)); 6175 6176 { 6177 // Simulate an external source adding the extension as INTERNAL. 6178 content::WindowedNotificationObserver observer( 6179 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6180 content::NotificationService::AllSources()); 6181 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId, 6182 &older_version, 6183 kInvalidPathToCrx, 6184 Manifest::INTERNAL, 6185 kCreationFlags, 6186 kDontMarkAcknowledged)); 6187 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6188 observer.Wait(); 6189 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED); 6190 } 6191 6192 { 6193 // Simulate an external source adding the extension as EXTERNAL_PREF. 6194 content::WindowedNotificationObserver observer( 6195 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6196 content::NotificationService::AllSources()); 6197 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId, 6198 &older_version, 6199 kInvalidPathToCrx, 6200 Manifest::EXTERNAL_PREF, 6201 kCreationFlags, 6202 kDontMarkAcknowledged)); 6203 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6204 observer.Wait(); 6205 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED); 6206 } 6207 6208 // Simulate an external source adding as EXTERNAL_PREF again. 6209 // This is rejected because the version and the location are the same as 6210 // the previous installation, which is still pending. 6211 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId, 6212 &older_version, 6213 kInvalidPathToCrx, 6214 Manifest::EXTERNAL_PREF, 6215 kCreationFlags, 6216 kDontMarkAcknowledged)); 6217 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6218 6219 // Try INTERNAL again. Should fail. 6220 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId, 6221 &older_version, 6222 kInvalidPathToCrx, 6223 Manifest::INTERNAL, 6224 kCreationFlags, 6225 kDontMarkAcknowledged)); 6226 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6227 6228 { 6229 // Now the registry adds the extension. 6230 content::WindowedNotificationObserver observer( 6231 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6232 content::NotificationService::AllSources()); 6233 EXPECT_TRUE( 6234 service()->OnExternalExtensionFileFound(kGoodId, 6235 &older_version, 6236 kInvalidPathToCrx, 6237 Manifest::EXTERNAL_REGISTRY, 6238 kCreationFlags, 6239 kDontMarkAcknowledged)); 6240 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6241 observer.Wait(); 6242 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED); 6243 } 6244 6245 // Registry outranks both external pref and internal, so both fail. 6246 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId, 6247 &older_version, 6248 kInvalidPathToCrx, 6249 Manifest::EXTERNAL_PREF, 6250 kCreationFlags, 6251 kDontMarkAcknowledged)); 6252 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6253 6254 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId, 6255 &older_version, 6256 kInvalidPathToCrx, 6257 Manifest::INTERNAL, 6258 kCreationFlags, 6259 kDontMarkAcknowledged)); 6260 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6261 6262 pending->Remove(kGoodId); 6263 6264 // Install the extension. 6265 base::FilePath path = data_dir().AppendASCII("good.crx"); 6266 const Extension* ext = InstallCRX(path, INSTALL_NEW); 6267 ValidatePrefKeyCount(1u); 6268 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 6269 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL); 6270 6271 // Now test the logic of OnExternalExtensionFileFound() when the extension 6272 // being added is already installed. 6273 6274 // Tests assume |older_version| is less than the installed version, and 6275 // |newer_version| is greater. Verify this: 6276 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString())); 6277 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString())); 6278 6279 // An external install for the same location should fail if the version is 6280 // older, or the same, and succeed if the version is newer. 6281 6282 // Older than the installed version... 6283 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId, 6284 &older_version, 6285 kInvalidPathToCrx, 6286 Manifest::INTERNAL, 6287 kCreationFlags, 6288 kDontMarkAcknowledged)); 6289 EXPECT_FALSE(pending->IsIdPending(kGoodId)); 6290 6291 // Same version as the installed version... 6292 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId, 6293 ext->version(), 6294 kInvalidPathToCrx, 6295 Manifest::INTERNAL, 6296 kCreationFlags, 6297 kDontMarkAcknowledged)); 6298 EXPECT_FALSE(pending->IsIdPending(kGoodId)); 6299 6300 // Newer than the installed version... 6301 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId, 6302 &newer_version, 6303 kInvalidPathToCrx, 6304 Manifest::INTERNAL, 6305 kCreationFlags, 6306 kDontMarkAcknowledged)); 6307 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6308 6309 // An external install for a higher priority install source should succeed 6310 // if the version is greater. |older_version| is not... 6311 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId, 6312 &older_version, 6313 kInvalidPathToCrx, 6314 Manifest::EXTERNAL_PREF, 6315 kCreationFlags, 6316 kDontMarkAcknowledged)); 6317 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6318 6319 // |newer_version| is newer. 6320 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId, 6321 &newer_version, 6322 kInvalidPathToCrx, 6323 Manifest::EXTERNAL_PREF, 6324 kCreationFlags, 6325 kDontMarkAcknowledged)); 6326 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6327 6328 // An external install for an even higher priority install source should 6329 // succeed if the version is greater. 6330 EXPECT_TRUE( 6331 service()->OnExternalExtensionFileFound(kGoodId, 6332 &newer_version, 6333 kInvalidPathToCrx, 6334 Manifest::EXTERNAL_REGISTRY, 6335 kCreationFlags, 6336 kDontMarkAcknowledged)); 6337 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6338 6339 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY, 6340 // adding from external pref will now fail. 6341 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId, 6342 &newer_version, 6343 kInvalidPathToCrx, 6344 Manifest::EXTERNAL_PREF, 6345 kCreationFlags, 6346 kDontMarkAcknowledged)); 6347 EXPECT_TRUE(pending->IsIdPending(kGoodId)); 6348} 6349 6350TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) { 6351 Version kVersion123("1.2.3"); 6352 Version kVersion124("1.2.4"); 6353 Version kVersion125("1.2.5"); 6354 const base::FilePath kInvalidPathToCrx = base::FilePath(); 6355 const int kCreationFlags = 0; 6356 const bool kDontMarkAcknowledged = false; 6357 6358 InitializeEmptyExtensionService(); 6359 6360 extensions::PendingExtensionManager* pending = 6361 service()->pending_extension_manager(); 6362 EXPECT_FALSE(pending->IsIdPending(kGoodId)); 6363 6364 // An external provider starts installing from a local crx. 6365 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId, 6366 &kVersion123, 6367 kInvalidPathToCrx, 6368 Manifest::EXTERNAL_PREF, 6369 kCreationFlags, 6370 kDontMarkAcknowledged)); 6371 const extensions::PendingExtensionInfo* info; 6372 EXPECT_TRUE((info = pending->GetById(kGoodId))); 6373 EXPECT_TRUE(info->version().IsValid()); 6374 EXPECT_TRUE(info->version().Equals(kVersion123)); 6375 6376 // Adding a newer version overrides the currently pending version. 6377 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId, 6378 &kVersion124, 6379 kInvalidPathToCrx, 6380 Manifest::EXTERNAL_PREF, 6381 kCreationFlags, 6382 kDontMarkAcknowledged)); 6383 EXPECT_TRUE((info = pending->GetById(kGoodId))); 6384 EXPECT_TRUE(info->version().IsValid()); 6385 EXPECT_TRUE(info->version().Equals(kVersion124)); 6386 6387 // Adding an older version fails. 6388 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId, 6389 &kVersion123, 6390 kInvalidPathToCrx, 6391 Manifest::EXTERNAL_PREF, 6392 kCreationFlags, 6393 kDontMarkAcknowledged)); 6394 EXPECT_TRUE((info = pending->GetById(kGoodId))); 6395 EXPECT_TRUE(info->version().IsValid()); 6396 EXPECT_TRUE(info->version().Equals(kVersion124)); 6397 6398 // Adding an older version fails even when coming from a higher-priority 6399 // location. 6400 EXPECT_FALSE( 6401 service()->OnExternalExtensionFileFound(kGoodId, 6402 &kVersion123, 6403 kInvalidPathToCrx, 6404 Manifest::EXTERNAL_REGISTRY, 6405 kCreationFlags, 6406 kDontMarkAcknowledged)); 6407 EXPECT_TRUE((info = pending->GetById(kGoodId))); 6408 EXPECT_TRUE(info->version().IsValid()); 6409 EXPECT_TRUE(info->version().Equals(kVersion124)); 6410 6411 // Adding the latest version from the webstore overrides a specific version. 6412 GURL kUpdateUrl("http://example.com/update"); 6413 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound( 6414 kGoodId, 6415 std::string(), 6416 kUpdateUrl, 6417 Manifest::EXTERNAL_POLICY_DOWNLOAD, 6418 Extension::NO_FLAGS, 6419 false)); 6420 EXPECT_TRUE((info = pending->GetById(kGoodId))); 6421 EXPECT_FALSE(info->version().IsValid()); 6422} 6423 6424// This makes sure we can package and install CRX files that use whitelisted 6425// permissions. 6426TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) { 6427 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk"; 6428 CommandLine::ForCurrentProcess()->AppendSwitchASCII( 6429 extensions::switches::kWhitelistedExtensionID, test_id); 6430 6431 InitializeEmptyExtensionService(); 6432 base::FilePath path = data_dir().AppendASCII("permissions"); 6433 base::FilePath pem_path = path 6434 .AppendASCII("whitelist.pem"); 6435 path = path 6436 .AppendASCII("whitelist"); 6437 6438 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW); 6439 EXPECT_EQ(0u, GetErrors().size()); 6440 ASSERT_EQ(1u, registry()->enabled_extensions().size()); 6441 EXPECT_EQ(test_id, extension->id()); 6442} 6443 6444// Test that when multiple sources try to install an extension, 6445// we consistently choose the right one. To make tests easy to read, 6446// methods that fake requests to install crx files in several ways 6447// are provided. 6448class ExtensionSourcePriorityTest : public ExtensionServiceTest { 6449 public: 6450 virtual void SetUp() { 6451 ExtensionServiceTest::SetUp(); 6452 6453 // All tests use a single extension. Put the id and path in member vars 6454 // that all methods can read. 6455 crx_id_ = kGoodId; 6456 crx_path_ = data_dir().AppendASCII("good.crx"); 6457 } 6458 6459 // Fake an external source adding a URL to fetch an extension from. 6460 bool AddPendingExternalPrefUrl() { 6461 return service()->pending_extension_manager()->AddFromExternalUpdateUrl( 6462 crx_id_, 6463 std::string(), 6464 GURL(), 6465 Manifest::EXTERNAL_PREF_DOWNLOAD, 6466 Extension::NO_FLAGS, 6467 false); 6468 } 6469 6470 // Fake an external file from external_extensions.json. 6471 bool AddPendingExternalPrefFileInstall() { 6472 Version version("1.0.0.0"); 6473 6474 return service()->OnExternalExtensionFileFound(crx_id_, 6475 &version, 6476 crx_path_, 6477 Manifest::EXTERNAL_PREF, 6478 Extension::NO_FLAGS, 6479 false); 6480 } 6481 6482 // Fake a request from sync to install an extension. 6483 bool AddPendingSyncInstall() { 6484 return service()->pending_extension_manager()->AddFromSync( 6485 crx_id_, 6486 GURL(kGoodUpdateURL), 6487 &IsExtension, 6488 kGoodInstallSilently, 6489 kGoodRemoteInstall, 6490 kGoodInstalledByCustodian); 6491 } 6492 6493 // Fake a policy install. 6494 bool AddPendingPolicyInstall() { 6495 // Get path to the CRX with id |kGoodId|. 6496 return service()->OnExternalExtensionUpdateUrlFound( 6497 crx_id_, 6498 std::string(), 6499 GURL(), 6500 Manifest::EXTERNAL_POLICY_DOWNLOAD, 6501 Extension::NO_FLAGS, 6502 false); 6503 } 6504 6505 // Get the install source of a pending extension. 6506 Manifest::Location GetPendingLocation() { 6507 const extensions::PendingExtensionInfo* info; 6508 EXPECT_TRUE( 6509 (info = service()->pending_extension_manager()->GetById(crx_id_))); 6510 return info->install_source(); 6511 } 6512 6513 // Is an extension pending from a sync request? 6514 bool GetPendingIsFromSync() { 6515 const extensions::PendingExtensionInfo* info; 6516 EXPECT_TRUE( 6517 (info = service()->pending_extension_manager()->GetById(crx_id_))); 6518 return info->is_from_sync(); 6519 } 6520 6521 // Is the CRX id these tests use pending? 6522 bool IsCrxPending() { 6523 return service()->pending_extension_manager()->IsIdPending(crx_id_); 6524 } 6525 6526 // Is an extension installed? 6527 bool IsCrxInstalled() { 6528 return (service()->GetExtensionById(crx_id_, true) != NULL); 6529 } 6530 6531 protected: 6532 // All tests use a single extension. Making the id and path member 6533 // vars avoids pasing the same argument to every method. 6534 std::string crx_id_; 6535 base::FilePath crx_path_; 6536}; 6537 6538// Test that a pending request for installation of an external CRX from 6539// an update URL overrides a pending request to install the same extension 6540// from sync. 6541TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) { 6542 InitializeEmptyExtensionService(); 6543 6544 ASSERT_FALSE(IsCrxInstalled()); 6545 6546 // Install pending extension from sync. 6547 content::WindowedNotificationObserver observer( 6548 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6549 content::NotificationService::AllSources()); 6550 EXPECT_TRUE(AddPendingSyncInstall()); 6551 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation()); 6552 EXPECT_TRUE(GetPendingIsFromSync()); 6553 ASSERT_FALSE(IsCrxInstalled()); 6554 6555 // Install pending as external prefs json would. 6556 AddPendingExternalPrefFileInstall(); 6557 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation()); 6558 ASSERT_FALSE(IsCrxInstalled()); 6559 6560 // Another request from sync should be ignored. 6561 EXPECT_FALSE(AddPendingSyncInstall()); 6562 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation()); 6563 ASSERT_FALSE(IsCrxInstalled()); 6564 6565 observer.Wait(); 6566 VerifyCrxInstall(crx_path_, INSTALL_NEW); 6567 ASSERT_TRUE(IsCrxInstalled()); 6568} 6569 6570// Test that an install of an external CRX from an update overrides 6571// an install of the same extension from sync. 6572TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) { 6573 InitializeEmptyExtensionService(); 6574 ASSERT_FALSE(IsCrxInstalled()); 6575 6576 EXPECT_TRUE(AddPendingSyncInstall()); 6577 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation()); 6578 EXPECT_TRUE(GetPendingIsFromSync()); 6579 ASSERT_FALSE(IsCrxInstalled()); 6580 6581 ASSERT_TRUE(AddPendingExternalPrefUrl()); 6582 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation()); 6583 EXPECT_FALSE(GetPendingIsFromSync()); 6584 ASSERT_FALSE(IsCrxInstalled()); 6585 6586 EXPECT_FALSE(AddPendingSyncInstall()); 6587 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation()); 6588 EXPECT_FALSE(GetPendingIsFromSync()); 6589 ASSERT_FALSE(IsCrxInstalled()); 6590} 6591 6592// Test that an external install request stops sync from installing 6593// the same extension. 6594TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) { 6595 InitializeEmptyExtensionService(); 6596 ASSERT_FALSE(IsCrxInstalled()); 6597 6598 // External prefs starts an install. 6599 AddPendingExternalPrefFileInstall(); 6600 6601 // Crx installer was made, but has not yet run. 6602 ASSERT_FALSE(IsCrxInstalled()); 6603 6604 // Before the CRX installer runs, Sync requests that the same extension 6605 // be installed. Should fail, because an external source is pending. 6606 content::WindowedNotificationObserver observer( 6607 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6608 content::NotificationService::AllSources()); 6609 ASSERT_FALSE(AddPendingSyncInstall()); 6610 6611 // Wait for the external source to install. 6612 observer.Wait(); 6613 VerifyCrxInstall(crx_path_, INSTALL_NEW); 6614 ASSERT_TRUE(IsCrxInstalled()); 6615 6616 // Now that the extension is installed, sync request should fail 6617 // because the extension is already installed. 6618 ASSERT_FALSE(AddPendingSyncInstall()); 6619} 6620 6621// Test that installing an external extension displays a GlobalError. 6622TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) { 6623 FeatureSwitch::ScopedOverride prompt( 6624 FeatureSwitch::prompt_for_external_extensions(), true); 6625 6626 InitializeEmptyExtensionService(); 6627 MockExtensionProvider* provider = 6628 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF); 6629 AddMockExternalProvider(provider); 6630 6631 service()->external_install_manager()->UpdateExternalExtensionAlert(); 6632 // Should return false, meaning there aren't any extensions that the user 6633 // needs to know about. 6634 EXPECT_FALSE( 6635 service()->external_install_manager()->HasExternalInstallError()); 6636 6637 // This is a normal extension, installed normally. 6638 // This should NOT trigger an alert. 6639 service()->set_extensions_enabled(true); 6640 base::FilePath path = data_dir().AppendASCII("good.crx"); 6641 InstallCRX(path, INSTALL_NEW); 6642 6643 service()->CheckForExternalUpdates(); 6644 base::RunLoop().RunUntilIdle(); 6645 EXPECT_FALSE( 6646 service()->external_install_manager()->HasExternalInstallError()); 6647 6648 // A hosted app, installed externally. 6649 // This should NOT trigger an alert. 6650 provider->UpdateOrAddExtension( 6651 hosted_app, "1.0.0.0", data_dir().AppendASCII("hosted_app.crx")); 6652 6653 content::WindowedNotificationObserver observer( 6654 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6655 content::NotificationService::AllSources()); 6656 service()->CheckForExternalUpdates(); 6657 observer.Wait(); 6658 EXPECT_FALSE( 6659 service()->external_install_manager()->HasExternalInstallError()); 6660 6661 // Another normal extension, but installed externally. 6662 // This SHOULD trigger an alert. 6663 provider->UpdateOrAddExtension( 6664 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx")); 6665 6666 content::WindowedNotificationObserver observer2( 6667 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6668 content::NotificationService::AllSources()); 6669 service()->CheckForExternalUpdates(); 6670 observer2.Wait(); 6671 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError()); 6672} 6673 6674// Test that external extensions are initially disabled, and that enabling 6675// them clears the prompt. 6676TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) { 6677 FeatureSwitch::ScopedOverride prompt( 6678 FeatureSwitch::prompt_for_external_extensions(), true); 6679 6680 InitializeEmptyExtensionService(); 6681 MockExtensionProvider* provider = 6682 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF); 6683 AddMockExternalProvider(provider); 6684 6685 provider->UpdateOrAddExtension( 6686 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx")); 6687 6688 content::WindowedNotificationObserver observer( 6689 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6690 content::NotificationService::AllSources()); 6691 service()->CheckForExternalUpdates(); 6692 observer.Wait(); 6693 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError()); 6694 EXPECT_FALSE(service()->IsExtensionEnabled(page_action)); 6695 6696 const Extension* extension = 6697 registry()->disabled_extensions().GetByID(page_action); 6698 EXPECT_TRUE(extension); 6699 EXPECT_EQ(page_action, extension->id()); 6700 6701 service()->EnableExtension(page_action); 6702 EXPECT_FALSE( 6703 service()->external_install_manager()->HasExternalInstallError()); 6704 EXPECT_TRUE(service()->IsExtensionEnabled(page_action)); 6705} 6706 6707// Test that installing multiple external extensions works. 6708// Flaky on windows; http://crbug.com/295757 . 6709#if defined(OS_WIN) 6710#define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple 6711#else 6712#define MAYBE_ExternalInstallMultiple ExternalInstallMultiple 6713#endif 6714TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) { 6715 FeatureSwitch::ScopedOverride prompt( 6716 FeatureSwitch::prompt_for_external_extensions(), true); 6717 6718 InitializeEmptyExtensionService(); 6719 MockExtensionProvider* provider = 6720 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF); 6721 AddMockExternalProvider(provider); 6722 6723 provider->UpdateOrAddExtension( 6724 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx")); 6725 provider->UpdateOrAddExtension( 6726 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx")); 6727 provider->UpdateOrAddExtension( 6728 theme_crx, "2.0", data_dir().AppendASCII("theme.crx")); 6729 6730 int count = 3; 6731 content::WindowedNotificationObserver observer( 6732 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6733 base::Bind(&WaitForCountNotificationsCallback, &count)); 6734 service()->CheckForExternalUpdates(); 6735 observer.Wait(); 6736 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError()); 6737 EXPECT_FALSE(service()->IsExtensionEnabled(page_action)); 6738 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx)); 6739 EXPECT_FALSE(service()->IsExtensionEnabled(theme_crx)); 6740 6741 service()->EnableExtension(page_action); 6742 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError()); 6743 EXPECT_FALSE(service() 6744 ->external_install_manager() 6745 ->HasExternalInstallBubbleForTesting()); 6746 6747 service()->EnableExtension(theme_crx); 6748 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError()); 6749 EXPECT_FALSE(service() 6750 ->external_install_manager() 6751 ->HasExternalInstallBubbleForTesting()); 6752 6753 service()->EnableExtension(good_crx); 6754 EXPECT_FALSE( 6755 service()->external_install_manager()->HasExternalInstallError()); 6756 EXPECT_FALSE(service() 6757 ->external_install_manager() 6758 ->HasExternalInstallBubbleForTesting()); 6759} 6760 6761// Test that there is a bubble for external extensions that update 6762// from the webstore if the profile is not new. 6763TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) { 6764 FeatureSwitch::ScopedOverride prompt( 6765 FeatureSwitch::prompt_for_external_extensions(), true); 6766 6767 // This sets up the ExtensionPrefs used by our ExtensionService to be 6768 // post-first run. 6769 ExtensionServiceInitParams params = CreateDefaultInitParams(); 6770 params.is_first_run = false; 6771 InitializeExtensionService(params); 6772 6773 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx"); 6774 PackCRX(data_dir().AppendASCII("update_from_webstore"), 6775 data_dir().AppendASCII("update_from_webstore.pem"), 6776 crx_path); 6777 6778 MockExtensionProvider* provider = 6779 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF); 6780 AddMockExternalProvider(provider); 6781 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path); 6782 6783 content::WindowedNotificationObserver observer( 6784 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6785 content::NotificationService::AllSources()); 6786 service()->CheckForExternalUpdates(); 6787 observer.Wait(); 6788 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError()); 6789 EXPECT_TRUE(service() 6790 ->external_install_manager() 6791 ->HasExternalInstallBubbleForTesting()); 6792 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore)); 6793} 6794 6795// Test that there is no bubble for external extensions if the profile is new. 6796TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) { 6797 FeatureSwitch::ScopedOverride prompt( 6798 FeatureSwitch::prompt_for_external_extensions(), true); 6799 6800 InitializeEmptyExtensionService(); 6801 6802 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx"); 6803 PackCRX(data_dir().AppendASCII("update_from_webstore"), 6804 data_dir().AppendASCII("update_from_webstore.pem"), 6805 crx_path); 6806 6807 MockExtensionProvider* provider = 6808 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF); 6809 AddMockExternalProvider(provider); 6810 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path); 6811 6812 content::WindowedNotificationObserver observer( 6813 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6814 content::NotificationService::AllSources()); 6815 service()->CheckForExternalUpdates(); 6816 observer.Wait(); 6817 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError()); 6818 EXPECT_FALSE(service() 6819 ->external_install_manager() 6820 ->HasExternalInstallBubbleForTesting()); 6821 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore)); 6822} 6823 6824// Test that clicking to remove the extension on an external install warning 6825// uninstalls the extension. 6826TEST_F(ExtensionServiceTest, ExternalInstallClickToRemove) { 6827 FeatureSwitch::ScopedOverride prompt( 6828 FeatureSwitch::prompt_for_external_extensions(), true); 6829 6830 ExtensionServiceInitParams params = CreateDefaultInitParams(); 6831 params.is_first_run = false; 6832 InitializeExtensionService(params); 6833 6834 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx"); 6835 PackCRX(data_dir().AppendASCII("update_from_webstore"), 6836 data_dir().AppendASCII("update_from_webstore.pem"), 6837 crx_path); 6838 6839 MockExtensionProvider* provider = 6840 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF); 6841 AddMockExternalProvider(provider); 6842 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path); 6843 6844 content::WindowedNotificationObserver observer( 6845 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6846 content::NotificationService::AllSources()); 6847 service_->CheckForExternalUpdates(); 6848 observer.Wait(); 6849 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError()); 6850 6851 // We check both enabled and disabled, since these are "eventually exclusive" 6852 // sets. 6853 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore)); 6854 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore)); 6855 6856 // Click the negative response. 6857 service_->external_install_manager()->error_for_testing()->InstallUIAbort( 6858 true); 6859 // The Extension should be uninstalled. 6860 EXPECT_FALSE(registry()->GetExtensionById(updates_from_webstore, 6861 ExtensionRegistry::EVERYTHING)); 6862 // The error should be removed. 6863 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError()); 6864} 6865 6866// Test that clicking to keep the extension on an external install warning 6867// re-enables the extension. 6868TEST_F(ExtensionServiceTest, ExternalInstallClickToKeep) { 6869 FeatureSwitch::ScopedOverride prompt( 6870 FeatureSwitch::prompt_for_external_extensions(), true); 6871 6872 ExtensionServiceInitParams params = CreateDefaultInitParams(); 6873 params.is_first_run = false; 6874 InitializeExtensionService(params); 6875 6876 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx"); 6877 PackCRX(data_dir().AppendASCII("update_from_webstore"), 6878 data_dir().AppendASCII("update_from_webstore.pem"), 6879 crx_path); 6880 6881 MockExtensionProvider* provider = 6882 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF); 6883 AddMockExternalProvider(provider); 6884 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path); 6885 6886 content::WindowedNotificationObserver observer( 6887 chrome::NOTIFICATION_CRX_INSTALLER_DONE, 6888 content::NotificationService::AllSources()); 6889 service_->CheckForExternalUpdates(); 6890 observer.Wait(); 6891 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError()); 6892 6893 // We check both enabled and disabled, since these are "eventually exclusive" 6894 // sets. 6895 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore)); 6896 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore)); 6897 6898 // Accept the extension. 6899 service_->external_install_manager()->error_for_testing()->InstallUIProceed(); 6900 6901 // It should be enabled again. 6902 EXPECT_TRUE(registry()->enabled_extensions().GetByID(updates_from_webstore)); 6903 EXPECT_FALSE( 6904 registry()->disabled_extensions().GetByID(updates_from_webstore)); 6905 6906 // The error should be removed. 6907 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError()); 6908} 6909 6910TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) { 6911 InitializeEmptyExtensionService(); 6912 6913 scoped_refptr<Extension> extension = extensions::ExtensionBuilder() 6914 .SetManifest(extensions::DictionaryBuilder() 6915 .Set("name", "extension") 6916 .Set("version", "1.0") 6917 .Set("manifest_version", 2).Build()) 6918 .Build(); 6919 ASSERT_TRUE(extension.get()); 6920 const std::string& id = extension->id(); 6921 6922 std::set<std::string> id_set; 6923 id_set.insert(id); 6924 extensions::ExtensionNotificationObserver notifications( 6925 content::NotificationService::AllSources(), id_set); 6926 6927 // Installation should be allowed but the extension should never have been 6928 // loaded and it should be blacklisted in prefs. 6929 service()->OnExtensionInstalled( 6930 extension.get(), 6931 syncer::StringOrdinal(), 6932 (extensions::kInstallFlagIsBlacklistedForMalware | 6933 extensions::kInstallFlagInstallImmediately)); 6934 base::RunLoop().RunUntilIdle(); 6935 6936 // Extension was installed but not loaded. 6937 EXPECT_TRUE(notifications.CheckNotifications( 6938 chrome::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED)); 6939 EXPECT_TRUE(service()->GetInstalledExtension(id)); 6940 6941 EXPECT_FALSE(registry()->enabled_extensions().Contains(id)); 6942 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(id)); 6943 6944 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlacklisted(id)); 6945 EXPECT_TRUE( 6946 ExtensionPrefs::Get(profile())->IsBlacklistedExtensionAcknowledged(id)); 6947} 6948 6949// Tests a profile being destroyed correctly disables extensions. 6950TEST_F(ExtensionServiceTest, DestroyingProfileClearsExtensions) { 6951 InitializeEmptyExtensionService(); 6952 6953 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW); 6954 EXPECT_NE(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_); 6955 EXPECT_EQ(1u, registry()->enabled_extensions().size()); 6956 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 6957 EXPECT_EQ(0u, registry()->terminated_extensions().size()); 6958 EXPECT_EQ(0u, registry()->blacklisted_extensions().size()); 6959 6960 service()->Observe(chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED, 6961 content::Source<Profile>(profile()), 6962 content::NotificationService::NoDetails()); 6963 EXPECT_EQ(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_); 6964 EXPECT_EQ(0u, registry()->enabled_extensions().size()); 6965 EXPECT_EQ(0u, registry()->disabled_extensions().size()); 6966 EXPECT_EQ(0u, registry()->terminated_extensions().size()); 6967 EXPECT_EQ(0u, registry()->blacklisted_extensions().size()); 6968} 6969