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