1 // Copyright (c) 2011 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/basictypes.h" 12 #include "base/command_line.h" 13 #include "base/file_util.h" 14 #include "base/json/json_reader.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/scoped_temp_dir.h" 17 #include "base/message_loop.h" 18 #include "base/path_service.h" 19 #include "base/stl_util-inl.h" 20 #include "base/string16.h" 21 #include "base/string_number_conversions.h" 22 #include "base/string_util.h" 23 #include "base/task.h" 24 #include "base/utf_string_conversions.h" 25 #include "base/version.h" 26 #include "chrome/browser/extensions/crx_installer.h" 27 #include "chrome/browser/extensions/extension_creator.h" 28 #include "chrome/browser/extensions/extension_error_reporter.h" 29 #include "chrome/browser/extensions/extension_service.h" 30 #include "chrome/browser/extensions/extension_special_storage_policy.h" 31 #include "chrome/browser/extensions/extension_sync_data.h" 32 #include "chrome/browser/extensions/extension_updater.h" 33 #include "chrome/browser/extensions/external_extension_provider_impl.h" 34 #include "chrome/browser/extensions/external_extension_provider_interface.h" 35 #include "chrome/browser/extensions/external_pref_extension_loader.h" 36 #include "chrome/browser/extensions/pack_extension_job.cc" 37 #include "chrome/browser/extensions/pending_extension_info.h" 38 #include "chrome/browser/extensions/pending_extension_manager.h" 39 #include "chrome/browser/prefs/browser_prefs.h" 40 #include "chrome/browser/prefs/pref_service_mock_builder.h" 41 #include "chrome/browser/prefs/scoped_user_pref_update.h" 42 #include "chrome/common/chrome_paths.h" 43 #include "chrome/common/chrome_switches.h" 44 #include "chrome/common/extensions/extension.h" 45 #include "chrome/common/extensions/extension_constants.h" 46 #include "chrome/common/extensions/extension_resource.h" 47 #include "chrome/common/extensions/url_pattern.h" 48 #include "chrome/common/pref_names.h" 49 #include "chrome/common/url_constants.h" 50 #include "chrome/test/testing_profile.h" 51 #include "content/browser/appcache/chrome_appcache_service.h" 52 #include "content/browser/browser_thread.h" 53 #include "content/browser/file_system/browser_file_system_helper.h" 54 #include "content/browser/in_process_webkit/dom_storage_context.h" 55 #include "content/browser/in_process_webkit/webkit_context.h" 56 #include "content/common/json_value_serializer.h" 57 #include "content/common/notification_registrar.h" 58 #include "content/common/notification_service.h" 59 #include "content/common/notification_type.h" 60 #include "googleurl/src/gurl.h" 61 #include "net/base/cookie_monster.h" 62 #include "net/base/cookie_options.h" 63 #include "net/url_request/url_request_context.h" 64 #include "net/url_request/url_request_context_getter.h" 65 #include "testing/gtest/include/gtest/gtest.h" 66 #include "testing/platform_test.h" 67 #include "webkit/database/database_tracker.h" 68 #include "webkit/database/database_util.h" 69 70 namespace keys = extension_manifest_keys; 71 72 namespace { 73 74 // Extension ids used during testing. 75 const char* const all_zero = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; 76 const char* const zero_n_one = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"; 77 const char* const good0 = "behllobkkfkfnphdnhnkndlbkcpglgmj"; 78 const char* const good1 = "hpiknbiabeeppbpihjehijgoemciehgk"; 79 const char* const good2 = "bjafgdebaacbbbecmhlhpofkepfkgcpa"; 80 const char* const good_crx = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; 81 const char* const page_action = "obcimlgaoabeegjmmpldobjndiealpln"; 82 const char* const theme_crx = "iamefpfkojoapidjnbafmgkgncegbkad"; 83 const char* const theme2_crx = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf"; 84 const char* const permissions_crx = "eagpmdpfmaekmmcejjbmjoecnejeiiin"; 85 86 struct ExtensionsOrder { 87 bool operator()(const Extension* a, const Extension* b) { 88 return a->name() < b->name(); 89 } 90 }; 91 92 static std::vector<std::string> GetErrors() { 93 const std::vector<std::string>* errors = 94 ExtensionErrorReporter::GetInstance()->GetErrors(); 95 std::vector<std::string> ret_val; 96 97 for (std::vector<std::string>::const_iterator iter = errors->begin(); 98 iter != errors->end(); ++iter) { 99 if (iter->find(".svn") == std::string::npos) { 100 ret_val.push_back(*iter); 101 } 102 } 103 104 // The tests rely on the errors being in a certain order, which can vary 105 // depending on how filesystem iteration works. 106 std::stable_sort(ret_val.begin(), ret_val.end()); 107 108 return ret_val; 109 } 110 111 static void AddPattern(ExtensionExtent* extent, const std::string& pattern) { 112 int schemes = URLPattern::SCHEME_ALL; 113 extent->AddPattern(URLPattern(schemes, pattern)); 114 } 115 116 static void AssertEqualExtents(ExtensionExtent* extent1, 117 ExtensionExtent* extent2) { 118 std::vector<URLPattern> patterns1 = extent1->patterns(); 119 std::vector<URLPattern> patterns2 = extent2->patterns(); 120 std::set<std::string> strings1; 121 EXPECT_EQ(patterns1.size(), patterns2.size()); 122 123 for (size_t i = 0; i < patterns1.size(); ++i) 124 strings1.insert(patterns1.at(i).GetAsString()); 125 126 std::set<std::string> strings2; 127 for (size_t i = 0; i < patterns2.size(); ++i) 128 strings2.insert(patterns2.at(i).GetAsString()); 129 130 EXPECT_EQ(strings1, strings2); 131 } 132 133 } // namespace 134 135 class MockExtensionProvider : public ExternalExtensionProviderInterface { 136 public: 137 explicit MockExtensionProvider( 138 VisitorInterface* visitor, 139 Extension::Location location) 140 : location_(location), visitor_(visitor), visit_count_(0) { 141 } 142 virtual ~MockExtensionProvider() {} 143 144 void UpdateOrAddExtension(const std::string& id, 145 const std::string& version, 146 const FilePath& path) { 147 extension_map_[id] = std::make_pair(version, path); 148 } 149 150 void RemoveExtension(const std::string& id) { 151 extension_map_.erase(id); 152 } 153 154 // ExternalExtensionProvider implementation: 155 virtual void VisitRegisteredExtension() const { 156 visit_count_++; 157 for (DataMap::const_iterator i = extension_map_.begin(); 158 i != extension_map_.end(); ++i) { 159 scoped_ptr<Version> version; 160 version.reset(Version::GetVersionFromString(i->second.first)); 161 162 visitor_->OnExternalExtensionFileFound( 163 i->first, version.get(), i->second.second, location_); 164 } 165 visitor_->OnExternalProviderReady(); 166 } 167 168 virtual bool HasExtension(const std::string& id) const { 169 return extension_map_.find(id) != extension_map_.end(); 170 } 171 172 virtual bool GetExtensionDetails(const std::string& id, 173 Extension::Location* location, 174 scoped_ptr<Version>* version) const { 175 DataMap::const_iterator it = extension_map_.find(id); 176 if (it == extension_map_.end()) 177 return false; 178 179 if (version) 180 version->reset(Version::GetVersionFromString(it->second.first)); 181 182 if (location) 183 *location = location_; 184 185 return true; 186 } 187 188 virtual bool IsReady() { 189 return true; 190 } 191 192 virtual void ServiceShutdown() { 193 } 194 195 int visit_count() const { return visit_count_; } 196 void set_visit_count(int visit_count) { 197 visit_count_ = visit_count; 198 } 199 200 private: 201 typedef std::map< std::string, std::pair<std::string, FilePath> > DataMap; 202 DataMap extension_map_; 203 Extension::Location location_; 204 VisitorInterface* visitor_; 205 206 // visit_count_ tracks the number of calls to VisitRegisteredExtension(). 207 // Mutable because it must be incremented on each call to 208 // VisitRegisteredExtension(), which must be a const method to inherit 209 // from the class being mocked. 210 mutable int visit_count_; 211 212 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider); 213 }; 214 215 class MockProviderVisitor 216 : public ExternalExtensionProviderInterface::VisitorInterface { 217 public: 218 219 // The provider will return |fake_base_path| from 220 // GetBaseCrxFilePath(). User can test the behavior with 221 // and without an empty path using this parameter. 222 explicit MockProviderVisitor(FilePath fake_base_path) 223 : ids_found_(0), 224 fake_base_path_(fake_base_path) { 225 } 226 227 int Visit(const std::string& json_data) { 228 // Give the test json file to the provider for parsing. 229 provider_.reset(new ExternalExtensionProviderImpl( 230 this, 231 new ExternalTestingExtensionLoader(json_data, fake_base_path_), 232 Extension::EXTERNAL_PREF, 233 Extension::EXTERNAL_PREF_DOWNLOAD)); 234 235 // We also parse the file into a dictionary to compare what we get back 236 // from the provider. 237 JSONStringValueSerializer serializer(json_data); 238 Value* json_value = serializer.Deserialize(NULL, NULL); 239 240 if (!json_value || !json_value->IsType(Value::TYPE_DICTIONARY)) { 241 NOTREACHED() << "Unable to deserialize json data"; 242 return -1; 243 } else { 244 DictionaryValue* external_extensions = 245 static_cast<DictionaryValue*>(json_value); 246 prefs_.reset(external_extensions); 247 } 248 249 // Reset our counter. 250 ids_found_ = 0; 251 // Ask the provider to look up all extensions and return them. 252 provider_->VisitRegisteredExtension(); 253 254 return ids_found_; 255 } 256 257 virtual void OnExternalExtensionFileFound(const std::string& id, 258 const Version* version, 259 const FilePath& path, 260 Extension::Location unused) { 261 ++ids_found_; 262 DictionaryValue* pref; 263 // This tests is to make sure that the provider only notifies us of the 264 // values we gave it. So if the id we doesn't exist in our internal 265 // dictionary then something is wrong. 266 EXPECT_TRUE(prefs_->GetDictionary(id, &pref)) 267 << "Got back ID (" << id.c_str() << ") we weren't expecting"; 268 269 EXPECT_TRUE(path.IsAbsolute()); 270 if (!fake_base_path_.empty()) 271 EXPECT_TRUE(fake_base_path_.IsParent(path)); 272 273 if (pref) { 274 EXPECT_TRUE(provider_->HasExtension(id)); 275 276 // Ask provider if the extension we got back is registered. 277 Extension::Location location = Extension::INVALID; 278 scoped_ptr<Version> v1; 279 FilePath crx_path; 280 281 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1)); 282 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str()); 283 284 scoped_ptr<Version> v2; 285 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2)); 286 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str()); 287 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str()); 288 EXPECT_EQ(Extension::EXTERNAL_PREF, location); 289 290 // Remove it so we won't count it ever again. 291 prefs_->Remove(id, NULL); 292 } 293 } 294 295 virtual void OnExternalExtensionUpdateUrlFound( 296 const std::string& id, const GURL& update_url, 297 Extension::Location location) { 298 ++ids_found_; 299 DictionaryValue* pref; 300 // This tests is to make sure that the provider only notifies us of the 301 // values we gave it. So if the id we doesn't exist in our internal 302 // dictionary then something is wrong. 303 EXPECT_TRUE(prefs_->GetDictionary(id, &pref)) 304 << L"Got back ID (" << id.c_str() << ") we weren't expecting"; 305 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location); 306 307 if (pref) { 308 EXPECT_TRUE(provider_->HasExtension(id)); 309 310 // External extensions with update URLs do not have versions. 311 scoped_ptr<Version> v1; 312 Extension::Location location1 = Extension::INVALID; 313 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1)); 314 EXPECT_FALSE(v1.get()); 315 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, location1); 316 317 // Remove it so we won't count it again. 318 prefs_->Remove(id, NULL); 319 } 320 } 321 322 virtual void OnExternalProviderReady() { 323 EXPECT_TRUE(provider_->IsReady()); 324 } 325 326 private: 327 int ids_found_; 328 FilePath fake_base_path_; 329 scoped_ptr<ExternalExtensionProviderImpl> provider_; 330 scoped_ptr<DictionaryValue> prefs_; 331 332 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor); 333 }; 334 335 class ExtensionTestingProfile : public TestingProfile { 336 public: 337 ExtensionTestingProfile() : service_(NULL) { 338 } 339 340 void set_extensions_service(ExtensionService* service) { 341 service_ = service; 342 } 343 virtual ExtensionService* GetExtensionService() { return service_; } 344 345 virtual ChromeAppCacheService* GetAppCacheService() { 346 if (!appcache_service_) { 347 appcache_service_ = new ChromeAppCacheService; 348 BrowserThread::PostTask( 349 BrowserThread::IO, FROM_HERE, 350 NewRunnableMethod( 351 appcache_service_.get(), 352 &ChromeAppCacheService::InitializeOnIOThread, 353 IsOffTheRecord() 354 ? FilePath() : GetPath().Append(chrome::kAppCacheDirname), 355 make_scoped_refptr(GetHostContentSettingsMap()), 356 make_scoped_refptr(GetExtensionSpecialStoragePolicy()), 357 false)); 358 } 359 return appcache_service_; 360 } 361 362 virtual fileapi::FileSystemContext* GetFileSystemContext() { 363 if (!file_system_context_) 364 file_system_context_ = CreateFileSystemContext( 365 GetPath(), IsOffTheRecord(), GetExtensionSpecialStoragePolicy()); 366 return file_system_context_; 367 } 368 369 private: 370 ExtensionService* service_; 371 scoped_refptr<ChromeAppCacheService> appcache_service_; 372 scoped_refptr<fileapi::FileSystemContext> file_system_context_; 373 }; 374 375 // Our message loop may be used in tests which require it to be an IO loop. 376 ExtensionServiceTestBase::ExtensionServiceTestBase() 377 : total_successes_(0), 378 loop_(MessageLoop::TYPE_IO), 379 ui_thread_(BrowserThread::UI, &loop_), 380 db_thread_(BrowserThread::DB, &loop_), 381 webkit_thread_(BrowserThread::WEBKIT, &loop_), 382 file_thread_(BrowserThread::FILE, &loop_), 383 io_thread_(BrowserThread::IO, &loop_) { 384 FilePath test_data_dir; 385 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) { 386 ADD_FAILURE(); 387 return; 388 } 389 data_dir_ = test_data_dir.AppendASCII("extensions"); 390 } 391 392 ExtensionServiceTestBase::~ExtensionServiceTestBase() { 393 // Drop our reference to ExtensionService and TestingProfile, so that they 394 // can be destroyed while BrowserThreads and MessageLoop are still around 395 // (they are used in the destruction process). 396 service_ = NULL; 397 profile_.reset(NULL); 398 MessageLoop::current()->RunAllPending(); 399 } 400 401 void ExtensionServiceTestBase::InitializeExtensionService( 402 const FilePath& pref_file, const FilePath& extensions_install_dir, 403 bool autoupdate_enabled) { 404 ExtensionTestingProfile* profile = new ExtensionTestingProfile(); 405 // Create a PrefService that only contains user defined preference values. 406 PrefService* prefs = 407 PrefServiceMockBuilder().WithUserFilePrefs(pref_file).Create(); 408 Profile::RegisterUserPrefs(prefs); 409 browser::RegisterUserPrefs(prefs); 410 profile->SetPrefService(prefs); 411 412 profile_.reset(profile); 413 414 service_ = profile->CreateExtensionService( 415 CommandLine::ForCurrentProcess(), 416 extensions_install_dir, 417 autoupdate_enabled); 418 service_->set_extensions_enabled(true); 419 service_->set_show_extensions_prompts(false); 420 profile->set_extensions_service(service_.get()); 421 422 // When we start up, we want to make sure there is no external provider, 423 // since the ExtensionService on Windows will use the Registry as a default 424 // provider and if there is something already registered there then it will 425 // interfere with the tests. Those tests that need an external provider 426 // will register one specifically. 427 service_->ClearProvidersForTesting(); 428 429 total_successes_ = 0; 430 } 431 432 void ExtensionServiceTestBase::InitializeInstalledExtensionService( 433 const FilePath& prefs_file, const FilePath& source_install_dir) { 434 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 435 FilePath path_ = temp_dir_.path(); 436 path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath")); 437 file_util::Delete(path_, true); 438 file_util::CreateDirectory(path_); 439 FilePath temp_prefs = path_.Append(FILE_PATH_LITERAL("Preferences")); 440 file_util::CopyFile(prefs_file, temp_prefs); 441 442 extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions")); 443 file_util::Delete(extensions_install_dir_, true); 444 file_util::CopyDirectory(source_install_dir, extensions_install_dir_, true); 445 446 InitializeExtensionService(temp_prefs, extensions_install_dir_, false); 447 } 448 449 void ExtensionServiceTestBase::InitializeEmptyExtensionService() { 450 InitializeExtensionServiceHelper(false); 451 } 452 453 void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() { 454 InitializeExtensionServiceHelper(true); 455 service_->updater()->Start(); 456 } 457 458 void ExtensionServiceTestBase::InitializeExtensionServiceHelper( 459 bool autoupdate_enabled) { 460 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 461 FilePath path_ = temp_dir_.path(); 462 path_ = path_.Append(FILE_PATH_LITERAL("TestingExtensionsPath")); 463 file_util::Delete(path_, true); 464 file_util::CreateDirectory(path_); 465 FilePath prefs_filename = path_ 466 .Append(FILE_PATH_LITERAL("TestPreferences")); 467 extensions_install_dir_ = path_.Append(FILE_PATH_LITERAL("Extensions")); 468 file_util::Delete(extensions_install_dir_, true); 469 file_util::CreateDirectory(extensions_install_dir_); 470 471 InitializeExtensionService(prefs_filename, extensions_install_dir_, 472 autoupdate_enabled); 473 } 474 475 // static 476 void ExtensionServiceTestBase::SetUpTestCase() { 477 ExtensionErrorReporter::Init(false); // no noisy errors 478 } 479 480 void ExtensionServiceTestBase::SetUp() { 481 ExtensionErrorReporter::GetInstance()->ClearErrors(); 482 } 483 484 class ExtensionServiceTest 485 : public ExtensionServiceTestBase, public NotificationObserver { 486 public: 487 ExtensionServiceTest() : installed_(NULL) { 488 registrar_.Add(this, NotificationType::EXTENSION_LOADED, 489 NotificationService::AllSources()); 490 registrar_.Add(this, NotificationType::EXTENSION_UNLOADED, 491 NotificationService::AllSources()); 492 registrar_.Add(this, NotificationType::EXTENSION_INSTALLED, 493 NotificationService::AllSources()); 494 } 495 496 virtual void Observe(NotificationType type, 497 const NotificationSource& source, 498 const NotificationDetails& details) { 499 switch (type.value) { 500 case NotificationType::EXTENSION_LOADED: { 501 const Extension* extension = Details<const Extension>(details).ptr(); 502 loaded_.push_back(make_scoped_refptr(extension)); 503 // The tests rely on the errors being in a certain order, which can vary 504 // depending on how filesystem iteration works. 505 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder()); 506 break; 507 } 508 509 case NotificationType::EXTENSION_UNLOADED: { 510 const Extension* e = 511 Details<UnloadedExtensionInfo>(details)->extension; 512 unloaded_id_ = e->id(); 513 ExtensionList::iterator i = 514 std::find(loaded_.begin(), loaded_.end(), e); 515 // TODO(erikkay) fix so this can be an assert. Right now the tests 516 // are manually calling clear() on loaded_, so this isn't doable. 517 if (i == loaded_.end()) 518 return; 519 loaded_.erase(i); 520 break; 521 } 522 case NotificationType::EXTENSION_INSTALLED: 523 installed_ = Details<const Extension>(details).ptr(); 524 break; 525 526 default: 527 DCHECK(false); 528 } 529 } 530 531 void AddMockExternalProvider(ExternalExtensionProviderInterface* provider) { 532 service_->AddProviderForTesting(provider); 533 } 534 535 protected: 536 void TestExternalProvider(MockExtensionProvider* provider, 537 Extension::Location location); 538 539 void PackAndInstallCrx(const FilePath& dir_path, 540 const FilePath& pem_path, 541 bool should_succeed) { 542 FilePath crx_path; 543 ScopedTempDir temp_dir; 544 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 545 crx_path = temp_dir_.path().AppendASCII("temp.crx"); 546 547 // Use the existing pem key, if provided. 548 FilePath pem_output_path; 549 if (pem_path.value().empty()) { 550 pem_output_path = crx_path.DirName().AppendASCII("temp.pem"); 551 ASSERT_TRUE(file_util::Delete(pem_output_path, false)); 552 } else { 553 ASSERT_TRUE(file_util::PathExists(pem_path)); 554 } 555 556 ASSERT_TRUE(file_util::Delete(crx_path, false)); 557 558 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); 559 ASSERT_TRUE(creator->Run(dir_path, 560 crx_path, 561 pem_path, 562 pem_output_path)); 563 564 ASSERT_TRUE(file_util::PathExists(crx_path)); 565 566 InstallCrx(crx_path, should_succeed); 567 } 568 569 void PackAndInstallCrx(const FilePath& dir_path, 570 bool should_succeed) { 571 PackAndInstallCrx(dir_path, FilePath(), should_succeed); 572 } 573 574 // Create a CrxInstaller and start installation. To allow the install 575 // to happen, use loop_.RunAllPending();. Most tests will not use this 576 // method directly. Instead, use InstallCrx(), which waits for 577 // the crx to be installed and does extra error checking. 578 void StartCrxInstall(const FilePath& crx_path) { 579 ASSERT_TRUE(file_util::PathExists(crx_path)) 580 << "Path does not exist: "<< crx_path.value().c_str(); 581 scoped_refptr<CrxInstaller> installer( 582 new CrxInstaller(service_, // frontend 583 NULL)); // no client (silent install) 584 installer->InstallCrx(crx_path); 585 } 586 587 void InstallCrx(const FilePath& path, 588 bool should_succeed) { 589 StartCrxInstall(path); 590 WaitForCrxInstall(path, should_succeed); 591 } 592 593 void InstallCrxWithLocation(const FilePath& crx_path, 594 Extension::Location install_location, 595 bool should_succeed) { 596 ASSERT_TRUE(file_util::PathExists(crx_path)) 597 << "Path does not exist: "<< crx_path.value().c_str(); 598 scoped_refptr<CrxInstaller> installer( 599 new CrxInstaller(service_, // frontend 600 NULL)); // no client (silent install) 601 602 installer->set_install_source(install_location); 603 installer->InstallCrx(crx_path); 604 605 WaitForCrxInstall(crx_path, should_succeed); 606 } 607 608 // Wait for a CrxInstaller to finish. Used by InstallCrx. 609 void WaitForCrxInstall(const FilePath& path, 610 bool should_succeed) { 611 loop_.RunAllPending(); 612 std::vector<std::string> errors = GetErrors(); 613 if (should_succeed) { 614 ++total_successes_; 615 616 EXPECT_TRUE(installed_) << path.value(); 617 618 ASSERT_EQ(1u, loaded_.size()) << path.value(); 619 EXPECT_EQ(0u, errors.size()) << path.value(); 620 EXPECT_EQ(total_successes_, service_->extensions()->size()) << 621 path.value(); 622 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) << 623 path.value(); 624 for (std::vector<std::string>::iterator err = errors.begin(); 625 err != errors.end(); ++err) { 626 LOG(ERROR) << *err; 627 } 628 } else { 629 EXPECT_FALSE(installed_) << path.value(); 630 EXPECT_EQ(0u, loaded_.size()) << path.value(); 631 EXPECT_EQ(1u, errors.size()) << path.value(); 632 } 633 634 installed_ = NULL; 635 loaded_.clear(); 636 ExtensionErrorReporter::GetInstance()->ClearErrors(); 637 } 638 639 enum UpdateState { 640 FAILED_SILENTLY, 641 FAILED, 642 UPDATED, 643 INSTALLED, 644 ENABLED 645 }; 646 647 void UpdateExtension(const std::string& id, const FilePath& in_path, 648 UpdateState expected_state) { 649 ASSERT_TRUE(file_util::PathExists(in_path)); 650 651 // We need to copy this to a temporary location because Update() will delete 652 // it. 653 FilePath path = temp_dir_.path(); 654 path = path.Append(in_path.BaseName()); 655 ASSERT_TRUE(file_util::CopyFile(in_path, path)); 656 657 int previous_enabled_extension_count = 658 service_->extensions()->size(); 659 int previous_installed_extension_count = 660 previous_enabled_extension_count + 661 service_->disabled_extensions()->size(); 662 663 service_->UpdateExtension(id, path, GURL()); 664 loop_.RunAllPending(); 665 666 std::vector<std::string> errors = GetErrors(); 667 int error_count = errors.size(); 668 int enabled_extension_count = 669 service_->extensions()->size(); 670 int installed_extension_count = 671 enabled_extension_count + service_->disabled_extensions()->size(); 672 673 int expected_error_count = (expected_state == FAILED) ? 1 : 0; 674 EXPECT_EQ(expected_error_count, error_count) << path.value(); 675 676 if (expected_state <= FAILED) { 677 EXPECT_EQ(previous_enabled_extension_count, 678 enabled_extension_count); 679 EXPECT_EQ(previous_installed_extension_count, 680 installed_extension_count); 681 } else { 682 int expected_installed_extension_count = 683 (expected_state >= INSTALLED) ? 1 : 0; 684 int expected_enabled_extension_count = 685 (expected_state >= ENABLED) ? 1 : 0; 686 EXPECT_EQ(expected_installed_extension_count, 687 installed_extension_count); 688 EXPECT_EQ(expected_enabled_extension_count, 689 enabled_extension_count); 690 } 691 692 // Update() should delete the temporary input file. 693 EXPECT_FALSE(file_util::PathExists(path)); 694 } 695 696 void ValidatePrefKeyCount(size_t count) { 697 const DictionaryValue* dict = 698 profile_->GetPrefs()->GetDictionary("extensions.settings"); 699 ASSERT_TRUE(dict != NULL); 700 EXPECT_EQ(count, dict->size()); 701 } 702 703 void ValidateBooleanPref(const std::string& extension_id, 704 const std::string& pref_path, 705 bool expected_val) { 706 std::string msg = " while checking: "; 707 msg += extension_id; 708 msg += " "; 709 msg += pref_path; 710 msg += " == "; 711 msg += expected_val ? "true" : "false"; 712 713 PrefService* prefs = profile_->GetPrefs(); 714 const DictionaryValue* dict = 715 prefs->GetDictionary("extensions.settings"); 716 ASSERT_TRUE(dict != NULL) << msg; 717 DictionaryValue* pref = NULL; 718 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; 719 EXPECT_TRUE(pref != NULL) << msg; 720 bool val; 721 ASSERT_TRUE(pref->GetBoolean(pref_path, &val)) << msg; 722 EXPECT_EQ(expected_val, val) << msg; 723 } 724 725 bool IsPrefExist(const std::string& extension_id, 726 const std::string& pref_path) { 727 const DictionaryValue* dict = 728 profile_->GetPrefs()->GetDictionary("extensions.settings"); 729 if (dict == NULL) return false; 730 DictionaryValue* pref = NULL; 731 if (!dict->GetDictionary(extension_id, &pref)) { 732 return false; 733 } 734 if (pref == NULL) { 735 return false; 736 } 737 bool val; 738 if (!pref->GetBoolean(pref_path, &val)) { 739 return false; 740 } 741 return true; 742 } 743 744 void ValidateIntegerPref(const std::string& extension_id, 745 const std::string& pref_path, 746 int expected_val) { 747 std::string msg = " while checking: "; 748 msg += extension_id; 749 msg += " "; 750 msg += pref_path; 751 msg += " == "; 752 msg += base::IntToString(expected_val); 753 754 PrefService* prefs = profile_->GetPrefs(); 755 const DictionaryValue* dict = 756 prefs->GetDictionary("extensions.settings"); 757 ASSERT_TRUE(dict != NULL) << msg; 758 DictionaryValue* pref = NULL; 759 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; 760 EXPECT_TRUE(pref != NULL) << msg; 761 int val; 762 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg; 763 EXPECT_EQ(expected_val, val) << msg; 764 } 765 766 void ValidateStringPref(const std::string& extension_id, 767 const std::string& pref_path, 768 const std::string& expected_val) { 769 std::string msg = " while checking: "; 770 msg += extension_id; 771 msg += ".manifest."; 772 msg += pref_path; 773 msg += " == "; 774 msg += expected_val; 775 776 const DictionaryValue* dict = 777 profile_->GetPrefs()->GetDictionary("extensions.settings"); 778 ASSERT_TRUE(dict != NULL) << msg; 779 DictionaryValue* pref = NULL; 780 std::string manifest_path = extension_id + ".manifest"; 781 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg; 782 EXPECT_TRUE(pref != NULL) << msg; 783 std::string val; 784 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg; 785 EXPECT_EQ(expected_val, val) << msg; 786 } 787 788 void SetPref(const std::string& extension_id, 789 const std::string& pref_path, 790 Value* value, 791 const std::string& msg) { 792 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings"); 793 DictionaryValue* dict = update.Get(); 794 ASSERT_TRUE(dict != NULL) << msg; 795 DictionaryValue* pref = NULL; 796 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; 797 EXPECT_TRUE(pref != NULL) << msg; 798 pref->Set(pref_path, value); 799 } 800 801 void SetPrefInteg(const std::string& extension_id, 802 const std::string& pref_path, 803 int value) { 804 std::string msg = " while setting: "; 805 msg += extension_id; 806 msg += " "; 807 msg += pref_path; 808 msg += " = "; 809 msg += base::IntToString(value); 810 811 SetPref(extension_id, pref_path, Value::CreateIntegerValue(value), msg); 812 } 813 814 void SetPrefBool(const std::string& extension_id, 815 const std::string& pref_path, 816 bool value) { 817 std::string msg = " while setting: "; 818 msg += extension_id + " " + pref_path; 819 msg += " = "; 820 msg += (value ? "true" : "false"); 821 822 SetPref(extension_id, pref_path, Value::CreateBooleanValue(value), msg); 823 } 824 825 void ClearPref(const std::string& extension_id, 826 const std::string& pref_path) { 827 std::string msg = " while clearing: "; 828 msg += extension_id + " " + pref_path; 829 830 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings"); 831 DictionaryValue* dict = update.Get(); 832 ASSERT_TRUE(dict != NULL) << msg; 833 DictionaryValue* pref = NULL; 834 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg; 835 EXPECT_TRUE(pref != NULL) << msg; 836 pref->Remove(pref_path, NULL); 837 } 838 839 void SetPrefStringSet(const std::string& extension_id, 840 const std::string& pref_path, 841 const std::set<std::string>& value) { 842 std::string msg = " while setting: "; 843 msg += extension_id + " " + pref_path; 844 845 ListValue* list_value = new ListValue(); 846 for (std::set<std::string>::const_iterator iter = value.begin(); 847 iter != value.end(); ++iter) 848 list_value->Append(Value::CreateStringValue(*iter)); 849 850 SetPref(extension_id, pref_path, list_value, msg); 851 } 852 853 protected: 854 ExtensionList loaded_; 855 std::string unloaded_id_; 856 const Extension* installed_; 857 858 private: 859 NotificationRegistrar registrar_; 860 }; 861 862 FilePath NormalizeSeparators(const FilePath& path) { 863 #if defined(FILE_PATH_USES_WIN_SEPARATORS) 864 return path.NormalizeWindowsPathSeparators(); 865 #else 866 return path; 867 #endif // FILE_PATH_USES_WIN_SEPARATORS 868 } 869 870 // Receives notifications from a PackExtensionJob, indicating either that 871 // packing succeeded or that there was some error. 872 class PackExtensionTestClient : public PackExtensionJob::Client { 873 public: 874 PackExtensionTestClient(const FilePath& expected_crx_path, 875 const FilePath& expected_private_key_path); 876 virtual void OnPackSuccess(const FilePath& crx_path, 877 const FilePath& private_key_path); 878 virtual void OnPackFailure(const std::string& error_message); 879 880 private: 881 const FilePath expected_crx_path_; 882 const FilePath expected_private_key_path_; 883 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient); 884 }; 885 886 PackExtensionTestClient::PackExtensionTestClient( 887 const FilePath& expected_crx_path, 888 const FilePath& expected_private_key_path) 889 : expected_crx_path_(expected_crx_path), 890 expected_private_key_path_(expected_private_key_path) {} 891 892 // If packing succeeded, we make sure that the package names match our 893 // expectations. 894 void PackExtensionTestClient::OnPackSuccess(const FilePath& crx_path, 895 const FilePath& private_key_path) { 896 // We got the notification and processed it; we don't expect any further tasks 897 // to be posted to the current thread, so we should stop blocking and continue 898 // on with the rest of the test. 899 // This call to |Quit()| matches the call to |Run()| in the 900 // |PackPunctuatedExtension| test. 901 MessageLoop::current()->Quit(); 902 EXPECT_EQ(expected_crx_path_.value(), crx_path.value()); 903 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value()); 904 ASSERT_TRUE(file_util::PathExists(private_key_path)); 905 } 906 907 // The tests are designed so that we never expect to see a packing error. 908 void PackExtensionTestClient::OnPackFailure(const std::string& error_message) { 909 FAIL() << "Packing should not fail."; 910 } 911 912 // Test loading good extensions from the profile directory. 913 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) { 914 // Initialize the test dir with a good Preferences/extensions. 915 FilePath source_install_dir = data_dir_ 916 .AppendASCII("good") 917 .AppendASCII("Extensions"); 918 FilePath pref_path = source_install_dir 919 .DirName() 920 .AppendASCII("Preferences"); 921 InitializeInstalledExtensionService(pref_path, source_install_dir); 922 923 service_->Init(); 924 925 uint32 expected_num_extensions = 3u; 926 ASSERT_EQ(expected_num_extensions, loaded_.size()); 927 928 EXPECT_EQ(std::string(good0), loaded_[0]->id()); 929 EXPECT_EQ(std::string("My extension 1"), 930 loaded_[0]->name()); 931 EXPECT_EQ(std::string("The first extension that I made."), 932 loaded_[0]->description()); 933 EXPECT_EQ(Extension::INTERNAL, loaded_[0]->location()); 934 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)); 935 EXPECT_EQ(expected_num_extensions, service_->extensions()->size()); 936 937 ValidatePrefKeyCount(3); 938 ValidateIntegerPref(good0, "state", Extension::ENABLED); 939 ValidateIntegerPref(good0, "location", Extension::INTERNAL); 940 ValidateIntegerPref(good1, "state", Extension::ENABLED); 941 ValidateIntegerPref(good1, "location", Extension::INTERNAL); 942 ValidateIntegerPref(good2, "state", Extension::ENABLED); 943 ValidateIntegerPref(good2, "location", Extension::INTERNAL); 944 945 const Extension* extension = loaded_[0]; 946 const UserScriptList& scripts = extension->content_scripts(); 947 ASSERT_EQ(2u, scripts.size()); 948 EXPECT_EQ(3u, scripts[0].url_patterns().size()); 949 EXPECT_EQ("file://*", 950 scripts[0].url_patterns()[0].GetAsString()); 951 EXPECT_EQ("http://*.google.com/*", 952 scripts[0].url_patterns()[1].GetAsString()); 953 EXPECT_EQ("https://*.google.com/*", 954 scripts[0].url_patterns()[2].GetAsString()); 955 EXPECT_EQ(2u, scripts[0].js_scripts().size()); 956 ExtensionResource resource00(extension->id(), 957 scripts[0].js_scripts()[0].extension_root(), 958 scripts[0].js_scripts()[0].relative_path()); 959 FilePath expected_path(extension->path().AppendASCII("script1.js")); 960 ASSERT_TRUE(file_util::AbsolutePath(&expected_path)); 961 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path)); 962 ExtensionResource resource01(extension->id(), 963 scripts[0].js_scripts()[1].extension_root(), 964 scripts[0].js_scripts()[1].relative_path()); 965 expected_path = extension->path().AppendASCII("script2.js"); 966 ASSERT_TRUE(file_util::AbsolutePath(&expected_path)); 967 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path)); 968 EXPECT_TRUE(extension->plugins().empty()); 969 EXPECT_EQ(1u, scripts[1].url_patterns().size()); 970 EXPECT_EQ("http://*.news.com/*", scripts[1].url_patterns()[0].GetAsString()); 971 ExtensionResource resource10(extension->id(), 972 scripts[1].js_scripts()[0].extension_root(), 973 scripts[1].js_scripts()[0].relative_path()); 974 expected_path = 975 extension->path().AppendASCII("js_files").AppendASCII("script3.js"); 976 ASSERT_TRUE(file_util::AbsolutePath(&expected_path)); 977 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path)); 978 const std::vector<URLPattern> permissions = extension->host_permissions(); 979 ASSERT_EQ(2u, permissions.size()); 980 EXPECT_EQ("http://*.google.com/*", permissions[0].GetAsString()); 981 EXPECT_EQ("https://*.google.com/*", permissions[1].GetAsString()); 982 983 EXPECT_EQ(std::string(good1), loaded_[1]->id()); 984 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name()); 985 EXPECT_EQ(std::string(""), loaded_[1]->description()); 986 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"), 987 loaded_[1]->background_url()); 988 EXPECT_EQ(0u, loaded_[1]->content_scripts().size()); 989 // We don't parse the plugins section on Chrome OS. 990 #if defined(OS_CHROMEOS) 991 EXPECT_EQ(0u, loaded_[1]->plugins().size()); 992 #else 993 ASSERT_EQ(2u, loaded_[1]->plugins().size()); 994 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(), 995 loaded_[1]->plugins()[0].path.value()); 996 EXPECT_TRUE(loaded_[1]->plugins()[0].is_public); 997 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(), 998 loaded_[1]->plugins()[1].path.value()); 999 EXPECT_FALSE(loaded_[1]->plugins()[1].is_public); 1000 #endif 1001 1002 EXPECT_EQ(Extension::INTERNAL, loaded_[1]->location()); 1003 1004 int index = expected_num_extensions - 1; 1005 EXPECT_EQ(std::string(good2), loaded_[index]->id()); 1006 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name()); 1007 EXPECT_EQ(std::string(""), loaded_[index]->description()); 1008 EXPECT_EQ(0u, loaded_[index]->content_scripts().size()); 1009 EXPECT_EQ(Extension::INTERNAL, loaded_[index]->location()); 1010 }; 1011 1012 // Test loading bad extensions from the profile directory. 1013 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) { 1014 // Initialize the test dir with a bad Preferences/extensions. 1015 FilePath source_install_dir = data_dir_ 1016 .AppendASCII("bad") 1017 .AppendASCII("Extensions"); 1018 FilePath pref_path = source_install_dir 1019 .DirName() 1020 .AppendASCII("Preferences"); 1021 1022 InitializeInstalledExtensionService(pref_path, source_install_dir); 1023 1024 service_->Init(); 1025 loop_.RunAllPending(); 1026 1027 ASSERT_EQ(4u, GetErrors().size()); 1028 ASSERT_EQ(0u, loaded_.size()); 1029 1030 EXPECT_TRUE(MatchPattern(GetErrors()[0], 1031 std::string("Could not load extension from '*'. ") + 1032 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[0]; 1033 1034 EXPECT_TRUE(MatchPattern(GetErrors()[1], 1035 std::string("Could not load extension from '*'. ") + 1036 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[1]; 1037 1038 EXPECT_TRUE(MatchPattern(GetErrors()[2], 1039 std::string("Could not load extension from '*'. ") + 1040 extension_manifest_errors::kMissingFile)) << GetErrors()[2]; 1041 1042 EXPECT_TRUE(MatchPattern(GetErrors()[3], 1043 std::string("Could not load extension from '*'. ") + 1044 extension_manifest_errors::kManifestUnreadable)) << GetErrors()[3]; 1045 }; 1046 1047 // Test that partially deleted extensions are cleaned up during startup 1048 // Test loading bad extensions from the profile directory. 1049 TEST_F(ExtensionServiceTest, CleanupOnStartup) { 1050 FilePath source_install_dir = data_dir_ 1051 .AppendASCII("good") 1052 .AppendASCII("Extensions"); 1053 FilePath pref_path = source_install_dir 1054 .DirName() 1055 .AppendASCII("Preferences"); 1056 1057 InitializeInstalledExtensionService(pref_path, source_install_dir); 1058 1059 // Simulate that one of them got partially deleted by clearing its pref. 1060 { 1061 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings"); 1062 DictionaryValue* dict = update.Get(); 1063 ASSERT_TRUE(dict != NULL); 1064 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL); 1065 } 1066 1067 service_->Init(); 1068 loop_.RunAllPending(); 1069 1070 file_util::FileEnumerator dirs(extensions_install_dir_, false, 1071 file_util::FileEnumerator::DIRECTORIES); 1072 size_t count = 0; 1073 while (!dirs.Next().empty()) 1074 count++; 1075 1076 // We should have only gotten two extensions now. 1077 EXPECT_EQ(2u, count); 1078 1079 // And extension1 dir should now be toast. 1080 FilePath extension_dir = extensions_install_dir_ 1081 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj"); 1082 ASSERT_FALSE(file_util::PathExists(extension_dir)); 1083 } 1084 1085 // Test installing extensions. This test tries to install few extensions using 1086 // crx files. If you need to change those crx files, feel free to repackage 1087 // them, throw away the key used and change the id's above. 1088 TEST_F(ExtensionServiceTest, InstallExtension) { 1089 InitializeEmptyExtensionService(); 1090 1091 // Extensions not enabled. 1092 set_extensions_enabled(false); 1093 FilePath path = data_dir_.AppendASCII("good.crx"); 1094 InstallCrx(path, false); 1095 set_extensions_enabled(true); 1096 1097 ValidatePrefKeyCount(0); 1098 1099 // A simple extension that should install without error. 1100 path = data_dir_.AppendASCII("good.crx"); 1101 InstallCrx(path, true); 1102 // TODO(erikkay): verify the contents of the installed extension. 1103 1104 int pref_count = 0; 1105 ValidatePrefKeyCount(++pref_count); 1106 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 1107 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL); 1108 1109 // An extension with page actions. 1110 path = data_dir_.AppendASCII("page_action.crx"); 1111 InstallCrx(path, true); 1112 ValidatePrefKeyCount(++pref_count); 1113 ValidateIntegerPref(page_action, "state", Extension::ENABLED); 1114 ValidateIntegerPref(page_action, "location", Extension::INTERNAL); 1115 1116 // Bad signature. 1117 path = data_dir_.AppendASCII("bad_signature.crx"); 1118 InstallCrx(path, false); 1119 ValidatePrefKeyCount(pref_count); 1120 1121 // 0-length extension file. 1122 path = data_dir_.AppendASCII("not_an_extension.crx"); 1123 InstallCrx(path, false); 1124 ValidatePrefKeyCount(pref_count); 1125 1126 // Bad magic number. 1127 path = data_dir_.AppendASCII("bad_magic.crx"); 1128 InstallCrx(path, false); 1129 ValidatePrefKeyCount(pref_count); 1130 1131 // Extensions cannot have folders or files that have underscores except in 1132 // certain whitelisted cases (eg _locales). This is an example of a broader 1133 // class of validation that we do to the directory structure of the extension. 1134 // We did not used to handle this correctly for installation. 1135 path = data_dir_.AppendASCII("bad_underscore.crx"); 1136 InstallCrx(path, false); 1137 ValidatePrefKeyCount(pref_count); 1138 1139 // TODO(erikkay): add more tests for many of the failure cases. 1140 // TODO(erikkay): add tests for upgrade cases. 1141 } 1142 1143 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED 1144 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) { 1145 InitializeEmptyExtensionService(); 1146 1147 FilePath path = data_dir_.AppendASCII("good.crx"); 1148 set_extensions_enabled(true); 1149 1150 scoped_ptr<Version> version; 1151 version.reset(Version::GetVersionFromString("1.0.0.0")); 1152 // Install an external extension. 1153 service_->OnExternalExtensionFileFound(good_crx, version.get(), 1154 path, Extension::EXTERNAL_PREF); 1155 loop_.RunAllPending(); 1156 ASSERT_TRUE(service_->GetExtensionById(good_crx, false)); 1157 1158 // Uninstall it and check that its killbit gets set. 1159 service_->UninstallExtension(good_crx, false, NULL); 1160 loop_.RunAllPending(); 1161 ValidateIntegerPref(good_crx, "location", 1162 Extension::EXTERNAL_EXTENSION_UNINSTALLED); 1163 1164 // Try to re-install it externally. This should fail because of the killbit. 1165 service_->OnExternalExtensionFileFound(good_crx, version.get(), 1166 path, Extension::EXTERNAL_PREF); 1167 loop_.RunAllPending(); 1168 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false)); 1169 ValidateIntegerPref(good_crx, "location", 1170 Extension::EXTERNAL_EXTENSION_UNINSTALLED); 1171 1172 version.reset(Version::GetVersionFromString("1.0.0.1")); 1173 // Repeat the same thing with a newer version of the extension. 1174 path = data_dir_.AppendASCII("good2.crx"); 1175 service_->OnExternalExtensionFileFound(good_crx, version.get(), 1176 path, Extension::EXTERNAL_PREF); 1177 loop_.RunAllPending(); 1178 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false)); 1179 ValidateIntegerPref(good_crx, "location", 1180 Extension::EXTERNAL_EXTENSION_UNINSTALLED); 1181 1182 // Try adding the same extension from an external update URL. 1183 service_->pending_extension_manager()->AddFromExternalUpdateUrl( 1184 good_crx, 1185 GURL("http:://fake.update/url"), 1186 Extension::EXTERNAL_PREF_DOWNLOAD); 1187 1188 ASSERT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx)); 1189 } 1190 1191 // Test that external extensions with incorrect IDs are not installed. 1192 TEST_F(ExtensionServiceTest, FailOnWrongId) { 1193 InitializeEmptyExtensionService(); 1194 FilePath path = data_dir_.AppendASCII("good.crx"); 1195 set_extensions_enabled(true); 1196 1197 scoped_ptr<Version> version; 1198 version.reset(Version::GetVersionFromString("1.0.0.0")); 1199 1200 const std::string wrong_id = all_zero; 1201 const std::string correct_id = good_crx; 1202 ASSERT_NE(correct_id, wrong_id); 1203 1204 // Install an external extension with an ID from the external 1205 // source that is not equal to the ID in the extension manifest. 1206 service_->OnExternalExtensionFileFound( 1207 wrong_id, version.get(), path, Extension::EXTERNAL_PREF); 1208 1209 loop_.RunAllPending(); 1210 ASSERT_FALSE(service_->GetExtensionById(good_crx, false)); 1211 1212 // Try again with the right ID. Expect success. 1213 service_->OnExternalExtensionFileFound( 1214 correct_id, version.get(), path, Extension::EXTERNAL_PREF); 1215 loop_.RunAllPending(); 1216 ASSERT_TRUE(service_->GetExtensionById(good_crx, false)); 1217 } 1218 1219 // Test that external extensions with incorrect versions are not installed. 1220 TEST_F(ExtensionServiceTest, FailOnWrongVersion) { 1221 InitializeEmptyExtensionService(); 1222 FilePath path = data_dir_.AppendASCII("good.crx"); 1223 set_extensions_enabled(true); 1224 1225 // Install an external extension with a version from the external 1226 // source that is not equal to the version in the extension manifest. 1227 scoped_ptr<Version> wrong_version; 1228 wrong_version.reset(Version::GetVersionFromString("1.2.3.4")); 1229 service_->OnExternalExtensionFileFound( 1230 good_crx, wrong_version.get(), path, Extension::EXTERNAL_PREF); 1231 1232 loop_.RunAllPending(); 1233 ASSERT_FALSE(service_->GetExtensionById(good_crx, false)); 1234 1235 // Try again with the right version. Expect success. 1236 scoped_ptr<Version> correct_version; 1237 correct_version.reset(Version::GetVersionFromString("1.0.0.0")); 1238 service_->OnExternalExtensionFileFound( 1239 good_crx, correct_version.get(), path, Extension::EXTERNAL_PREF); 1240 loop_.RunAllPending(); 1241 ASSERT_TRUE(service_->GetExtensionById(good_crx, false)); 1242 } 1243 1244 // Install a user script (they get converted automatically to an extension) 1245 TEST_F(ExtensionServiceTest, InstallUserScript) { 1246 // The details of script conversion are tested elsewhere, this just tests 1247 // integration with ExtensionService. 1248 InitializeEmptyExtensionService(); 1249 1250 FilePath path = data_dir_ 1251 .AppendASCII("user_script_basic.user.js"); 1252 1253 ASSERT_TRUE(file_util::PathExists(path)); 1254 scoped_refptr<CrxInstaller> installer( 1255 new CrxInstaller(service_, NULL)); // silent install 1256 installer->InstallUserScript( 1257 path, 1258 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js")); 1259 1260 loop_.RunAllPending(); 1261 std::vector<std::string> errors = GetErrors(); 1262 EXPECT_TRUE(installed_) << "Nothing was installed."; 1263 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded."; 1264 EXPECT_EQ(0u, errors.size()) << "There were errors: " 1265 << JoinString(errors, ','); 1266 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) << 1267 path.value(); 1268 1269 installed_ = NULL; 1270 loaded_.clear(); 1271 ExtensionErrorReporter::GetInstance()->ClearErrors(); 1272 } 1273 1274 // This tests that the granted permissions preferences are correctly set when 1275 // installing an extension. 1276 TEST_F(ExtensionServiceTest, GrantedPermissions) { 1277 InitializeEmptyExtensionService(); 1278 FilePath path = data_dir_ 1279 .AppendASCII("permissions"); 1280 1281 FilePath pem_path = path.AppendASCII("unknown.pem"); 1282 path = path.AppendASCII("unknown"); 1283 1284 ASSERT_TRUE(file_util::PathExists(pem_path)); 1285 ASSERT_TRUE(file_util::PathExists(path)); 1286 1287 ExtensionPrefs* prefs = service_->extension_prefs(); 1288 1289 std::set<std::string> expected_api_perms; 1290 std::set<std::string> known_api_perms; 1291 bool full_access; 1292 ExtensionExtent expected_host_perms; 1293 ExtensionExtent known_host_perms; 1294 1295 // Make sure there aren't any granted permissions before the 1296 // extension is installed. 1297 EXPECT_FALSE(prefs->GetGrantedPermissions( 1298 permissions_crx, &full_access, &known_api_perms, &known_host_perms)); 1299 EXPECT_TRUE(known_api_perms.empty()); 1300 EXPECT_TRUE(known_host_perms.is_empty()); 1301 1302 PackAndInstallCrx(path, pem_path, true); 1303 1304 EXPECT_EQ(0u, GetErrors().size()); 1305 ASSERT_EQ(1u, service_->extensions()->size()); 1306 std::string extension_id = service_->extensions()->at(0)->id(); 1307 EXPECT_EQ(permissions_crx, extension_id); 1308 1309 1310 // Verify that the valid API permissions have been recognized. 1311 expected_api_perms.insert("tabs"); 1312 1313 AddPattern(&expected_host_perms, "http://*.google.com/*"); 1314 AddPattern(&expected_host_perms, "https://*.google.com/*"); 1315 AddPattern(&expected_host_perms, "http://*.google.com.hk/*"); 1316 AddPattern(&expected_host_perms, "http://www.example.com/*"); 1317 1318 EXPECT_TRUE(prefs->GetGrantedPermissions(extension_id, 1319 &full_access, 1320 &known_api_perms, 1321 &known_host_perms)); 1322 1323 EXPECT_EQ(expected_api_perms, known_api_perms); 1324 EXPECT_FALSE(full_access); 1325 AssertEqualExtents(&expected_host_perms, &known_host_perms); 1326 } 1327 1328 #if !defined(OS_CHROMEOS) 1329 // Tests that the granted permissions full_access bit gets set correctly when 1330 // an extension contains an NPAPI plugin. Don't run this test on Chrome OS 1331 // since they don't support plugins. 1332 TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) { 1333 InitializeEmptyExtensionService(); 1334 1335 FilePath path = data_dir_ 1336 .AppendASCII("good") 1337 .AppendASCII("Extensions") 1338 .AppendASCII(good1) 1339 .AppendASCII("2"); 1340 1341 ASSERT_TRUE(file_util::PathExists(path)); 1342 1343 PackAndInstallCrx(path, true); 1344 1345 EXPECT_EQ(0u, GetErrors().size()); 1346 EXPECT_EQ(1u, service_->extensions()->size()); 1347 const Extension* extension = service_->extensions()->at(0); 1348 std::string extension_id = extension->id(); 1349 ExtensionPrefs* prefs = service_->extension_prefs(); 1350 1351 bool full_access; 1352 std::set<std::string> api_permissions; 1353 ExtensionExtent host_permissions; 1354 EXPECT_TRUE(prefs->GetGrantedPermissions( 1355 extension_id, &full_access, &api_permissions, &host_permissions)); 1356 1357 EXPECT_TRUE(full_access); 1358 EXPECT_TRUE(api_permissions.empty()); 1359 EXPECT_TRUE(host_permissions.is_empty()); 1360 } 1361 #endif 1362 1363 // Tests that the extension is disabled when permissions are missing from 1364 // the extension's granted permissions preferences. (This simulates updating 1365 // the browser to a version which recognizes more permissions). 1366 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) { 1367 InitializeEmptyExtensionService(); 1368 1369 FilePath path = data_dir_ 1370 .AppendASCII("permissions") 1371 .AppendASCII("unknown"); 1372 1373 ASSERT_TRUE(file_util::PathExists(path)); 1374 1375 PackAndInstallCrx(path, true); 1376 1377 EXPECT_EQ(0u, GetErrors().size()); 1378 EXPECT_EQ(1u, service_->extensions()->size()); 1379 const Extension* extension = service_->extensions()->at(0); 1380 std::string extension_id = extension->id(); 1381 1382 ExtensionPrefs* prefs = service_->extension_prefs(); 1383 1384 std::set<std::string> expected_api_permissions; 1385 ExtensionExtent expected_host_permissions; 1386 1387 expected_api_permissions.insert("tabs"); 1388 AddPattern(&expected_host_permissions, "http://*.google.com/*"); 1389 AddPattern(&expected_host_permissions, "https://*.google.com/*"); 1390 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*"); 1391 AddPattern(&expected_host_permissions, "http://www.example.com/*"); 1392 1393 std::set<std::string> api_permissions; 1394 std::set<std::string> host_permissions; 1395 1396 // Test that the extension is disabled when an API permission is missing from 1397 // the extension's granted api permissions preference. (This simulates 1398 // updating the browser to a version which recognizes a new API permission). 1399 SetPrefStringSet(extension_id, "granted_permissions.api", api_permissions); 1400 1401 service_->ReloadExtensions(); 1402 1403 EXPECT_EQ(1u, service_->disabled_extensions()->size()); 1404 extension = service_->disabled_extensions()->at(0); 1405 1406 ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::DISABLED); 1407 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id)); 1408 1409 // Now grant and re-enable the extension, making sure the prefs are updated. 1410 service_->GrantPermissionsAndEnableExtension(extension); 1411 1412 ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED); 1413 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id)); 1414 1415 std::set<std::string> current_api_permissions; 1416 ExtensionExtent current_host_permissions; 1417 bool current_full_access; 1418 1419 ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id, 1420 ¤t_full_access, 1421 ¤t_api_permissions, 1422 ¤t_host_permissions)); 1423 1424 ASSERT_FALSE(current_full_access); 1425 ASSERT_EQ(expected_api_permissions, current_api_permissions); 1426 AssertEqualExtents(&expected_host_permissions, ¤t_host_permissions); 1427 1428 // Tests that the extension is disabled when a host permission is missing from 1429 // the extension's granted host permissions preference. (This simulates 1430 // updating the browser to a version which recognizes additional host 1431 // permissions). 1432 api_permissions.clear(); 1433 host_permissions.clear(); 1434 current_api_permissions.clear(); 1435 current_host_permissions.ClearPaths(); 1436 1437 api_permissions.insert("tabs"); 1438 host_permissions.insert("http://*.google.com/*"); 1439 host_permissions.insert("https://*.google.com/*"); 1440 host_permissions.insert("http://*.google.com.hk/*"); 1441 1442 SetPrefStringSet(extension_id, "granted_permissions.api", api_permissions); 1443 SetPrefStringSet(extension_id, "granted_permissions.host", host_permissions); 1444 1445 service_->ReloadExtensions(); 1446 1447 EXPECT_EQ(1u, service_->disabled_extensions()->size()); 1448 extension = service_->disabled_extensions()->at(0); 1449 1450 ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::DISABLED); 1451 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id)); 1452 1453 // Now grant and re-enable the extension, making sure the prefs are updated. 1454 service_->GrantPermissionsAndEnableExtension(extension); 1455 1456 ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED); 1457 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id)); 1458 1459 ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id, 1460 ¤t_full_access, 1461 ¤t_api_permissions, 1462 ¤t_host_permissions)); 1463 1464 ASSERT_FALSE(current_full_access); 1465 ASSERT_EQ(expected_api_permissions, current_api_permissions); 1466 AssertEqualExtents(&expected_host_permissions, ¤t_host_permissions); 1467 1468 // Tests that the granted permissions preferences are initialized when 1469 // migrating from the old pref schema. 1470 current_api_permissions.clear(); 1471 current_host_permissions.ClearPaths(); 1472 1473 ClearPref(extension_id, "granted_permissions"); 1474 1475 service_->ReloadExtensions(); 1476 1477 EXPECT_EQ(1u, service_->extensions()->size()); 1478 extension = service_->extensions()->at(0); 1479 1480 ASSERT_TRUE(prefs->GetExtensionState(extension_id) == Extension::ENABLED); 1481 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id)); 1482 1483 ASSERT_TRUE(prefs->GetGrantedPermissions(extension_id, 1484 ¤t_full_access, 1485 ¤t_api_permissions, 1486 ¤t_host_permissions)); 1487 1488 ASSERT_FALSE(current_full_access); 1489 ASSERT_EQ(expected_api_permissions, current_api_permissions); 1490 AssertEqualExtents(&expected_host_permissions, ¤t_host_permissions); 1491 } 1492 1493 // Test Packaging and installing an extension. 1494 TEST_F(ExtensionServiceTest, PackExtension) { 1495 InitializeEmptyExtensionService(); 1496 FilePath input_directory = data_dir_ 1497 .AppendASCII("good") 1498 .AppendASCII("Extensions") 1499 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 1500 .AppendASCII("1.0.0.0"); 1501 1502 ScopedTempDir temp_dir; 1503 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1504 FilePath output_directory = temp_dir.path(); 1505 1506 FilePath crx_path(output_directory.AppendASCII("ex1.crx")); 1507 FilePath privkey_path(output_directory.AppendASCII("privkey.pem")); 1508 1509 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); 1510 ASSERT_TRUE(creator->Run(input_directory, crx_path, FilePath(), 1511 privkey_path)); 1512 1513 ASSERT_TRUE(file_util::PathExists(privkey_path)); 1514 InstallCrx(crx_path, true); 1515 1516 // Try packing with invalid paths. 1517 creator.reset(new ExtensionCreator()); 1518 ASSERT_FALSE(creator->Run(FilePath(), FilePath(), FilePath(), FilePath())); 1519 1520 // Try packing an empty directory. Should fail because an empty directory is 1521 // not a valid extension. 1522 ScopedTempDir temp_dir2; 1523 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir()); 1524 creator.reset(new ExtensionCreator()); 1525 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path, 1526 FilePath())); 1527 1528 // Try packing with an invalid manifest. 1529 std::string invalid_manifest_content = "I am not a manifest."; 1530 ASSERT_TRUE(file_util::WriteFile( 1531 temp_dir2.path().Append(Extension::kManifestFilename), 1532 invalid_manifest_content.c_str(), invalid_manifest_content.size())); 1533 creator.reset(new ExtensionCreator()); 1534 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path, 1535 FilePath())); 1536 } 1537 1538 // Test Packaging and installing an extension whose name contains punctuation. 1539 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) { 1540 InitializeEmptyExtensionService(); 1541 FilePath input_directory = data_dir_ 1542 .AppendASCII("good") 1543 .AppendASCII("Extensions") 1544 .AppendASCII(good0) 1545 .AppendASCII("1.0.0.0"); 1546 1547 ScopedTempDir temp_dir; 1548 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1549 1550 // Extension names containing punctuation, and the expected names for the 1551 // packed extensions. 1552 const FilePath punctuated_names[] = { 1553 FilePath(FilePath::StringType( 1554 FILE_PATH_LITERAL("this.extensions.name.has.periods"))), 1555 FilePath(FilePath::StringType( 1556 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod"))), 1557 NormalizeSeparators(FilePath(FilePath::StringType( 1558 FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")))), 1559 }; 1560 const FilePath expected_crx_names[] = { 1561 FilePath(FilePath::StringType( 1562 FILE_PATH_LITERAL("this.extensions.name.has.periods.crx"))), 1563 FilePath(FilePath::StringType( 1564 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx"))), 1565 FilePath(FilePath::StringType( 1566 FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx"))), 1567 }; 1568 const FilePath expected_private_key_names[] = { 1569 FilePath(FilePath::StringType( 1570 FILE_PATH_LITERAL("this.extensions.name.has.periods.pem"))), 1571 FilePath(FilePath::StringType( 1572 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem"))), 1573 FilePath(FilePath::StringType( 1574 FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem"))), 1575 }; 1576 1577 for (size_t i = 0; i < arraysize(punctuated_names); ++i) { 1578 SCOPED_TRACE(punctuated_names[i].value().c_str()); 1579 FilePath output_dir = temp_dir.path().Append(punctuated_names[i]); 1580 1581 // Copy the extension into the output directory, as PackExtensionJob doesn't 1582 // let us choose where to output the packed extension. 1583 ASSERT_TRUE(file_util::CopyDirectory(input_directory, output_dir, true)); 1584 1585 FilePath expected_crx_path = temp_dir.path().Append(expected_crx_names[i]); 1586 FilePath expected_private_key_path = 1587 temp_dir.path().Append(expected_private_key_names[i]); 1588 PackExtensionTestClient pack_client(expected_crx_path, 1589 expected_private_key_path); 1590 scoped_refptr<PackExtensionJob> packer(new PackExtensionJob(&pack_client, 1591 output_dir, 1592 FilePath())); 1593 packer->Start(); 1594 1595 // The packer will post a notification task to the current thread's message 1596 // loop when it is finished. We manually run the loop here so that we 1597 // block and catch the notification; otherwise, the process would exit. 1598 // This call to |Run()| is matched by a call to |Quit()| in the 1599 // |PackExtensionTestClient|'s notification handling code. 1600 MessageLoop::current()->Run(); 1601 1602 if (HasFatalFailure()) 1603 return; 1604 1605 InstallCrx(expected_crx_path, true); 1606 } 1607 } 1608 1609 // Test Packaging and installing an extension using an openssl generated key. 1610 // The openssl is generated with the following: 1611 // > openssl genrsa -out privkey.pem 1024 1612 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem 1613 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a 1614 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects. 1615 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) { 1616 InitializeEmptyExtensionService(); 1617 FilePath input_directory = data_dir_ 1618 .AppendASCII("good") 1619 .AppendASCII("Extensions") 1620 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 1621 .AppendASCII("1.0.0.0"); 1622 FilePath privkey_path(data_dir_.AppendASCII( 1623 "openssl_privkey_asn1.pem")); 1624 ASSERT_TRUE(file_util::PathExists(privkey_path)); 1625 1626 ScopedTempDir temp_dir; 1627 ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); 1628 FilePath output_directory = temp_dir.path(); 1629 1630 FilePath crx_path(output_directory.AppendASCII("ex1.crx")); 1631 1632 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator()); 1633 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path, 1634 FilePath())); 1635 1636 InstallCrx(crx_path, true); 1637 } 1638 1639 TEST_F(ExtensionServiceTest, InstallTheme) { 1640 InitializeEmptyExtensionService(); 1641 1642 // A theme. 1643 FilePath path = data_dir_.AppendASCII("theme.crx"); 1644 InstallCrx(path, true); 1645 int pref_count = 0; 1646 ValidatePrefKeyCount(++pref_count); 1647 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED); 1648 ValidateIntegerPref(theme_crx, "location", Extension::INTERNAL); 1649 1650 // A theme when extensions are disabled. Themes can be installed, even when 1651 // extensions are disabled. 1652 set_extensions_enabled(false); 1653 path = data_dir_.AppendASCII("theme2.crx"); 1654 InstallCrx(path, true); 1655 ValidatePrefKeyCount(++pref_count); 1656 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED); 1657 ValidateIntegerPref(theme2_crx, "location", Extension::INTERNAL); 1658 1659 // A theme with extension elements. Themes cannot have extension elements so 1660 // this test should fail. 1661 set_extensions_enabled(true); 1662 path = data_dir_.AppendASCII("theme_with_extension.crx"); 1663 InstallCrx(path, false); 1664 ValidatePrefKeyCount(pref_count); 1665 1666 // A theme with image resources missing (misspelt path). 1667 path = data_dir_.AppendASCII("theme_missing_image.crx"); 1668 InstallCrx(path, false); 1669 ValidatePrefKeyCount(pref_count); 1670 } 1671 1672 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) { 1673 // Load. 1674 InitializeEmptyExtensionService(); 1675 FilePath extension_path = data_dir_ 1676 .AppendASCII("theme_i18n"); 1677 1678 service_->LoadExtension(extension_path); 1679 loop_.RunAllPending(); 1680 EXPECT_EQ(0u, GetErrors().size()); 1681 ASSERT_EQ(1u, loaded_.size()); 1682 EXPECT_EQ(1u, service_->extensions()->size()); 1683 EXPECT_EQ("name", service_->extensions()->at(0)->name()); 1684 EXPECT_EQ("description", service_->extensions()->at(0)->description()); 1685 } 1686 1687 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) { 1688 InitializeEmptyExtensionService(); 1689 FilePath theme_path = data_dir_ 1690 .AppendASCII("theme_i18n"); 1691 1692 PackAndInstallCrx(theme_path, true); 1693 1694 EXPECT_EQ(0u, GetErrors().size()); 1695 EXPECT_EQ(1u, service_->extensions()->size()); 1696 EXPECT_EQ("name", service_->extensions()->at(0)->name()); 1697 EXPECT_EQ("description", service_->extensions()->at(0)->description()); 1698 } 1699 1700 TEST_F(ExtensionServiceTest, InstallApps) { 1701 InitializeEmptyExtensionService(); 1702 1703 // An empty app. 1704 PackAndInstallCrx(data_dir_.AppendASCII("app1"), true); 1705 int pref_count = 0; 1706 ValidatePrefKeyCount(++pref_count); 1707 ASSERT_EQ(1u, service_->extensions()->size()); 1708 std::string id = service_->extensions()->at(0)->id(); 1709 ValidateIntegerPref(id, "state", Extension::ENABLED); 1710 ValidateIntegerPref(id, "location", Extension::INTERNAL); 1711 1712 // Another app with non-overlapping extent. Should succeed. 1713 PackAndInstallCrx(data_dir_.AppendASCII("app2"), true); 1714 ValidatePrefKeyCount(++pref_count); 1715 1716 // A third app whose extent overlaps the first. Should fail. 1717 PackAndInstallCrx(data_dir_.AppendASCII("app3"), false); 1718 ValidatePrefKeyCount(pref_count); 1719 } 1720 1721 TEST_F(ExtensionServiceTest, UpdateApps) { 1722 InitializeEmptyExtensionService(); 1723 FilePath extensions_path = data_dir_.AppendASCII("app_update"); 1724 1725 // First install v1 of a hosted app. 1726 InstallCrx(extensions_path.AppendASCII("v1.crx"), true); 1727 ASSERT_EQ(1u, service_->extensions()->size()); 1728 std::string id = service_->extensions()->at(0)->id(); 1729 ASSERT_EQ(std::string("1"), 1730 service_->extensions()->at(0)->version()->GetString()); 1731 1732 // Now try updating to v2. 1733 UpdateExtension(id, 1734 extensions_path.AppendASCII("v2.crx"), 1735 ENABLED); 1736 ASSERT_EQ(std::string("2"), 1737 service_->extensions()->at(0)->version()->GetString()); 1738 } 1739 1740 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimtedStorage) { 1741 InitializeEmptyExtensionService(); 1742 EXPECT_TRUE(service_->extensions()->empty()); 1743 1744 int pref_count = 0; 1745 1746 // Install app1 with unlimited storage. 1747 PackAndInstallCrx(data_dir_.AppendASCII("app1"), true); 1748 ValidatePrefKeyCount(++pref_count); 1749 ASSERT_EQ(1u, service_->extensions()->size()); 1750 const Extension* extension = service_->extensions()->at(0); 1751 const std::string id1 = extension->id(); 1752 EXPECT_TRUE(extension->HasApiPermission( 1753 Extension::kUnlimitedStoragePermission)); 1754 EXPECT_TRUE(extension->web_extent().ContainsURL( 1755 extension->GetFullLaunchURL())); 1756 const GURL origin1(extension->GetFullLaunchURL().GetOrigin()); 1757 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()-> 1758 IsStorageUnlimited(origin1)); 1759 1760 // Install app2 from the same origin with unlimited storage. 1761 PackAndInstallCrx(data_dir_.AppendASCII("app2"), true); 1762 ValidatePrefKeyCount(++pref_count); 1763 ASSERT_EQ(2u, service_->extensions()->size()); 1764 extension = service_->extensions()->at(1); 1765 const std::string id2 = extension->id(); 1766 EXPECT_TRUE(extension->HasApiPermission( 1767 Extension::kUnlimitedStoragePermission)); 1768 EXPECT_TRUE(extension->web_extent().ContainsURL( 1769 extension->GetFullLaunchURL())); 1770 const GURL origin2(extension->GetFullLaunchURL().GetOrigin()); 1771 EXPECT_EQ(origin1, origin2); 1772 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()-> 1773 IsStorageUnlimited(origin2)); 1774 1775 1776 // Uninstall one of them, unlimited storage should still be granted 1777 // to the origin. 1778 service_->UninstallExtension(id1, false, NULL); 1779 loop_.RunAllPending(); 1780 EXPECT_EQ(1u, service_->extensions()->size()); 1781 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()-> 1782 IsStorageUnlimited(origin1)); 1783 1784 1785 // Uninstall the other, unlimited storage should be revoked. 1786 service_->UninstallExtension(id2, false, NULL); 1787 loop_.RunAllPending(); 1788 EXPECT_EQ(0u, service_->extensions()->size()); 1789 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()-> 1790 IsStorageUnlimited(origin2)); 1791 } 1792 1793 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) { 1794 InitializeEmptyExtensionService(); 1795 EXPECT_TRUE(service_->extensions()->empty()); 1796 1797 int pref_count = 0; 1798 1799 PackAndInstallCrx(data_dir_.AppendASCII("app1"), true); 1800 ValidatePrefKeyCount(++pref_count); 1801 ASSERT_EQ(1u, service_->extensions()->size()); 1802 const Extension* extension = service_->extensions()->at(0); 1803 EXPECT_TRUE(extension->is_app()); 1804 const std::string id1 = extension->id(); 1805 const GURL origin1(extension->GetFullLaunchURL().GetOrigin()); 1806 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()-> 1807 IsStorageProtected(origin1)); 1808 1809 // App 4 has a different origin (maps.google.com). 1810 PackAndInstallCrx(data_dir_.AppendASCII("app4"), true); 1811 ValidatePrefKeyCount(++pref_count); 1812 ASSERT_EQ(2u, service_->extensions()->size()); 1813 extension = service_->extensions()->at(1); 1814 const std::string id2 = extension->id(); 1815 const GURL origin2(extension->GetFullLaunchURL().GetOrigin()); 1816 ASSERT_NE(origin1, origin2); 1817 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()-> 1818 IsStorageProtected(origin2)); 1819 1820 service_->UninstallExtension(id1, false, NULL); 1821 loop_.RunAllPending(); 1822 EXPECT_EQ(1u, service_->extensions()->size()); 1823 1824 service_->UninstallExtension(id2, false, NULL); 1825 loop_.RunAllPending(); 1826 1827 EXPECT_TRUE(service_->extensions()->empty()); 1828 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()-> 1829 IsStorageProtected(origin1)); 1830 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()-> 1831 IsStorageProtected(origin2)); 1832 } 1833 1834 // Test that when an extension version is reinstalled, nothing happens. 1835 TEST_F(ExtensionServiceTest, Reinstall) { 1836 InitializeEmptyExtensionService(); 1837 1838 // A simple extension that should install without error. 1839 FilePath path = data_dir_.AppendASCII("good.crx"); 1840 StartCrxInstall(path); 1841 loop_.RunAllPending(); 1842 1843 ASSERT_TRUE(installed_); 1844 ASSERT_EQ(1u, loaded_.size()); 1845 ASSERT_EQ(0u, GetErrors().size()); 1846 ValidatePrefKeyCount(1); 1847 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 1848 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL); 1849 1850 installed_ = NULL; 1851 loaded_.clear(); 1852 ExtensionErrorReporter::GetInstance()->ClearErrors(); 1853 1854 // Reinstall the same version, it should overwrite the previous one. 1855 StartCrxInstall(path); 1856 loop_.RunAllPending(); 1857 1858 ASSERT_TRUE(installed_); 1859 ASSERT_EQ(1u, loaded_.size()); 1860 ASSERT_EQ(0u, GetErrors().size()); 1861 ValidatePrefKeyCount(1); 1862 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 1863 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL); 1864 } 1865 1866 // Test upgrading a signed extension. 1867 TEST_F(ExtensionServiceTest, UpgradeSignedGood) { 1868 InitializeEmptyExtensionService(); 1869 1870 FilePath path = data_dir_.AppendASCII("good.crx"); 1871 StartCrxInstall(path); 1872 loop_.RunAllPending(); 1873 1874 ASSERT_TRUE(installed_); 1875 ASSERT_EQ(1u, loaded_.size()); 1876 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString()); 1877 ASSERT_EQ(0u, GetErrors().size()); 1878 1879 // Upgrade to version 2.0 1880 path = data_dir_.AppendASCII("good2.crx"); 1881 StartCrxInstall(path); 1882 loop_.RunAllPending(); 1883 1884 ASSERT_TRUE(installed_); 1885 ASSERT_EQ(1u, loaded_.size()); 1886 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString()); 1887 ASSERT_EQ(0u, GetErrors().size()); 1888 } 1889 1890 // Test upgrading a signed extension with a bad signature. 1891 TEST_F(ExtensionServiceTest, UpgradeSignedBad) { 1892 InitializeEmptyExtensionService(); 1893 1894 FilePath path = data_dir_.AppendASCII("good.crx"); 1895 StartCrxInstall(path); 1896 loop_.RunAllPending(); 1897 1898 ASSERT_TRUE(installed_); 1899 ASSERT_EQ(1u, loaded_.size()); 1900 ASSERT_EQ(0u, GetErrors().size()); 1901 installed_ = NULL; 1902 1903 // Try upgrading with a bad signature. This should fail during the unpack, 1904 // because the key will not match the signature. 1905 path = data_dir_.AppendASCII("bad_signature.crx"); 1906 StartCrxInstall(path); 1907 loop_.RunAllPending(); 1908 1909 ASSERT_FALSE(installed_); 1910 ASSERT_EQ(1u, loaded_.size()); 1911 ASSERT_EQ(1u, GetErrors().size()); 1912 } 1913 1914 // Test a normal update via the UpdateExtension API 1915 TEST_F(ExtensionServiceTest, UpdateExtension) { 1916 InitializeEmptyExtensionService(); 1917 1918 FilePath path = data_dir_.AppendASCII("good.crx"); 1919 1920 InstallCrx(path, true); 1921 const Extension* good = service_->extensions()->at(0); 1922 ASSERT_EQ("1.0.0.0", good->VersionString()); 1923 ASSERT_EQ(good_crx, good->id()); 1924 1925 path = data_dir_.AppendASCII("good2.crx"); 1926 UpdateExtension(good_crx, path, ENABLED); 1927 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString()); 1928 } 1929 1930 // Test updating a not-already-installed extension - this should fail 1931 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) { 1932 InitializeEmptyExtensionService(); 1933 1934 FilePath path = data_dir_.AppendASCII("good.crx"); 1935 UpdateExtension(good_crx, path, UPDATED); 1936 loop_.RunAllPending(); 1937 1938 ASSERT_EQ(0u, service_->extensions()->size()); 1939 ASSERT_FALSE(installed_); 1940 ASSERT_EQ(0u, loaded_.size()); 1941 } 1942 1943 // Makes sure you can't downgrade an extension via UpdateExtension 1944 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) { 1945 InitializeEmptyExtensionService(); 1946 1947 FilePath path = data_dir_.AppendASCII("good2.crx"); 1948 1949 InstallCrx(path, true); 1950 const Extension* good = service_->extensions()->at(0); 1951 ASSERT_EQ("1.0.0.1", good->VersionString()); 1952 ASSERT_EQ(good_crx, good->id()); 1953 1954 // Change path from good2.crx -> good.crx 1955 path = data_dir_.AppendASCII("good.crx"); 1956 UpdateExtension(good_crx, path, FAILED); 1957 ASSERT_EQ("1.0.0.1", service_->extensions()->at(0)->VersionString()); 1958 } 1959 1960 // Make sure calling update with an identical version does nothing 1961 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) { 1962 InitializeEmptyExtensionService(); 1963 1964 FilePath path = data_dir_.AppendASCII("good.crx"); 1965 1966 InstallCrx(path, true); 1967 const Extension* good = service_->extensions()->at(0); 1968 ASSERT_EQ(good_crx, good->id()); 1969 UpdateExtension(good_crx, path, FAILED_SILENTLY); 1970 } 1971 1972 // Tests that updating an extension does not clobber old state. 1973 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) { 1974 InitializeEmptyExtensionService(); 1975 1976 FilePath path = data_dir_.AppendASCII("good.crx"); 1977 1978 InstallCrx(path, true); 1979 const Extension* good = service_->extensions()->at(0); 1980 ASSERT_EQ("1.0.0.0", good->VersionString()); 1981 ASSERT_EQ(good_crx, good->id()); 1982 1983 // Disable it and allow it to run in incognito. These settings should carry 1984 // over to the updated version. 1985 service_->DisableExtension(good->id()); 1986 service_->SetIsIncognitoEnabled(good->id(), true); 1987 1988 path = data_dir_.AppendASCII("good2.crx"); 1989 UpdateExtension(good_crx, path, INSTALLED); 1990 ASSERT_EQ(1u, service_->disabled_extensions()->size()); 1991 const Extension* good2 = service_->disabled_extensions()->at(0); 1992 ASSERT_EQ("1.0.0.1", good2->version()->GetString()); 1993 EXPECT_TRUE(service_->IsIncognitoEnabled(good2->id())); 1994 } 1995 1996 // Tests that updating preserves extension location. 1997 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) { 1998 InitializeEmptyExtensionService(); 1999 2000 FilePath path = data_dir_.AppendASCII("good.crx"); 2001 2002 InstallCrx(path, true); 2003 const Extension* good = service_->extensions()->at(0); 2004 2005 ASSERT_EQ("1.0.0.0", good->VersionString()); 2006 ASSERT_EQ(good_crx, good->id()); 2007 2008 // Simulate non-internal location. 2009 const_cast<Extension*>(good)->location_ = Extension::EXTERNAL_PREF; 2010 2011 path = data_dir_.AppendASCII("good2.crx"); 2012 UpdateExtension(good_crx, path, ENABLED); 2013 const Extension* good2 = service_->extensions()->at(0); 2014 ASSERT_EQ("1.0.0.1", good2->version()->GetString()); 2015 EXPECT_EQ(good2->location(), Extension::EXTERNAL_PREF); 2016 } 2017 2018 // Makes sure that LOAD extension types can downgrade. 2019 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) { 2020 InitializeEmptyExtensionService(); 2021 2022 ScopedTempDir temp; 2023 ASSERT_TRUE(temp.CreateUniqueTempDir()); 2024 2025 // We'll write the extension manifest dynamically to a temporary path 2026 // to make it easier to change the version number. 2027 FilePath extension_path = temp.path(); 2028 FilePath manifest_path = extension_path.Append(Extension::kManifestFilename); 2029 ASSERT_FALSE(file_util::PathExists(manifest_path)); 2030 2031 // Start with version 2.0. 2032 DictionaryValue manifest; 2033 manifest.SetString("version", "2.0"); 2034 manifest.SetString("name", "LOAD Downgrade Test"); 2035 2036 JSONFileValueSerializer serializer(manifest_path); 2037 ASSERT_TRUE(serializer.Serialize(manifest)); 2038 2039 service_->LoadExtension(extension_path); 2040 loop_.RunAllPending(); 2041 2042 EXPECT_EQ(0u, GetErrors().size()); 2043 ASSERT_EQ(1u, loaded_.size()); 2044 EXPECT_EQ(Extension::LOAD, loaded_[0]->location()); 2045 EXPECT_EQ(1u, service_->extensions()->size()); 2046 EXPECT_EQ("2.0", loaded_[0]->VersionString()); 2047 2048 // Now set the version number to 1.0, reload the extensions and verify that 2049 // the downgrade was accepted. 2050 manifest.SetString("version", "1.0"); 2051 ASSERT_TRUE(serializer.Serialize(manifest)); 2052 2053 service_->LoadExtension(extension_path); 2054 loop_.RunAllPending(); 2055 2056 EXPECT_EQ(0u, GetErrors().size()); 2057 ASSERT_EQ(1u, loaded_.size()); 2058 EXPECT_EQ(Extension::LOAD, loaded_[0]->location()); 2059 EXPECT_EQ(1u, service_->extensions()->size()); 2060 EXPECT_EQ("1.0", loaded_[0]->VersionString()); 2061 } 2062 2063 namespace { 2064 2065 bool IsExtension(const Extension& extension) { 2066 return extension.GetType() == Extension::TYPE_EXTENSION; 2067 } 2068 2069 } // namespace 2070 2071 // Test adding a pending extension. 2072 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) { 2073 InitializeEmptyExtensionService(); 2074 2075 const std::string kFakeId(all_zero); 2076 const GURL kFakeUpdateURL("http:://fake.update/url"); 2077 const bool kFakeInstallSilently(true); 2078 const Extension::State kFakeInitialState(Extension::ENABLED); 2079 const bool kFakeInitialIncognitoEnabled(false); 2080 2081 service_->pending_extension_manager()->AddFromSync( 2082 kFakeId, kFakeUpdateURL, &IsExtension, 2083 kFakeInstallSilently, kFakeInitialState, kFakeInitialIncognitoEnabled); 2084 2085 PendingExtensionInfo pending_extension_info; 2086 ASSERT_TRUE(service_->pending_extension_manager()->GetById( 2087 kFakeId, &pending_extension_info)); 2088 EXPECT_EQ(kFakeUpdateURL, pending_extension_info.update_url()); 2089 EXPECT_EQ(&IsExtension, pending_extension_info.should_allow_install_); 2090 EXPECT_EQ(kFakeInstallSilently, pending_extension_info.install_silently()); 2091 } 2092 2093 namespace { 2094 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf"; 2095 const char kGoodUpdateURL[] = "http://good.update/url"; 2096 const bool kGoodIsFromSync = true; 2097 const bool kGoodInstallSilently = true; 2098 const Extension::State kGoodInitialState = Extension::DISABLED; 2099 const bool kGoodInitialIncognitoEnabled = true; 2100 } // namespace 2101 2102 // Test updating a pending extension. 2103 TEST_F(ExtensionServiceTest, UpdatePendingExtension) { 2104 InitializeEmptyExtensionService(); 2105 service_->pending_extension_manager()->AddFromSync( 2106 kGoodId, GURL(kGoodUpdateURL), &IsExtension, 2107 kGoodInstallSilently, kGoodInitialState, 2108 kGoodInitialIncognitoEnabled); 2109 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId)); 2110 2111 FilePath path = data_dir_.AppendASCII("good.crx"); 2112 UpdateExtension(kGoodId, path, INSTALLED); 2113 2114 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId)); 2115 2116 const Extension* extension = service_->GetExtensionById(kGoodId, true); 2117 ASSERT_TRUE(extension); 2118 2119 bool enabled = service_->GetExtensionById(kGoodId, false); 2120 EXPECT_EQ(enabled, kGoodInitialState == Extension::ENABLED); 2121 EXPECT_EQ(kGoodInitialState, 2122 service_->extension_prefs()->GetExtensionState(extension->id())); 2123 EXPECT_EQ(kGoodInitialIncognitoEnabled, 2124 service_->IsIncognitoEnabled(extension->id())); 2125 } 2126 2127 namespace { 2128 2129 bool IsTheme(const Extension& extension) { 2130 return extension.is_theme(); 2131 } 2132 2133 } // namespace 2134 2135 // Test updating a pending theme. 2136 TEST_F(ExtensionServiceTest, UpdatePendingTheme) { 2137 InitializeEmptyExtensionService(); 2138 service_->pending_extension_manager()->AddFromSync( 2139 theme_crx, GURL(), &IsTheme, 2140 false, Extension::ENABLED, false); 2141 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx)); 2142 2143 FilePath path = data_dir_.AppendASCII("theme.crx"); 2144 UpdateExtension(theme_crx, path, ENABLED); 2145 2146 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx)); 2147 2148 const Extension* extension = service_->GetExtensionById(theme_crx, true); 2149 ASSERT_TRUE(extension); 2150 2151 EXPECT_EQ(Extension::ENABLED, 2152 service_->extension_prefs()->GetExtensionState(extension->id())); 2153 EXPECT_FALSE(service_->IsIncognitoEnabled(extension->id())); 2154 } 2155 2156 #if defined(OS_CHROMEOS) 2157 // Always fails on ChromeOS: http://crbug.com/79737 2158 #define MAYBE_UpdatePendingExternalCrx FAILS_UpdatePendingExternalCrx 2159 #else 2160 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx 2161 #endif 2162 // Test updating a pending CRX as if the source is an external extension 2163 // with an update URL. In this case we don't know if the CRX is a theme 2164 // or not. 2165 TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) { 2166 InitializeEmptyExtensionService(); 2167 service_->pending_extension_manager()->AddFromExternalUpdateUrl( 2168 theme_crx, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD); 2169 2170 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx)); 2171 2172 FilePath path = data_dir_.AppendASCII("theme.crx"); 2173 UpdateExtension(theme_crx, path, ENABLED); 2174 2175 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx)); 2176 2177 const Extension* extension = service_->GetExtensionById(theme_crx, true); 2178 ASSERT_TRUE(extension); 2179 2180 EXPECT_EQ(Extension::ENABLED, 2181 service_->extension_prefs()->GetExtensionState(extension->id())); 2182 EXPECT_FALSE(service_->IsIncognitoEnabled(extension->id())); 2183 } 2184 2185 // Test updating a pending CRX as if the source is an external extension 2186 // with an update URL. The external update should overwrite a sync update, 2187 // but a sync update should not overwrite a non-sync update. 2188 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) { 2189 InitializeEmptyExtensionService(); 2190 2191 // Add a crx to be installed from the update mechanism. 2192 service_->pending_extension_manager()->AddFromSync( 2193 kGoodId, GURL(kGoodUpdateURL), &IsExtension, 2194 kGoodInstallSilently, kGoodInitialState, 2195 kGoodInitialIncognitoEnabled); 2196 2197 // Check that there is a pending crx, with is_from_sync set to true. 2198 PendingExtensionInfo pending_extension_info; 2199 ASSERT_TRUE(service_->pending_extension_manager()->GetById( 2200 kGoodId, &pending_extension_info)); 2201 EXPECT_TRUE(pending_extension_info.is_from_sync()); 2202 2203 // Add a crx to be updated, with the same ID, from a non-sync source. 2204 service_->pending_extension_manager()->AddFromExternalUpdateUrl( 2205 kGoodId, GURL(kGoodUpdateURL), Extension::EXTERNAL_PREF_DOWNLOAD); 2206 2207 // Check that there is a pending crx, with is_from_sync set to false. 2208 ASSERT_TRUE(service_->pending_extension_manager()->GetById( 2209 kGoodId, &pending_extension_info)); 2210 EXPECT_FALSE(pending_extension_info.is_from_sync()); 2211 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, 2212 pending_extension_info.install_source()); 2213 2214 // Add a crx to be installed from the update mechanism. 2215 service_->pending_extension_manager()->AddFromSync( 2216 kGoodId, GURL(kGoodUpdateURL), &IsExtension, 2217 kGoodInstallSilently, kGoodInitialState, 2218 kGoodInitialIncognitoEnabled); 2219 2220 // Check that the external, non-sync update was not overridden. 2221 ASSERT_TRUE(service_->pending_extension_manager()->GetById( 2222 kGoodId, &pending_extension_info)); 2223 EXPECT_FALSE(pending_extension_info.is_from_sync()); 2224 EXPECT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, 2225 pending_extension_info.install_source()); 2226 } 2227 2228 // Updating a theme should fail if the updater is explicitly told that 2229 // the CRX is not a theme. 2230 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) { 2231 InitializeEmptyExtensionService(); 2232 service_->pending_extension_manager()->AddFromSync( 2233 theme_crx, GURL(), &IsExtension, 2234 true, Extension::ENABLED, false); 2235 2236 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx)); 2237 2238 FilePath path = data_dir_.AppendASCII("theme.crx"); 2239 UpdateExtension(theme_crx, path, FAILED_SILENTLY); 2240 2241 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx)); 2242 2243 const Extension* extension = service_->GetExtensionById(theme_crx, true); 2244 ASSERT_FALSE(extension); 2245 } 2246 2247 // TODO(akalin): Test updating a pending extension non-silently once 2248 // we can mock out ExtensionInstallUI and inject our version into 2249 // UpdateExtension(). 2250 2251 // Test updating a pending extension which fails the should-install test. 2252 TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) { 2253 InitializeEmptyExtensionService(); 2254 // Add pending extension with a flipped is_theme. 2255 service_->pending_extension_manager()->AddFromSync( 2256 kGoodId, GURL(kGoodUpdateURL), &IsTheme, 2257 kGoodInstallSilently, kGoodInitialState, 2258 kGoodInitialIncognitoEnabled); 2259 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId)); 2260 2261 FilePath path = data_dir_.AppendASCII("good.crx"); 2262 UpdateExtension(kGoodId, path, UPDATED); 2263 2264 // TODO(akalin): Figure out how to check that the extensions 2265 // directory is cleaned up properly in OnExtensionInstalled(). 2266 2267 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId)); 2268 } 2269 2270 // TODO(akalin): Figure out how to test that installs of pending 2271 // unsyncable extensions are blocked. 2272 2273 // Test updating a pending extension for one that is not pending. 2274 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) { 2275 InitializeEmptyExtensionService(); 2276 2277 FilePath path = data_dir_.AppendASCII("good.crx"); 2278 UpdateExtension(kGoodId, path, UPDATED); 2279 2280 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId)); 2281 } 2282 2283 // Test updating a pending extension for one that is already 2284 // installed. 2285 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) { 2286 InitializeEmptyExtensionService(); 2287 2288 FilePath path = data_dir_.AppendASCII("good.crx"); 2289 InstallCrx(path, true); 2290 ASSERT_EQ(1u, service_->extensions()->size()); 2291 const Extension* good = service_->extensions()->at(0); 2292 2293 EXPECT_FALSE(good->is_theme()); 2294 2295 // Use AddExtensionImpl() as AddFrom*() would balk. 2296 service_->pending_extension_manager()->AddExtensionImpl( 2297 good->id(), good->update_url(), &IsExtension, 2298 kGoodIsFromSync, kGoodInstallSilently, kGoodInitialState, 2299 kGoodInitialIncognitoEnabled, Extension::INTERNAL); 2300 UpdateExtension(good->id(), path, INSTALLED); 2301 2302 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId)); 2303 } 2304 2305 // Test pref settings for blacklist and unblacklist extensions. 2306 TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) { 2307 InitializeEmptyExtensionService(); 2308 std::vector<std::string> blacklist; 2309 blacklist.push_back(good0); 2310 blacklist.push_back("invalid_id"); // an invalid id 2311 blacklist.push_back(good1); 2312 service_->UpdateExtensionBlacklist(blacklist); 2313 // Make sure pref is updated 2314 loop_.RunAllPending(); 2315 2316 // blacklist is set for good0,1,2 2317 ValidateBooleanPref(good0, "blacklist", true); 2318 ValidateBooleanPref(good1, "blacklist", true); 2319 // invalid_id should not be inserted to pref. 2320 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist")); 2321 2322 // remove good1, add good2 2323 blacklist.pop_back(); 2324 blacklist.push_back(good2); 2325 2326 service_->UpdateExtensionBlacklist(blacklist); 2327 // only good0 and good1 should be set 2328 ValidateBooleanPref(good0, "blacklist", true); 2329 EXPECT_FALSE(IsPrefExist(good1, "blacklist")); 2330 ValidateBooleanPref(good2, "blacklist", true); 2331 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist")); 2332 } 2333 2334 // Unload installed extension from blacklist. 2335 TEST_F(ExtensionServiceTest, UnloadBlacklistedExtension) { 2336 InitializeEmptyExtensionService(); 2337 2338 FilePath path = data_dir_.AppendASCII("good.crx"); 2339 2340 InstallCrx(path, true); 2341 const Extension* good = service_->extensions()->at(0); 2342 EXPECT_EQ(good_crx, good->id()); 2343 UpdateExtension(good_crx, path, FAILED_SILENTLY); 2344 2345 std::vector<std::string> blacklist; 2346 blacklist.push_back(good_crx); 2347 service_->UpdateExtensionBlacklist(blacklist); 2348 // Make sure pref is updated 2349 loop_.RunAllPending(); 2350 2351 // Now, the good_crx is blacklisted. 2352 ValidateBooleanPref(good_crx, "blacklist", true); 2353 EXPECT_EQ(0u, service_->extensions()->size()); 2354 2355 // Remove good_crx from blacklist 2356 blacklist.pop_back(); 2357 service_->UpdateExtensionBlacklist(blacklist); 2358 // Make sure pref is updated 2359 loop_.RunAllPending(); 2360 // blacklist value should not be set for good_crx 2361 EXPECT_FALSE(IsPrefExist(good_crx, "blacklist")); 2362 } 2363 2364 // Unload installed extension from blacklist. 2365 TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) { 2366 InitializeEmptyExtensionService(); 2367 std::vector<std::string> blacklist; 2368 blacklist.push_back(good_crx); 2369 service_->UpdateExtensionBlacklist(blacklist); 2370 // Make sure pref is updated 2371 loop_.RunAllPending(); 2372 2373 // Now, the good_crx is blacklisted. 2374 ValidateBooleanPref(good_crx, "blacklist", true); 2375 2376 // We can not install good_crx. 2377 FilePath path = data_dir_.AppendASCII("good.crx"); 2378 StartCrxInstall(path); 2379 loop_.RunAllPending(); 2380 EXPECT_EQ(0u, service_->extensions()->size()); 2381 ValidateBooleanPref(good_crx, "blacklist", true); 2382 } 2383 2384 // Test loading extensions from the profile directory, except 2385 // blacklisted ones. 2386 TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) { 2387 // Initialize the test dir with a good Preferences/extensions. 2388 FilePath source_install_dir = data_dir_ 2389 .AppendASCII("good") 2390 .AppendASCII("Extensions"); 2391 FilePath pref_path = source_install_dir 2392 .DirName() 2393 .AppendASCII("Preferences"); 2394 InitializeInstalledExtensionService(pref_path, source_install_dir); 2395 2396 // Blacklist good1. 2397 std::vector<std::string> blacklist; 2398 blacklist.push_back(good1); 2399 service_->UpdateExtensionBlacklist(blacklist); 2400 // Make sure pref is updated 2401 loop_.RunAllPending(); 2402 2403 ValidateBooleanPref(good1, "blacklist", true); 2404 2405 // Load extensions. 2406 service_->Init(); 2407 loop_.RunAllPending(); 2408 2409 std::vector<std::string> errors = GetErrors(); 2410 for (std::vector<std::string>::iterator err = errors.begin(); 2411 err != errors.end(); ++err) { 2412 LOG(ERROR) << *err; 2413 } 2414 ASSERT_EQ(2u, loaded_.size()); 2415 2416 EXPECT_NE(std::string(good1), loaded_[0]->id()); 2417 EXPECT_NE(std::string(good1), loaded_[1]->id()); 2418 } 2419 2420 // Will not install extension blacklisted by policy. 2421 TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) { 2422 InitializeEmptyExtensionService(); 2423 2424 // Blacklist everything. 2425 { 2426 ListPrefUpdate update(profile_->GetPrefs(), 2427 prefs::kExtensionInstallDenyList); 2428 ListValue* blacklist = update.Get(); 2429 blacklist->Append(Value::CreateStringValue("*")); 2430 } 2431 2432 // Blacklist prevents us from installing good_crx. 2433 FilePath path = data_dir_.AppendASCII("good.crx"); 2434 StartCrxInstall(path); 2435 loop_.RunAllPending(); 2436 EXPECT_EQ(0u, service_->extensions()->size()); 2437 2438 // Now whitelist this particular extension. 2439 { 2440 ListPrefUpdate update(profile_->GetPrefs(), 2441 prefs::kExtensionInstallAllowList); 2442 ListValue* whitelist = update.Get(); 2443 whitelist->Append(Value::CreateStringValue(good_crx)); 2444 } 2445 2446 2447 // Ensure we can now install good_crx. 2448 StartCrxInstall(path); 2449 loop_.RunAllPending(); 2450 EXPECT_EQ(1u, service_->extensions()->size()); 2451 } 2452 2453 // Extension blacklisted by policy get unloaded after installing. 2454 TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) { 2455 InitializeEmptyExtensionService(); 2456 2457 // Install good_crx. 2458 FilePath path = data_dir_.AppendASCII("good.crx"); 2459 StartCrxInstall(path); 2460 loop_.RunAllPending(); 2461 EXPECT_EQ(1u, service_->extensions()->size()); 2462 2463 { // Scope for pref update notification. 2464 PrefService* prefs = profile_->GetPrefs(); 2465 ListPrefUpdate update(prefs, prefs::kExtensionInstallDenyList); 2466 ListValue* blacklist = update.Get(); 2467 ASSERT_TRUE(blacklist != NULL); 2468 2469 // Blacklist this extension. 2470 blacklist->Append(Value::CreateStringValue(good_crx)); 2471 prefs->ScheduleSavePersistentPrefs(); 2472 } 2473 2474 // Extension should not be running now. 2475 loop_.RunAllPending(); 2476 EXPECT_EQ(0u, service_->extensions()->size()); 2477 } 2478 2479 // Tests disabling extensions 2480 TEST_F(ExtensionServiceTest, DisableExtension) { 2481 InitializeEmptyExtensionService(); 2482 2483 // A simple extension that should install without error. 2484 FilePath path = data_dir_.AppendASCII("good.crx"); 2485 InstallCrx(path, true); 2486 2487 const char* extension_id = good_crx; 2488 EXPECT_FALSE(service_->extensions()->empty()); 2489 EXPECT_TRUE(service_->GetExtensionById(extension_id, true) != NULL); 2490 EXPECT_TRUE(service_->GetExtensionById(extension_id, false) != NULL); 2491 EXPECT_TRUE(service_->disabled_extensions()->empty()); 2492 2493 // Disable it. 2494 service_->DisableExtension(extension_id); 2495 2496 EXPECT_TRUE(service_->extensions()->empty()); 2497 EXPECT_TRUE(service_->GetExtensionById(extension_id, true) != NULL); 2498 EXPECT_FALSE(service_->GetExtensionById(extension_id, false) != NULL); 2499 EXPECT_FALSE(service_->disabled_extensions()->empty()); 2500 } 2501 2502 // Tests disabling all extensions (simulating --disable-extensions flag). 2503 TEST_F(ExtensionServiceTest, DisableAllExtensions) { 2504 InitializeEmptyExtensionService(); 2505 2506 2507 FilePath path = data_dir_.AppendASCII("good.crx"); 2508 InstallCrx(path, true); 2509 2510 EXPECT_EQ(1u, service_->extensions()->size()); 2511 EXPECT_EQ(0u, service_->disabled_extensions()->size()); 2512 2513 // Disable extensions. 2514 service_->set_extensions_enabled(false); 2515 service_->ReloadExtensions(); 2516 2517 // There shouldn't be extensions in either list. 2518 EXPECT_EQ(0u, service_->extensions()->size()); 2519 EXPECT_EQ(0u, service_->disabled_extensions()->size()); 2520 2521 // This shouldn't do anything when all extensions are disabled. 2522 service_->EnableExtension(good_crx); 2523 service_->ReloadExtensions(); 2524 2525 // There still shouldn't be extensions in either list. 2526 EXPECT_EQ(0u, service_->extensions()->size()); 2527 EXPECT_EQ(0u, service_->disabled_extensions()->size()); 2528 2529 // And then re-enable the extensions. 2530 service_->set_extensions_enabled(true); 2531 service_->ReloadExtensions(); 2532 2533 EXPECT_EQ(1u, service_->extensions()->size()); 2534 EXPECT_EQ(0u, service_->disabled_extensions()->size()); 2535 } 2536 2537 // Tests reloading extensions 2538 TEST_F(ExtensionServiceTest, ReloadExtensions) { 2539 InitializeEmptyExtensionService(); 2540 2541 // Simple extension that should install without error. 2542 FilePath path = data_dir_.AppendASCII("good.crx"); 2543 InstallCrx(path, true); 2544 const char* extension_id = good_crx; 2545 service_->DisableExtension(extension_id); 2546 2547 EXPECT_EQ(0u, service_->extensions()->size()); 2548 EXPECT_EQ(1u, service_->disabled_extensions()->size()); 2549 2550 service_->ReloadExtensions(); 2551 2552 // Extension counts shouldn't change. 2553 EXPECT_EQ(0u, service_->extensions()->size()); 2554 EXPECT_EQ(1u, service_->disabled_extensions()->size()); 2555 2556 service_->EnableExtension(extension_id); 2557 2558 EXPECT_EQ(1u, service_->extensions()->size()); 2559 EXPECT_EQ(0u, service_->disabled_extensions()->size()); 2560 2561 // Need to clear |loaded_| manually before reloading as the 2562 // EnableExtension() call above inserted into it and 2563 // UnloadAllExtensions() doesn't send out notifications. 2564 loaded_.clear(); 2565 service_->ReloadExtensions(); 2566 2567 // Extension counts shouldn't change. 2568 EXPECT_EQ(1u, service_->extensions()->size()); 2569 EXPECT_EQ(0u, service_->disabled_extensions()->size()); 2570 } 2571 2572 // Tests uninstalling normal extensions 2573 TEST_F(ExtensionServiceTest, UninstallExtension) { 2574 InitializeEmptyExtensionService(); 2575 2576 // A simple extension that should install without error. 2577 FilePath path = data_dir_.AppendASCII("good.crx"); 2578 InstallCrx(path, true); 2579 2580 // The directory should be there now. 2581 const char* extension_id = good_crx; 2582 FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id); 2583 EXPECT_TRUE(file_util::PathExists(extension_path)); 2584 2585 ValidatePrefKeyCount(1); 2586 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 2587 ValidateIntegerPref(good_crx, "location", Extension::INTERNAL); 2588 2589 // Uninstall it. 2590 service_->UninstallExtension(extension_id, false, NULL); 2591 total_successes_ = 0; 2592 2593 // We should get an unload notification. 2594 ASSERT_TRUE(unloaded_id_.length()); 2595 EXPECT_EQ(extension_id, unloaded_id_); 2596 2597 ValidatePrefKeyCount(0); 2598 2599 // The extension should not be in the service anymore. 2600 ASSERT_FALSE(service_->GetExtensionById(extension_id, false)); 2601 loop_.RunAllPending(); 2602 2603 // The directory should be gone. 2604 EXPECT_FALSE(file_util::PathExists(extension_path)); 2605 } 2606 2607 // Tests the uninstaller helper. 2608 TEST_F(ExtensionServiceTest, UninstallExtensionHelper) { 2609 InitializeEmptyExtensionService(); 2610 2611 // A simple extension that should install without error. 2612 FilePath path = data_dir_.AppendASCII("good.crx"); 2613 InstallCrx(path, true); 2614 2615 // The directory should be there now. 2616 const char* extension_id = good_crx; 2617 FilePath extension_path = extensions_install_dir_.AppendASCII(extension_id); 2618 EXPECT_TRUE(file_util::PathExists(extension_path)); 2619 2620 bool result = ExtensionService::UninstallExtensionHelper(service_, 2621 extension_id); 2622 total_successes_ = 0; 2623 2624 EXPECT_TRUE(result); 2625 2626 // We should get an unload notification. 2627 ASSERT_TRUE(unloaded_id_.length()); 2628 EXPECT_EQ(extension_id, unloaded_id_); 2629 2630 ValidatePrefKeyCount(0); 2631 2632 // The extension should not be in the service anymore. 2633 ASSERT_FALSE(service_->GetExtensionById(extension_id, false)); 2634 loop_.RunAllPending(); 2635 2636 // The directory should be gone. 2637 EXPECT_FALSE(file_util::PathExists(extension_path)); 2638 2639 // Attempt to uninstall again. This should fail as we just removed the 2640 // extension. 2641 result = ExtensionService::UninstallExtensionHelper(service_, extension_id); 2642 EXPECT_FALSE(result); 2643 } 2644 2645 // Verifies extension state is removed upon uninstall 2646 TEST_F(ExtensionServiceTest, ClearExtensionData) { 2647 InitializeEmptyExtensionService(); 2648 2649 // Load a test extension. 2650 FilePath path = data_dir_; 2651 path = path.AppendASCII("good.crx"); 2652 InstallCrx(path, true); 2653 const Extension* extension = service_->GetExtensionById(good_crx, false); 2654 ASSERT_TRUE(extension); 2655 GURL ext_url(extension->url()); 2656 string16 origin_id = 2657 webkit_database::DatabaseUtil::GetOriginIdentifier(ext_url); 2658 2659 // Set a cookie for the extension. 2660 net::CookieMonster* cookie_monster = 2661 profile_->GetRequestContextForExtensions()->GetURLRequestContext()-> 2662 cookie_store()->GetCookieMonster(); 2663 ASSERT_TRUE(cookie_monster); 2664 net::CookieOptions options; 2665 cookie_monster->SetCookieWithOptions(ext_url, "dummy=value", options); 2666 net::CookieList list = cookie_monster->GetAllCookiesForURL(ext_url); 2667 EXPECT_EQ(1U, list.size()); 2668 2669 // Open a database. 2670 webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker(); 2671 string16 db_name = UTF8ToUTF16("db"); 2672 string16 description = UTF8ToUTF16("db_description"); 2673 int64 size; 2674 int64 available; 2675 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size, 2676 &available); 2677 db_tracker->DatabaseClosed(origin_id, db_name); 2678 std::vector<webkit_database::OriginInfo> origins; 2679 db_tracker->GetAllOriginsInfo(&origins); 2680 EXPECT_EQ(1U, origins.size()); 2681 EXPECT_EQ(origin_id, origins[0].GetOrigin()); 2682 2683 // Create local storage. We only simulate this by creating the backing file 2684 // since webkit is not initialized. 2685 DOMStorageContext* context = 2686 profile_->GetWebKitContext()->dom_storage_context(); 2687 FilePath lso_path = context->GetLocalStorageFilePath(origin_id); 2688 EXPECT_TRUE(file_util::CreateDirectory(lso_path.DirName())); 2689 EXPECT_EQ(0, file_util::WriteFile(lso_path, NULL, 0)); 2690 EXPECT_TRUE(file_util::PathExists(lso_path)); 2691 2692 // Create indexed db. Again, it is enough to only simulate this by creating 2693 // the file on the disk. 2694 IndexedDBContext* idb_context = 2695 profile_->GetWebKitContext()->indexed_db_context(); 2696 FilePath idb_path = idb_context->GetIndexedDBFilePath(origin_id); 2697 EXPECT_TRUE(file_util::CreateDirectory(idb_path.DirName())); 2698 EXPECT_EQ(0, file_util::WriteFile(idb_path, NULL, 0)); 2699 EXPECT_TRUE(file_util::PathExists(idb_path)); 2700 2701 // Uninstall the extension. 2702 service_->UninstallExtension(good_crx, false, NULL); 2703 loop_.RunAllPending(); 2704 2705 // Check that the cookie is gone. 2706 list = cookie_monster->GetAllCookiesForURL(ext_url); 2707 EXPECT_EQ(0U, list.size()); 2708 2709 // The database should have vanished as well. 2710 origins.clear(); 2711 db_tracker->GetAllOriginsInfo(&origins); 2712 EXPECT_EQ(0U, origins.size()); 2713 2714 // Check that the LSO file has been removed. 2715 EXPECT_FALSE(file_util::PathExists(lso_path)); 2716 2717 // Check if the indexed db has disappeared too. 2718 EXPECT_FALSE(file_util::PathExists(idb_path)); 2719 } 2720 2721 // Tests loading single extensions (like --load-extension) 2722 TEST_F(ExtensionServiceTest, LoadExtension) { 2723 InitializeEmptyExtensionService(); 2724 2725 FilePath ext1 = data_dir_ 2726 .AppendASCII("good") 2727 .AppendASCII("Extensions") 2728 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 2729 .AppendASCII("1.0.0.0"); 2730 service_->LoadExtension(ext1); 2731 loop_.RunAllPending(); 2732 EXPECT_EQ(0u, GetErrors().size()); 2733 ASSERT_EQ(1u, loaded_.size()); 2734 EXPECT_EQ(Extension::LOAD, loaded_[0]->location()); 2735 EXPECT_EQ(1u, service_->extensions()->size()); 2736 2737 ValidatePrefKeyCount(1); 2738 2739 FilePath no_manifest = data_dir_ 2740 .AppendASCII("bad") 2741 // .AppendASCII("Extensions") 2742 .AppendASCII("cccccccccccccccccccccccccccccccc") 2743 .AppendASCII("1"); 2744 service_->LoadExtension(no_manifest); 2745 loop_.RunAllPending(); 2746 EXPECT_EQ(1u, GetErrors().size()); 2747 ASSERT_EQ(1u, loaded_.size()); 2748 EXPECT_EQ(1u, service_->extensions()->size()); 2749 2750 // Test uninstall. 2751 std::string id = loaded_[0]->id(); 2752 EXPECT_FALSE(unloaded_id_.length()); 2753 service_->UninstallExtension(id, false, NULL); 2754 loop_.RunAllPending(); 2755 EXPECT_EQ(id, unloaded_id_); 2756 ASSERT_EQ(0u, loaded_.size()); 2757 EXPECT_EQ(0u, service_->extensions()->size()); 2758 } 2759 2760 // Tests that we generate IDs when they are not specified in the manifest for 2761 // --load-extension. 2762 TEST_F(ExtensionServiceTest, GenerateID) { 2763 InitializeEmptyExtensionService(); 2764 2765 2766 FilePath no_id_ext = data_dir_.AppendASCII("no_id"); 2767 service_->LoadExtension(no_id_ext); 2768 loop_.RunAllPending(); 2769 EXPECT_EQ(0u, GetErrors().size()); 2770 ASSERT_EQ(1u, loaded_.size()); 2771 ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id())); 2772 EXPECT_EQ(loaded_[0]->location(), Extension::LOAD); 2773 2774 ValidatePrefKeyCount(1); 2775 2776 std::string previous_id = loaded_[0]->id(); 2777 2778 // If we reload the same path, we should get the same extension ID. 2779 service_->LoadExtension(no_id_ext); 2780 loop_.RunAllPending(); 2781 ASSERT_EQ(1u, loaded_.size()); 2782 ASSERT_EQ(previous_id, loaded_[0]->id()); 2783 } 2784 2785 void ExtensionServiceTest::TestExternalProvider( 2786 MockExtensionProvider* provider, Extension::Location location) { 2787 // Verify that starting with no providers loads no extensions. 2788 service_->Init(); 2789 loop_.RunAllPending(); 2790 ASSERT_EQ(0u, loaded_.size()); 2791 2792 provider->set_visit_count(0); 2793 2794 // Register a test extension externally using the mock registry provider. 2795 FilePath source_path = data_dir_.AppendASCII("good.crx"); 2796 2797 // Add the extension. 2798 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path); 2799 2800 // Reloading extensions should find our externally registered extension 2801 // and install it. 2802 service_->CheckForExternalUpdates(); 2803 loop_.RunAllPending(); 2804 2805 ASSERT_EQ(0u, GetErrors().size()); 2806 ASSERT_EQ(1u, loaded_.size()); 2807 ASSERT_EQ(location, loaded_[0]->location()); 2808 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString()); 2809 ValidatePrefKeyCount(1); 2810 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 2811 ValidateIntegerPref(good_crx, "location", location); 2812 2813 // Reload extensions without changing anything. The extension should be 2814 // loaded again. 2815 loaded_.clear(); 2816 service_->ReloadExtensions(); 2817 loop_.RunAllPending(); 2818 ASSERT_EQ(0u, GetErrors().size()); 2819 ASSERT_EQ(1u, loaded_.size()); 2820 ValidatePrefKeyCount(1); 2821 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 2822 ValidateIntegerPref(good_crx, "location", location); 2823 2824 // Now update the extension with a new version. We should get upgraded. 2825 source_path = source_path.DirName().AppendASCII("good2.crx"); 2826 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path); 2827 2828 loaded_.clear(); 2829 service_->CheckForExternalUpdates(); 2830 loop_.RunAllPending(); 2831 ASSERT_EQ(0u, GetErrors().size()); 2832 ASSERT_EQ(1u, loaded_.size()); 2833 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString()); 2834 ValidatePrefKeyCount(1); 2835 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 2836 ValidateIntegerPref(good_crx, "location", location); 2837 2838 // Uninstall the extension and reload. Nothing should happen because the 2839 // preference should prevent us from reinstalling. 2840 std::string id = loaded_[0]->id(); 2841 service_->UninstallExtension(id, false, NULL); 2842 loop_.RunAllPending(); 2843 2844 FilePath install_path = extensions_install_dir_.AppendASCII(id); 2845 // It should not be possible to uninstall a policy controlled extension. 2846 if (Extension::UserMayDisable(location)) { 2847 // The extension should also be gone from the install directory. 2848 ASSERT_FALSE(file_util::PathExists(install_path)); 2849 loaded_.clear(); 2850 service_->CheckForExternalUpdates(); 2851 loop_.RunAllPending(); 2852 ASSERT_EQ(0u, loaded_.size()); 2853 ValidatePrefKeyCount(1); 2854 ValidateIntegerPref(good_crx, "state", 2855 Extension::EXTERNAL_EXTENSION_UNINSTALLED); 2856 ValidateIntegerPref(good_crx, "location", location); 2857 2858 // Now clear the preference and reinstall. 2859 SetPrefInteg(good_crx, "state", Extension::ENABLED); 2860 profile_->GetPrefs()->ScheduleSavePersistentPrefs(); 2861 2862 loaded_.clear(); 2863 service_->CheckForExternalUpdates(); 2864 loop_.RunAllPending(); 2865 ASSERT_EQ(1u, loaded_.size()); 2866 } else { 2867 // Policy controlled extesions should not have been touched by uninstall. 2868 ASSERT_TRUE(file_util::PathExists(install_path)); 2869 } 2870 ValidatePrefKeyCount(1); 2871 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 2872 ValidateIntegerPref(good_crx, "location", location); 2873 2874 if (Extension::UserMayDisable(location)) { 2875 // Now test an externally triggered uninstall (deleting the registry key or 2876 // the pref entry). 2877 provider->RemoveExtension(good_crx); 2878 2879 loaded_.clear(); 2880 service_->OnExternalProviderReady(); 2881 loop_.RunAllPending(); 2882 ASSERT_EQ(0u, loaded_.size()); 2883 ValidatePrefKeyCount(0); 2884 2885 // The extension should also be gone from the install directory. 2886 ASSERT_FALSE(file_util::PathExists(install_path)); 2887 2888 // Now test the case where user uninstalls and then the extension is removed 2889 // from the external provider. 2890 2891 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path); 2892 service_->CheckForExternalUpdates(); 2893 loop_.RunAllPending(); 2894 2895 ASSERT_EQ(1u, loaded_.size()); 2896 ASSERT_EQ(0u, GetErrors().size()); 2897 2898 // User uninstalls. 2899 loaded_.clear(); 2900 service_->UninstallExtension(id, false, NULL); 2901 loop_.RunAllPending(); 2902 ASSERT_EQ(0u, loaded_.size()); 2903 2904 // Then remove the extension from the extension provider. 2905 provider->RemoveExtension(good_crx); 2906 2907 // Should still be at 0. 2908 loaded_.clear(); 2909 service_->LoadAllExtensions(); 2910 loop_.RunAllPending(); 2911 ASSERT_EQ(0u, loaded_.size()); 2912 ValidatePrefKeyCount(1); 2913 2914 EXPECT_EQ(5, provider->visit_count()); 2915 } else { 2916 EXPECT_EQ(2, provider->visit_count()); 2917 } 2918 } 2919 2920 // Tests the external installation feature 2921 #if defined(OS_WIN) 2922 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) { 2923 // This should all work, even when normal extension installation is disabled. 2924 InitializeEmptyExtensionService(); 2925 set_extensions_enabled(false); 2926 2927 // Now add providers. Extension system takes ownership of the objects. 2928 MockExtensionProvider* reg_provider = 2929 new MockExtensionProvider(service_.get(), Extension::EXTERNAL_REGISTRY); 2930 AddMockExternalProvider(reg_provider); 2931 TestExternalProvider(reg_provider, Extension::EXTERNAL_REGISTRY); 2932 } 2933 #endif 2934 2935 TEST_F(ExtensionServiceTest, ExternalInstallPref) { 2936 InitializeEmptyExtensionService(); 2937 2938 // Now add providers. Extension system takes ownership of the objects. 2939 MockExtensionProvider* pref_provider = 2940 new MockExtensionProvider(service_.get(), Extension::EXTERNAL_PREF); 2941 2942 AddMockExternalProvider(pref_provider); 2943 TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF); 2944 } 2945 2946 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) { 2947 // This should all work, even when normal extension installation is disabled. 2948 InitializeEmptyExtensionService(); 2949 set_extensions_enabled(false); 2950 2951 // TODO(skerner): The mock provider is not a good model of a provider 2952 // that works with update URLs, because it adds file and version info. 2953 // Extend the mock to work with update URLs. This test checks the 2954 // behavior that is common to all external extension visitors. The 2955 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that 2956 // what the visitor does results in an extension being downloaded and 2957 // installed. 2958 MockExtensionProvider* pref_provider = 2959 new MockExtensionProvider(service_.get(), 2960 Extension::EXTERNAL_PREF_DOWNLOAD); 2961 AddMockExternalProvider(pref_provider); 2962 TestExternalProvider(pref_provider, Extension::EXTERNAL_PREF_DOWNLOAD); 2963 } 2964 2965 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) { 2966 // This should all work, even when normal extension installation is disabled. 2967 InitializeEmptyExtensionService(); 2968 set_extensions_enabled(false); 2969 2970 // TODO(skerner): The mock provider is not a good model of a provider 2971 // that works with update URLs, because it adds file and version info. 2972 // Extend the mock to work with update URLs. This test checks the 2973 // behavior that is common to all external extension visitors. The 2974 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that 2975 // what the visitor does results in an extension being downloaded and 2976 // installed. 2977 MockExtensionProvider* pref_provider = 2978 new MockExtensionProvider(service_.get(), 2979 Extension::EXTERNAL_POLICY_DOWNLOAD); 2980 AddMockExternalProvider(pref_provider); 2981 TestExternalProvider(pref_provider, Extension::EXTERNAL_POLICY_DOWNLOAD); 2982 } 2983 2984 // Tests that external extensions get uninstalled when the external extension 2985 // providers can't account for them. 2986 TEST_F(ExtensionServiceTest, ExternalUninstall) { 2987 // Start the extensions service with one external extension already installed. 2988 FilePath source_install_dir = data_dir_ 2989 .AppendASCII("good") 2990 .AppendASCII("Extensions"); 2991 FilePath pref_path = source_install_dir 2992 .DirName() 2993 .AppendASCII("PreferencesExternal"); 2994 2995 // This initializes the extensions service with no ExternalExtensionProviders. 2996 InitializeInstalledExtensionService(pref_path, source_install_dir); 2997 set_extensions_enabled(false); 2998 2999 service_->Init(); 3000 loop_.RunAllPending(); 3001 3002 ASSERT_EQ(0u, GetErrors().size()); 3003 ASSERT_EQ(0u, loaded_.size()); 3004 3005 // Verify that it's not the disabled extensions flag causing it not to load. 3006 set_extensions_enabled(true); 3007 service_->ReloadExtensions(); 3008 loop_.RunAllPending(); 3009 3010 ASSERT_EQ(0u, GetErrors().size()); 3011 ASSERT_EQ(0u, loaded_.size()); 3012 } 3013 3014 // Test that running multiple update checks simultaneously does not 3015 // keep the update from succeeding. 3016 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) { 3017 InitializeEmptyExtensionService(); 3018 3019 MockExtensionProvider* provider = 3020 new MockExtensionProvider(service_.get(), Extension::EXTERNAL_PREF); 3021 AddMockExternalProvider(provider); 3022 3023 // Verify that starting with no providers loads no extensions. 3024 service_->Init(); 3025 loop_.RunAllPending(); 3026 ASSERT_EQ(0u, loaded_.size()); 3027 3028 // Start two checks for updates. 3029 provider->set_visit_count(0); 3030 service_->CheckForExternalUpdates(); 3031 service_->CheckForExternalUpdates(); 3032 loop_.RunAllPending(); 3033 3034 // Two calls should cause two checks for external extensions. 3035 EXPECT_EQ(2, provider->visit_count()); 3036 EXPECT_EQ(0u, GetErrors().size()); 3037 EXPECT_EQ(0u, loaded_.size()); 3038 3039 // Register a test extension externally using the mock registry provider. 3040 FilePath source_path = data_dir_.AppendASCII("good.crx"); 3041 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path); 3042 3043 // Two checks for external updates should find the extension, and install it 3044 // once. 3045 provider->set_visit_count(0); 3046 service_->CheckForExternalUpdates(); 3047 service_->CheckForExternalUpdates(); 3048 loop_.RunAllPending(); 3049 EXPECT_EQ(2, provider->visit_count()); 3050 ASSERT_EQ(0u, GetErrors().size()); 3051 ASSERT_EQ(1u, loaded_.size()); 3052 ASSERT_EQ(Extension::EXTERNAL_PREF, loaded_[0]->location()); 3053 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString()); 3054 ValidatePrefKeyCount(1); 3055 ValidateIntegerPref(good_crx, "state", Extension::ENABLED); 3056 ValidateIntegerPref(good_crx, "location", Extension::EXTERNAL_PREF); 3057 3058 provider->RemoveExtension(good_crx); 3059 provider->set_visit_count(0); 3060 service_->CheckForExternalUpdates(); 3061 service_->CheckForExternalUpdates(); 3062 loop_.RunAllPending(); 3063 3064 // Two calls should cause two checks for external extensions. 3065 // Because the external source no longer includes good_crx, 3066 // good_crx will be uninstalled. So, expect that no extensions 3067 // are loaded. 3068 EXPECT_EQ(2, provider->visit_count()); 3069 EXPECT_EQ(0u, GetErrors().size()); 3070 EXPECT_EQ(0u, loaded_.size()); 3071 } 3072 3073 TEST_F(ExtensionServiceTest, ExternalPrefProvider) { 3074 InitializeEmptyExtensionService(); 3075 3076 // Test some valid extension records. 3077 // Set a base path to avoid erroring out on relative paths. 3078 // Paths starting with // are absolute on every platform we support. 3079 FilePath base_path(FILE_PATH_LITERAL("//base/path")); 3080 ASSERT_TRUE(base_path.IsAbsolute()); 3081 MockProviderVisitor visitor(base_path); 3082 std::string json_data = 3083 "{" 3084 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 3085 " \"external_crx\": \"RandomExtension.crx\"," 3086 " \"external_version\": \"1.0\"" 3087 " }," 3088 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" 3089 " \"external_crx\": \"RandomExtension2.crx\"," 3090 " \"external_version\": \"2.0\"" 3091 " }," 3092 " \"cccccccccccccccccccccccccccccccc\": {" 3093 " \"external_update_url\": \"http:\\\\foo.com/update\"" 3094 " }" 3095 "}"; 3096 EXPECT_EQ(3, visitor.Visit(json_data)); 3097 3098 // Simulate an external_extensions.json file that contains seven invalid 3099 // records: 3100 // - One that is missing the 'external_crx' key. 3101 // - One that is missing the 'external_version' key. 3102 // - One that is specifying .. in the path. 3103 // - One that specifies both a file and update URL. 3104 // - One that specifies no file or update URL. 3105 // - One that has an update URL that is not well formed. 3106 // - One that contains a malformed version. 3107 // - One that has an invalid id. 3108 // - One that has a non-dictionary value. 3109 // The final extension is valid, and we check that it is read to make sure 3110 // failures don't stop valid records from being read. 3111 json_data = 3112 "{" 3113 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 3114 " \"external_version\": \"1.0\"" 3115 " }," 3116 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" 3117 " \"external_crx\": \"RandomExtension.crx\"" 3118 " }," 3119 " \"cccccccccccccccccccccccccccccccc\": {" 3120 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\"," 3121 " \"external_version\": \"2.0\"" 3122 " }," 3123 " \"dddddddddddddddddddddddddddddddd\": {" 3124 " \"external_crx\": \"RandomExtension2.crx\"," 3125 " \"external_version\": \"2.0\"," 3126 " \"external_update_url\": \"http:\\\\foo.com/update\"" 3127 " }," 3128 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {" 3129 " }," 3130 " \"ffffffffffffffffffffffffffffffff\": {" 3131 " \"external_update_url\": \"This string is not a valid URL\"" 3132 " }," 3133 " \"gggggggggggggggggggggggggggggggg\": {" 3134 " \"external_crx\": \"RandomExtension3.crx\"," 3135 " \"external_version\": \"This is not a valid version!\"" 3136 " }," 3137 " \"This is not a valid id!\": {}," 3138 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true," 3139 " \"pppppppppppppppppppppppppppppppp\": {" 3140 " \"external_crx\": \"RandomValidExtension.crx\"," 3141 " \"external_version\": \"1.0\"" 3142 " }" 3143 "}"; 3144 EXPECT_EQ(1, visitor.Visit(json_data)); 3145 3146 // Check that if a base path is not provided, use of a relative 3147 // path fails. 3148 FilePath empty; 3149 MockProviderVisitor visitor_no_relative_paths(empty); 3150 3151 // Use absolute paths. Expect success. 3152 json_data = 3153 "{" 3154 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {" 3155 " \"external_crx\": \"//RandomExtension1.crx\"," 3156 " \"external_version\": \"3.0\"" 3157 " }," 3158 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {" 3159 " \"external_crx\": \"//path/to/RandomExtension2.crx\"," 3160 " \"external_version\": \"3.0\"" 3161 " }" 3162 "}"; 3163 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data)); 3164 3165 // Use a relative path. Expect that it will error out. 3166 json_data = 3167 "{" 3168 " \"cccccccccccccccccccccccccccccccc\": {" 3169 " \"external_crx\": \"RandomExtension2.crx\"," 3170 " \"external_version\": \"3.0\"" 3171 " }" 3172 "}"; 3173 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data)); 3174 } 3175 3176 // Test loading good extensions from the profile directory. 3177 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) { 3178 // Initialize the test dir with a good Preferences/extensions. 3179 FilePath source_install_dir = data_dir_ 3180 .AppendASCII("l10n"); 3181 FilePath pref_path = source_install_dir.AppendASCII("Preferences"); 3182 InitializeInstalledExtensionService(pref_path, source_install_dir); 3183 3184 service_->Init(); 3185 loop_.RunAllPending(); 3186 3187 ASSERT_EQ(3u, loaded_.size()); 3188 3189 // This was equal to "sr" on load. 3190 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en"); 3191 3192 // These are untouched by re-localization. 3193 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en"); 3194 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale)); 3195 3196 // This one starts with Serbian name, and gets re-localized into English. 3197 EXPECT_EQ("My name is simple.", loaded_[0]->name()); 3198 3199 // These are untouched by re-localization. 3200 EXPECT_EQ("My name is simple.", loaded_[1]->name()); 3201 EXPECT_EQ("no l10n", loaded_[2]->name()); 3202 } 3203 3204 class ExtensionsReadyRecorder : public NotificationObserver { 3205 public: 3206 ExtensionsReadyRecorder() : ready_(false) { 3207 registrar_.Add(this, NotificationType::EXTENSIONS_READY, 3208 NotificationService::AllSources()); 3209 } 3210 3211 void set_ready(bool value) { ready_ = value; } 3212 bool ready() { return ready_; } 3213 3214 private: 3215 virtual void Observe(NotificationType type, 3216 const NotificationSource& source, 3217 const NotificationDetails& details) { 3218 switch (type.value) { 3219 case NotificationType::EXTENSIONS_READY: 3220 ready_ = true; 3221 break; 3222 default: 3223 NOTREACHED(); 3224 } 3225 } 3226 3227 NotificationRegistrar registrar_; 3228 bool ready_; 3229 }; 3230 3231 // Test that we get enabled/disabled correctly for all the pref/command-line 3232 // combinations. We don't want to derive from the ExtensionServiceTest class 3233 // for this test, so we use ExtensionServiceTestSimple. 3234 // 3235 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are 3236 // enabled or not. 3237 TEST(ExtensionServiceTestSimple, Enabledness) { 3238 ExtensionsReadyRecorder recorder; 3239 scoped_ptr<TestingProfile> profile(new TestingProfile()); 3240 MessageLoop loop; 3241 BrowserThread ui_thread(BrowserThread::UI, &loop); 3242 BrowserThread file_thread(BrowserThread::FILE, &loop); 3243 scoped_ptr<CommandLine> command_line; 3244 scoped_refptr<ExtensionService> service; 3245 FilePath install_dir = profile->GetPath() 3246 .AppendASCII(ExtensionService::kInstallDirectoryName); 3247 3248 // By default, we are enabled. 3249 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM)); 3250 service = profile->CreateExtensionService(command_line.get(), 3251 install_dir, 3252 false); 3253 EXPECT_TRUE(service->extensions_enabled()); 3254 service->Init(); 3255 loop.RunAllPending(); 3256 EXPECT_TRUE(recorder.ready()); 3257 3258 // If either the command line or pref is set, we are disabled. 3259 recorder.set_ready(false); 3260 profile.reset(new TestingProfile()); 3261 command_line->AppendSwitch(switches::kDisableExtensions); 3262 service = profile->CreateExtensionService(command_line.get(), 3263 install_dir, 3264 false); 3265 EXPECT_FALSE(service->extensions_enabled()); 3266 service->Init(); 3267 loop.RunAllPending(); 3268 EXPECT_TRUE(recorder.ready()); 3269 3270 recorder.set_ready(false); 3271 profile.reset(new TestingProfile()); 3272 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true); 3273 service = profile->CreateExtensionService(command_line.get(), 3274 install_dir, 3275 false); 3276 EXPECT_FALSE(service->extensions_enabled()); 3277 service->Init(); 3278 loop.RunAllPending(); 3279 EXPECT_TRUE(recorder.ready()); 3280 3281 recorder.set_ready(false); 3282 profile.reset(new TestingProfile()); 3283 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true); 3284 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM)); 3285 service = profile->CreateExtensionService(command_line.get(), 3286 install_dir, 3287 false); 3288 EXPECT_FALSE(service->extensions_enabled()); 3289 service->Init(); 3290 loop.RunAllPending(); 3291 EXPECT_TRUE(recorder.ready()); 3292 3293 // Explicitly delete all the resources used in this test. 3294 profile.reset(); 3295 service = NULL; 3296 } 3297 3298 // Test loading extensions that require limited and unlimited storage quotas. 3299 TEST_F(ExtensionServiceTest, StorageQuota) { 3300 InitializeEmptyExtensionService(); 3301 3302 FilePath extensions_path = data_dir_ 3303 .AppendASCII("storage_quota"); 3304 3305 FilePath limited_quota_ext = 3306 extensions_path.AppendASCII("limited_quota") 3307 .AppendASCII("1.0"); 3308 3309 // The old permission name for unlimited quota was "unlimited_storage", but 3310 // we changed it to "unlimitedStorage". This tests both versions. 3311 FilePath unlimited_quota_ext = 3312 extensions_path.AppendASCII("unlimited_quota") 3313 .AppendASCII("1.0"); 3314 FilePath unlimited_quota_ext2 = 3315 extensions_path.AppendASCII("unlimited_quota") 3316 .AppendASCII("2.0"); 3317 service_->LoadExtension(limited_quota_ext); 3318 service_->LoadExtension(unlimited_quota_ext); 3319 service_->LoadExtension(unlimited_quota_ext2); 3320 loop_.RunAllPending(); 3321 3322 ASSERT_EQ(3u, loaded_.size()); 3323 EXPECT_TRUE(profile_.get()); 3324 EXPECT_FALSE(profile_->IsOffTheRecord()); 3325 3326 // Open the database from each origin to make the tracker aware 3327 // of the existence of these origins and to get their quotas. 3328 int64 limited_quota = -1; 3329 int64 unlimited_quota = -1; 3330 string16 limited_quota_identifier = 3331 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[0]->url()); 3332 string16 unlimited_quota_identifier = 3333 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[1]->url()); 3334 string16 unlimited_quota_identifier2 = 3335 webkit_database::DatabaseUtil::GetOriginIdentifier(loaded_[2]->url()); 3336 string16 db_name = UTF8ToUTF16("db"); 3337 string16 description = UTF8ToUTF16("db_description"); 3338 int64 database_size; 3339 webkit_database::DatabaseTracker* db_tracker = profile_->GetDatabaseTracker(); 3340 3341 // First check the normal limited quota extension. 3342 db_tracker->DatabaseOpened(limited_quota_identifier, db_name, description, 3343 1, &database_size, &limited_quota); 3344 db_tracker->DatabaseClosed(limited_quota_identifier, db_name); 3345 EXPECT_EQ(profile_->GetDatabaseTracker()->GetDefaultQuota(), limited_quota); 3346 3347 // Now check the two unlimited quota ones. 3348 db_tracker->DatabaseOpened(unlimited_quota_identifier, db_name, description, 3349 1, &database_size, &unlimited_quota); 3350 db_tracker->DatabaseClosed(unlimited_quota_identifier, db_name); 3351 EXPECT_EQ(kint64max, unlimited_quota); 3352 db_tracker->DatabaseOpened(unlimited_quota_identifier2, db_name, description, 3353 1, &database_size, &unlimited_quota); 3354 db_tracker->DatabaseClosed(unlimited_quota_identifier2, db_name); 3355 3356 EXPECT_EQ(kint64max, unlimited_quota); 3357 } 3358 3359 // Tests ExtensionService::register_component_extension(). 3360 TEST_F(ExtensionServiceTest, ComponentExtensions) { 3361 InitializeEmptyExtensionService(); 3362 3363 // Component extensions should work even when extensions are disabled. 3364 set_extensions_enabled(false); 3365 3366 FilePath path = data_dir_ 3367 .AppendASCII("good") 3368 .AppendASCII("Extensions") 3369 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj") 3370 .AppendASCII("1.0.0.0"); 3371 3372 std::string manifest; 3373 ASSERT_TRUE(file_util::ReadFileToString( 3374 path.Append(Extension::kManifestFilename), &manifest)); 3375 3376 service_->register_component_extension( 3377 ExtensionService::ComponentExtensionInfo(manifest, path)); 3378 service_->Init(); 3379 3380 // Note that we do not pump messages -- the extension should be loaded 3381 // immediately. 3382 3383 EXPECT_EQ(0u, GetErrors().size()); 3384 ASSERT_EQ(1u, loaded_.size()); 3385 EXPECT_EQ(Extension::COMPONENT, loaded_[0]->location()); 3386 EXPECT_EQ(1u, service_->extensions()->size()); 3387 3388 // Component extensions shouldn't get recourded in the prefs. 3389 ValidatePrefKeyCount(0); 3390 3391 // Reload all extensions, and make sure it comes back. 3392 std::string extension_id = service_->extensions()->at(0)->id(); 3393 loaded_.clear(); 3394 service_->ReloadExtensions(); 3395 ASSERT_EQ(1u, service_->extensions()->size()); 3396 EXPECT_EQ(extension_id, service_->extensions()->at(0)->id()); 3397 } 3398 3399 namespace { 3400 3401 bool AlwaysInstall(const Extension& extension) { 3402 return true; 3403 } 3404 3405 } // namespace 3406 3407 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) { 3408 InitializeEmptyExtensionService(); 3409 3410 ExtensionSyncData extension_sync_data; 3411 extension_sync_data.id = good_crx; 3412 extension_sync_data.uninstalled = true; 3413 3414 // Should do nothing. 3415 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall); 3416 3417 // Install the extension. 3418 FilePath extension_path = data_dir_.AppendASCII("good.crx"); 3419 InstallCrx(extension_path, true); 3420 EXPECT_TRUE(service_->GetExtensionById(good_crx, true)); 3421 3422 // Should uninstall the extension. 3423 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall); 3424 EXPECT_FALSE(service_->GetExtensionById(good_crx, true)); 3425 3426 // Should again do nothing. 3427 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall); 3428 } 3429 3430 3431 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) { 3432 InitializeEmptyExtensionService(); 3433 3434 FilePath extension_path = data_dir_.AppendASCII("good.crx"); 3435 InstallCrx(extension_path, true); 3436 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx)); 3437 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx)); 3438 3439 ExtensionSyncData extension_sync_data; 3440 extension_sync_data.id = good_crx; 3441 extension_sync_data.version = 3442 *(service_->GetExtensionById(good_crx, true)->version()); 3443 3444 extension_sync_data.enabled = false; 3445 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall); 3446 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx)); 3447 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx)); 3448 3449 extension_sync_data.enabled = true; 3450 extension_sync_data.incognito_enabled = true; 3451 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall); 3452 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx)); 3453 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx)); 3454 3455 extension_sync_data.enabled = false; 3456 extension_sync_data.incognito_enabled = true; 3457 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall); 3458 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx)); 3459 EXPECT_TRUE(service_->IsIncognitoEnabled(good_crx)); 3460 3461 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx)); 3462 } 3463 3464 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) { 3465 InitializeExtensionServiceWithUpdater(); 3466 3467 // Install the extension. 3468 FilePath extension_path = data_dir_.AppendASCII("good.crx"); 3469 InstallCrx(extension_path, true); 3470 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx)); 3471 EXPECT_FALSE(service_->IsIncognitoEnabled(good_crx)); 3472 3473 ExtensionSyncData extension_sync_data; 3474 extension_sync_data.id = good_crx; 3475 extension_sync_data.enabled = true; 3476 extension_sync_data.version = 3477 *(service_->GetExtensionById(good_crx, true)->version()); 3478 3479 // Should do nothing if extension version == sync version. 3480 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall); 3481 EXPECT_FALSE(service_->updater()->WillCheckSoon()); 3482 3483 // Should do nothing if extension version > sync version (but see 3484 // the TODO in ProcessSyncData). 3485 { 3486 scoped_ptr<Version> version(Version::GetVersionFromString("0.0.0.0")); 3487 extension_sync_data.version = *version; 3488 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall); 3489 EXPECT_FALSE(service_->updater()->WillCheckSoon()); 3490 } 3491 3492 // Should kick off an update if extension version < sync version. 3493 { 3494 scoped_ptr<Version> version(Version::GetVersionFromString("9.9.9.9")); 3495 extension_sync_data.version = *version; 3496 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall); 3497 EXPECT_TRUE(service_->updater()->WillCheckSoon()); 3498 } 3499 3500 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx)); 3501 } 3502 3503 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) { 3504 InitializeExtensionServiceWithUpdater(); 3505 3506 ExtensionSyncData extension_sync_data; 3507 extension_sync_data.id = good_crx; 3508 extension_sync_data.update_url = GURL("http://www.google.com"); 3509 extension_sync_data.enabled = true; 3510 { 3511 scoped_ptr<Version> version(Version::GetVersionFromString("1.2.3.4")); 3512 extension_sync_data.version = *version; 3513 } 3514 3515 service_->ProcessSyncData(extension_sync_data, &AlwaysInstall); 3516 EXPECT_TRUE(service_->updater()->WillCheckSoon()); 3517 3518 PendingExtensionInfo info; 3519 EXPECT_TRUE( 3520 service_->pending_extension_manager()->GetById(good_crx, &info)); 3521 EXPECT_EQ(extension_sync_data.update_url, info.update_url()); 3522 EXPECT_TRUE(info.is_from_sync()); 3523 EXPECT_TRUE(info.install_silently()); 3524 EXPECT_EQ(extension_sync_data.enabled, info.enable_on_install()); 3525 EXPECT_EQ(extension_sync_data.incognito_enabled, 3526 info.enable_incognito_on_install()); 3527 EXPECT_EQ(Extension::INTERNAL, info.install_source()); 3528 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|. 3529 } 3530 3531 // Test that when multiple sources try to install an extension, 3532 // we consistently choose the right one. To make tests easy to read, 3533 // methods that fake requests to install crx files in several ways 3534 // are provided. 3535 class ExtensionSourcePriorityTest : public ExtensionServiceTest { 3536 public: 3537 void SetUp() { 3538 // All tests use a single extension. Put the id and path in member vars 3539 // that all methods can read. 3540 crx_id_ = kGoodId; 3541 crx_path_ = data_dir_.AppendASCII("good.crx"); 3542 } 3543 3544 // Fake an external source adding a URL to fetch an extension from. 3545 void AddPendingExternalPrefUrl() { 3546 service_->pending_extension_manager()->AddFromExternalUpdateUrl( 3547 crx_id_, GURL(), Extension::EXTERNAL_PREF_DOWNLOAD); 3548 } 3549 3550 // Fake an external file from external_extensions.json. 3551 void AddPendingExternalPrefFileInstall() { 3552 scoped_ptr<Version> version; 3553 version.reset(Version::GetVersionFromString("1.0.0.0")); 3554 3555 service_->OnExternalExtensionFileFound( 3556 crx_id_, version.get(), crx_path_, Extension::EXTERNAL_PREF); 3557 } 3558 3559 // Fake a request from sync to install an extension. 3560 bool AddPendingSyncInstall() { 3561 return service_->pending_extension_manager()->AddFromSync( 3562 crx_id_, GURL(kGoodUpdateURL), &IsExtension, 3563 kGoodInstallSilently, kGoodInitialState, 3564 kGoodInitialIncognitoEnabled); 3565 } 3566 3567 // Fake a request to install a default app. 3568 void AddPendingDefaultAppInstall() { 3569 service_->pending_extension_manager()->AddFromDefaultAppList(crx_id_); 3570 } 3571 3572 // Fake a policy install. 3573 void AddPendingPolicyInstall() { 3574 scoped_ptr<Version> version; 3575 version.reset(Version::GetVersionFromString("1.0.0.0")); 3576 3577 // Get path to the CRX with id |kGoodId|. 3578 service_->OnExternalExtensionUpdateUrlFound( 3579 crx_id_, GURL(), Extension::EXTERNAL_POLICY_DOWNLOAD); 3580 } 3581 3582 // Get the install source of a pending extension. 3583 Extension::Location GetPendingLocation() { 3584 PendingExtensionInfo info; 3585 EXPECT_TRUE(service_->pending_extension_manager()->GetById(crx_id_, &info)); 3586 return info.install_source(); 3587 } 3588 3589 // Is an extension pending from a sync request? 3590 bool GetPendingIsFromSync() { 3591 PendingExtensionInfo info; 3592 EXPECT_TRUE(service_->pending_extension_manager()->GetById(crx_id_, &info)); 3593 return info.is_from_sync(); 3594 } 3595 3596 // Is the CRX id these tests use pending? 3597 bool IsCrxPending() { 3598 return service_->pending_extension_manager()->IsIdPending(crx_id_); 3599 } 3600 3601 // Is an extension installed? 3602 bool IsCrxInstalled() { 3603 return (service_->GetExtensionById(crx_id_, true) != NULL); 3604 } 3605 3606 protected: 3607 // All tests use a single extension. Making the id and path member 3608 // vars avoids pasing the same argument to every method. 3609 std::string crx_id_; 3610 FilePath crx_path_; 3611 }; 3612 3613 #if defined(OS_CHROMEOS) 3614 // TODO(skerner): crbug/79755 3615 #define MAYBE_PendingExternalFileOverSync DISABLED_PendingExternalFileOverSync 3616 #else 3617 #define MAYBE_PendingExternalFileOverSync PendingExternalFileOverSync 3618 #endif 3619 // Test that a pending request for installation of an external CRX from 3620 // an update URL overrides a pending request to install the same extension 3621 // from sync. 3622 TEST_F(ExtensionSourcePriorityTest, MAYBE_PendingExternalFileOverSync) { 3623 InitializeEmptyExtensionService(); 3624 3625 ASSERT_FALSE(IsCrxInstalled()); 3626 3627 // Install pending extension from sync. 3628 AddPendingSyncInstall(); 3629 ASSERT_EQ(Extension::INTERNAL, GetPendingLocation()); 3630 EXPECT_TRUE(GetPendingIsFromSync()); 3631 ASSERT_FALSE(IsCrxInstalled()); 3632 3633 // Install pending as external prefs json would. 3634 AddPendingExternalPrefFileInstall(); 3635 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation()); 3636 ASSERT_FALSE(IsCrxInstalled()); 3637 3638 // Another request from sync should be ignorred. 3639 AddPendingSyncInstall(); 3640 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation()); 3641 ASSERT_FALSE(IsCrxInstalled()); 3642 3643 WaitForCrxInstall(crx_path_, true); 3644 ASSERT_TRUE(IsCrxInstalled()); 3645 } 3646 3647 #if defined(OS_CHROMEOS) 3648 // TODO(skerner): crbug/79755 3649 #define MAYBE_PendingExternalUrlOverSync DISABLED_PendingExternalUrlOverSync 3650 #else 3651 #define MAYBE_PendingExternalUrlOverSync PendingExternalUrlOverSync 3652 #endif 3653 // Test that an install of an external CRX from an update overrides 3654 // an install of the same extension from sync. 3655 TEST_F(ExtensionSourcePriorityTest, MAYBE_PendingExternalUrlOverSync) { 3656 InitializeEmptyExtensionService(); 3657 ASSERT_FALSE(IsCrxInstalled()); 3658 3659 AddPendingSyncInstall(); 3660 ASSERT_EQ(Extension::INTERNAL, GetPendingLocation()); 3661 EXPECT_TRUE(GetPendingIsFromSync()); 3662 ASSERT_FALSE(IsCrxInstalled()); 3663 3664 AddPendingExternalPrefUrl(); 3665 ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation()); 3666 EXPECT_FALSE(GetPendingIsFromSync()); 3667 ASSERT_FALSE(IsCrxInstalled()); 3668 3669 AddPendingSyncInstall(); 3670 ASSERT_EQ(Extension::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation()); 3671 EXPECT_FALSE(GetPendingIsFromSync()); 3672 ASSERT_FALSE(IsCrxInstalled()); 3673 } 3674 3675 #if defined(OS_CHROMEOS) 3676 // TODO(skerner): crbug/79755 3677 #define MAYBE_PendingExternalFileOverDefaultApp DISABLED_PendingExternalFileOverDefaultApp 3678 #else 3679 #define MAYBE_PendingExternalFileOverDefaultApp PendingExternalFileOverDefaultApp 3680 #endif 3681 // Test that an install of an external CRX overrides a request for a default 3682 // app. 3683 TEST_F(ExtensionSourcePriorityTest, MAYBE_PendingExternalFileOverDefaultApp) { 3684 InitializeEmptyExtensionService(); 3685 ASSERT_FALSE(IsCrxInstalled()); 3686 3687 AddPendingDefaultAppInstall(); 3688 ASSERT_EQ(Extension::INTERNAL, GetPendingLocation()); 3689 ASSERT_FALSE(IsCrxInstalled()); 3690 3691 AddPendingExternalPrefFileInstall(); 3692 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation()); 3693 ASSERT_FALSE(IsCrxInstalled()); 3694 3695 AddPendingDefaultAppInstall(); 3696 ASSERT_EQ(Extension::EXTERNAL_PREF, GetPendingLocation()); 3697 ASSERT_FALSE(IsCrxInstalled()); 3698 3699 WaitForCrxInstall(crx_path_, true); 3700 ASSERT_TRUE(IsCrxInstalled()); 3701 } 3702 3703 #if defined(OS_CHROMEOS) 3704 // TODO(skerner): crbug/79755 3705 #define MAYBE_InstallExternalBlocksSyncRequest DISABLED_InstallExternalBlocksSyncRequest 3706 #else 3707 #define MAYBE_InstallExternalBlocksSyncRequest InstallExternalBlocksSyncRequest 3708 #endif 3709 // Test that an external install request stops sync from installing 3710 // the same extension. 3711 TEST_F(ExtensionSourcePriorityTest, MAYBE_InstallExternalBlocksSyncRequest) { 3712 InitializeEmptyExtensionService(); 3713 ASSERT_FALSE(IsCrxInstalled()); 3714 3715 // External prefs starts an install. 3716 AddPendingExternalPrefFileInstall(); 3717 3718 // Crx installer was made, but has not yet run. 3719 ASSERT_FALSE(IsCrxInstalled()); 3720 3721 // Before the CRX installer runs, Sync requests that the same extension 3722 // be installed. Should fail, because an external source is pending. 3723 ASSERT_FALSE(AddPendingSyncInstall()); 3724 3725 // Wait for the external source to install. 3726 WaitForCrxInstall(crx_path_, true); 3727 ASSERT_TRUE(IsCrxInstalled()); 3728 3729 // Now that the extension is installed, sync request should fail 3730 // because the extension is already installed. 3731 ASSERT_FALSE(AddPendingSyncInstall()); 3732 } 3733