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