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