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.
5 #include "chrome/browser/extensions/extension_service_unittest.h"
11 #include "base/at_exit.h"
12 #include "base/basictypes.h"
13 #include "base/bind.h"
14 #include "base/command_line.h"
15 #include "base/file_util.h"
16 #include "base/files/file_enumerator.h"
17 #include "base/files/scoped_temp_dir.h"
18 #include "base/json/json_file_value_serializer.h"
19 #include "base/json/json_reader.h"
20 #include "base/json/json_string_value_serializer.h"
21 #include "base/memory/scoped_ptr.h"
22 #include "base/memory/weak_ptr.h"
23 #include "base/message_loop/message_loop.h"
24 #include "base/path_service.h"
25 #include "base/prefs/scoped_user_pref_update.h"
26 #include "base/stl_util.h"
27 #include "base/strings/string16.h"
28 #include "base/strings/string_number_conversions.h"
29 #include "base/strings/string_util.h"
30 #include "base/strings/utf_string_conversions.h"
31 #include "base/version.h"
32 #include "chrome/browser/browser_process.h"
33 #include "chrome/browser/chrome_notification_types.h"
34 #include "chrome/browser/extensions/app_sync_data.h"
35 #include "chrome/browser/extensions/blacklist.h"
36 #include "chrome/browser/extensions/component_loader.h"
37 #include "chrome/browser/extensions/crx_installer.h"
38 #include "chrome/browser/extensions/default_apps.h"
39 #include "chrome/browser/extensions/extension_creator.h"
40 #include "chrome/browser/extensions/extension_error_reporter.h"
41 #include "chrome/browser/extensions/extension_error_ui.h"
42 #include "chrome/browser/extensions/extension_notification_observer.h"
43 #include "chrome/browser/extensions/extension_service.h"
44 #include "chrome/browser/extensions/extension_sorting.h"
45 #include "chrome/browser/extensions/extension_special_storage_policy.h"
46 #include "chrome/browser/extensions/extension_sync_data.h"
47 #include "chrome/browser/extensions/extension_system.h"
48 #include "chrome/browser/extensions/extension_util.h"
49 #include "chrome/browser/extensions/external_install_ui.h"
50 #include "chrome/browser/extensions/external_policy_loader.h"
51 #include "chrome/browser/extensions/external_pref_loader.h"
52 #include "chrome/browser/extensions/external_provider_impl.h"
53 #include "chrome/browser/extensions/external_provider_interface.h"
54 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
55 #include "chrome/browser/extensions/install_observer.h"
56 #include "chrome/browser/extensions/install_tracker.h"
57 #include "chrome/browser/extensions/install_tracker_factory.h"
58 #include "chrome/browser/extensions/installed_loader.h"
59 #include "chrome/browser/extensions/management_policy.h"
60 #include "chrome/browser/extensions/pack_extension_job.h"
61 #include "chrome/browser/extensions/pending_extension_info.h"
62 #include "chrome/browser/extensions/pending_extension_manager.h"
63 #include "chrome/browser/extensions/test_extension_system.h"
64 #include "chrome/browser/extensions/test_management_policy.h"
65 #include "chrome/browser/extensions/unpacked_installer.h"
66 #include "chrome/browser/extensions/updater/extension_updater.h"
67 #include "chrome/browser/prefs/browser_prefs.h"
68 #include "chrome/browser/prefs/pref_service_mock_builder.h"
69 #include "chrome/browser/prefs/pref_service_syncable.h"
70 #include "chrome/browser/sync/profile_sync_service.h"
71 #include "chrome/browser/sync/profile_sync_service_factory.h"
72 #include "chrome/common/chrome_constants.h"
73 #include "chrome/common/chrome_paths.h"
74 #include "chrome/common/chrome_switches.h"
75 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
76 #include "chrome/common/extensions/background_info.h"
77 #include "chrome/common/extensions/extension.h"
78 #include "chrome/common/extensions/extension_builder.h"
79 #include "chrome/common/extensions/extension_l10n_util.h"
80 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
81 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
82 #include "chrome/common/extensions/manifest_url_handler.h"
83 #include "chrome/common/extensions/value_builder.h"
84 #include "chrome/common/pref_names.h"
85 #include "chrome/common/url_constants.h"
86 #include "chrome/test/base/scoped_browser_locale.h"
87 #include "chrome/test/base/testing_profile.h"
88 #include "components/user_prefs/pref_registry_syncable.h"
89 #include "content/public/browser/dom_storage_context.h"
90 #include "content/public/browser/gpu_data_manager.h"
91 #include "content/public/browser/indexed_db_context.h"
92 #include "content/public/browser/notification_registrar.h"
93 #include "content/public/browser/notification_service.h"
94 #include "content/public/browser/plugin_service.h"
95 #include "content/public/browser/render_process_host.h"
96 #include "content/public/browser/storage_partition.h"
97 #include "content/public/common/content_constants.h"
98 #include "content/public/test/test_utils.h"
99 #include "extensions/common/constants.h"
100 #include "extensions/common/extension_resource.h"
101 #include "extensions/common/manifest_constants.h"
102 #include "extensions/common/permissions/permission_set.h"
103 #include "extensions/common/url_pattern.h"
104 #include "gpu/config/gpu_info.h"
105 #include "grit/browser_resources.h"
106 #include "net/cookies/canonical_cookie.h"
107 #include "net/cookies/cookie_monster.h"
108 #include "net/cookies/cookie_options.h"
109 #include "net/url_request/url_request_context.h"
110 #include "net/url_request/url_request_context_getter.h"
111 #include "sync/api/string_ordinal.h"
112 #include "sync/api/sync_data.h"
113 #include "sync/api/sync_error_factory.h"
114 #include "sync/api/sync_error_factory_mock.h"
115 #include "sync/api/syncable_service.h"
116 #include "sync/protocol/app_specifics.pb.h"
117 #include "sync/protocol/extension_specifics.pb.h"
118 #include "sync/protocol/sync.pb.h"
119 #include "testing/gtest/include/gtest/gtest.h"
120 #include "testing/platform_test.h"
121 #include "url/gurl.h"
122 #include "webkit/browser/database/database_tracker.h"
123 #include "webkit/browser/quota/quota_manager.h"
124 #include "webkit/common/database/database_identifier.h"
126 #if defined(OS_CHROMEOS)
127 #include "chrome/browser/chromeos/extensions/install_limiter.h"
128 #include "chrome/browser/chromeos/login/user_manager.h"
129 #include "chrome/browser/chromeos/settings/cros_settings.h"
130 #include "chrome/browser/chromeos/settings/device_settings_service.h"
133 // The blacklist tests rely on safe browsing.
134 #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
135 #define ENABLE_BLACKLIST_TESTS
138 using base::DictionaryValue;
139 using base::ListValue;
141 using content::BrowserContext;
142 using content::BrowserThread;
143 using content::DOMStorageContext;
144 using content::IndexedDBContext;
145 using content::PluginService;
146 using extensions::APIPermission;
147 using extensions::APIPermissionSet;
148 using extensions::Blacklist;
149 using extensions::CrxInstaller;
150 using extensions::Extension;
151 using extensions::ExtensionCreator;
152 using extensions::ExtensionPrefs;
153 using extensions::ExtensionResource;
154 using extensions::ExtensionSystem;
155 using extensions::FakeSafeBrowsingDatabaseManager;
156 using extensions::FeatureSwitch;
157 using extensions::Manifest;
158 using extensions::PermissionSet;
159 using extensions::TestExtensionSystem;
160 using extensions::URLPatternSet;
162 namespace keys = extensions::manifest_keys;
166 // Extension ids used during testing.
167 const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
168 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
169 const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
170 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
171 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
172 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
173 const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
174 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
175 const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad";
176 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
177 const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
178 const char unpacked[] = "cbcdidchbppangcjoddlpdjlenngjldk";
179 const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
181 struct ExtensionsOrder {
182 bool operator()(const scoped_refptr<const Extension>& a,
183 const scoped_refptr<const Extension>& b) {
184 return a->name() < b->name();
188 static std::vector<string16> GetErrors() {
189 const std::vector<string16>* errors =
190 ExtensionErrorReporter::GetInstance()->GetErrors();
191 std::vector<string16> ret_val;
193 for (std::vector<string16>::const_iterator iter = errors->begin();
194 iter != errors->end(); ++iter) {
195 std::string utf8_error = UTF16ToUTF8(*iter);
196 if (utf8_error.find(".svn") == std::string::npos) {
197 ret_val.push_back(*iter);
201 // The tests rely on the errors being in a certain order, which can vary
202 // depending on how filesystem iteration works.
203 std::stable_sort(ret_val.begin(), ret_val.end());
208 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
209 int schemes = URLPattern::SCHEME_ALL;
210 extent->AddPattern(URLPattern(schemes, pattern));
213 base::FilePath GetTemporaryFile() {
214 base::FilePath temp_file;
215 CHECK(file_util::CreateTemporaryFile(&temp_file));
220 bool WaitForCountNotificationsCallback(int *count) {
221 return --(*count) == 0;
226 class MockExtensionProvider : public extensions::ExternalProviderInterface {
228 MockExtensionProvider(
229 VisitorInterface* visitor,
230 Manifest::Location location)
231 : location_(location), visitor_(visitor), visit_count_(0) {
234 virtual ~MockExtensionProvider() {}
236 void UpdateOrAddExtension(const std::string& id,
237 const std::string& version,
238 const base::FilePath& path) {
239 extension_map_[id] = std::make_pair(version, path);
242 void RemoveExtension(const std::string& id) {
243 extension_map_.erase(id);
246 // ExternalProvider implementation:
247 virtual void VisitRegisteredExtension() OVERRIDE {
249 for (DataMap::const_iterator i = extension_map_.begin();
250 i != extension_map_.end(); ++i) {
251 Version version(i->second.first);
253 visitor_->OnExternalExtensionFileFound(
254 i->first, &version, i->second.second, location_,
255 Extension::NO_FLAGS, false);
257 visitor_->OnExternalProviderReady(this);
260 virtual bool HasExtension(const std::string& id) const OVERRIDE {
261 return extension_map_.find(id) != extension_map_.end();
264 virtual bool GetExtensionDetails(
265 const std::string& id,
266 Manifest::Location* location,
267 scoped_ptr<Version>* version) const OVERRIDE {
268 DataMap::const_iterator it = extension_map_.find(id);
269 if (it == extension_map_.end())
273 version->reset(new Version(it->second.first));
276 *location = location_;
281 virtual bool IsReady() const OVERRIDE {
285 virtual void ServiceShutdown() OVERRIDE {
288 int visit_count() const { return visit_count_; }
289 void set_visit_count(int visit_count) {
290 visit_count_ = visit_count;
294 typedef std::map< std::string, std::pair<std::string, base::FilePath> >
296 DataMap extension_map_;
297 Manifest::Location location_;
298 VisitorInterface* visitor_;
300 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
301 // Mutable because it must be incremented on each call to
302 // VisitRegisteredExtension(), which must be a const method to inherit
303 // from the class being mocked.
304 mutable int visit_count_;
306 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
309 class MockProviderVisitor
310 : public extensions::ExternalProviderInterface::VisitorInterface {
312 // The provider will return |fake_base_path| from
313 // GetBaseCrxFilePath(). User can test the behavior with
314 // and without an empty path using this parameter.
315 explicit MockProviderVisitor(base::FilePath fake_base_path)
317 fake_base_path_(fake_base_path),
318 expected_creation_flags_(Extension::NO_FLAGS) {
319 profile_.reset(new TestingProfile);
322 MockProviderVisitor(base::FilePath fake_base_path,
323 int expected_creation_flags)
325 fake_base_path_(fake_base_path),
326 expected_creation_flags_(expected_creation_flags) {
329 int Visit(const std::string& json_data) {
330 // Give the test json file to the provider for parsing.
331 provider_.reset(new extensions::ExternalProviderImpl(
333 new extensions::ExternalTestingLoader(json_data, fake_base_path_),
335 Manifest::EXTERNAL_PREF,
336 Manifest::EXTERNAL_PREF_DOWNLOAD,
337 Extension::NO_FLAGS));
339 // We also parse the file into a dictionary to compare what we get back
340 // from the provider.
341 JSONStringValueSerializer serializer(json_data);
342 Value* json_value = serializer.Deserialize(NULL, NULL);
344 if (!json_value || !json_value->IsType(Value::TYPE_DICTIONARY)) {
345 NOTREACHED() << "Unable to deserialize json data";
348 DictionaryValue* external_extensions =
349 static_cast<DictionaryValue*>(json_value);
350 prefs_.reset(external_extensions);
353 // Reset our counter.
355 // Ask the provider to look up all extensions and return them.
356 provider_->VisitRegisteredExtension();
361 virtual bool OnExternalExtensionFileFound(const std::string& id,
362 const Version* version,
363 const base::FilePath& path,
364 Manifest::Location unused,
366 bool mark_acknowledged) OVERRIDE {
367 EXPECT_EQ(expected_creation_flags_, creation_flags);
370 DictionaryValue* pref;
371 // This tests is to make sure that the provider only notifies us of the
372 // values we gave it. So if the id we doesn't exist in our internal
373 // dictionary then something is wrong.
374 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
375 << "Got back ID (" << id.c_str() << ") we weren't expecting";
377 EXPECT_TRUE(path.IsAbsolute());
378 if (!fake_base_path_.empty())
379 EXPECT_TRUE(fake_base_path_.IsParent(path));
382 EXPECT_TRUE(provider_->HasExtension(id));
384 // Ask provider if the extension we got back is registered.
385 Manifest::Location location = Manifest::INVALID_LOCATION;
386 scoped_ptr<Version> v1;
387 base::FilePath crx_path;
389 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
390 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
392 scoped_ptr<Version> v2;
393 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
394 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
395 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
396 EXPECT_EQ(Manifest::EXTERNAL_PREF, location);
398 // Remove it so we won't count it ever again.
399 prefs_->Remove(id, NULL);
404 virtual bool OnExternalExtensionUpdateUrlFound(
405 const std::string& id, const GURL& update_url,
406 Manifest::Location location,
408 bool mark_acknowledged) OVERRIDE {
410 DictionaryValue* pref;
411 // This tests is to make sure that the provider only notifies us of the
412 // values we gave it. So if the id we doesn't exist in our internal
413 // dictionary then something is wrong.
414 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
415 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
416 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location);
419 EXPECT_TRUE(provider_->HasExtension(id));
421 // External extensions with update URLs do not have versions.
422 scoped_ptr<Version> v1;
423 Manifest::Location location1 = Manifest::INVALID_LOCATION;
424 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
425 EXPECT_FALSE(v1.get());
426 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1);
428 // Remove it so we won't count it again.
429 prefs_->Remove(id, NULL);
434 virtual void OnExternalProviderReady(
435 const extensions::ExternalProviderInterface* provider) OVERRIDE {
436 EXPECT_EQ(provider, provider_.get());
437 EXPECT_TRUE(provider->IsReady());
442 base::FilePath fake_base_path_;
443 int expected_creation_flags_;
444 scoped_ptr<extensions::ExternalProviderImpl> provider_;
445 scoped_ptr<DictionaryValue> prefs_;
446 scoped_ptr<TestingProfile> profile_;
448 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
451 ExtensionServiceTestBase::ExtensionServiceInitParams::
452 ExtensionServiceInitParams()
453 : autoupdate_enabled(false), is_first_run(true), profile_is_managed(false) {
456 // Our message loop may be used in tests which require it to be an IO loop.
457 ExtensionServiceTestBase::ExtensionServiceTestBase()
458 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
460 management_policy_(NULL),
461 expected_extensions_count_(0) {
462 base::FilePath test_data_dir;
463 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) {
467 data_dir_ = test_data_dir.AppendASCII("extensions");
470 ExtensionServiceTestBase::~ExtensionServiceTestBase() {
474 void ExtensionServiceTestBase::InitializeExtensionService(
475 const ExtensionServiceTestBase::ExtensionServiceInitParams& params) {
476 TestingProfile::Builder profile_builder;
477 // Create a PrefService that only contains user defined preference values.
478 PrefServiceMockBuilder builder;
479 // If pref_file is empty, TestingProfile automatically creates
480 // TestingPrefServiceSyncable instance.
481 if (!params.pref_file.empty()) {
482 builder.WithUserFilePrefs(params.pref_file,
483 base::MessageLoopProxy::current().get());
484 scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
485 new user_prefs::PrefRegistrySyncable);
486 scoped_ptr<PrefServiceSyncable> prefs(
487 builder.CreateSyncable(registry.get()));
488 chrome::RegisterUserProfilePrefs(registry.get());
489 profile_builder.SetPrefService(prefs.Pass());
492 if (params.profile_is_managed)
493 profile_builder.SetManagedUserId("asdf");
495 profile_builder.SetPath(params.profile_path);
496 profile_ = profile_builder.Build();
498 TestExtensionSystem* system = static_cast<TestExtensionSystem*>(
499 ExtensionSystem::Get(profile_.get()));
500 if (!params.is_first_run) {
501 ExtensionPrefs* prefs = system->CreateExtensionPrefs(
502 CommandLine::ForCurrentProcess(),
503 params.extensions_install_dir);
504 prefs->SetAlertSystemFirstRun();
507 service_ = system->CreateExtensionService(
508 CommandLine::ForCurrentProcess(),
509 params.extensions_install_dir,
510 params.autoupdate_enabled);
512 service_->SetFileTaskRunnerForTesting(
513 base::MessageLoopProxy::current().get());
514 service_->set_extensions_enabled(true);
515 service_->set_show_extensions_prompts(false);
516 service_->set_install_updates_when_idle_for_test(false);
519 ExtensionSystem::Get(profile_.get())->management_policy();
521 extensions_install_dir_ = params.extensions_install_dir;
523 // When we start up, we want to make sure there is no external provider,
524 // since the ExtensionService on Windows will use the Registry as a default
525 // provider and if there is something already registered there then it will
526 // interfere with the tests. Those tests that need an external provider
527 // will register one specifically.
528 service_->ClearProvidersForTesting();
530 #if defined(OS_CHROMEOS)
531 extensions::InstallLimiter::Get(profile_.get())->DisableForTest();
534 expected_extensions_count_ = 0;
537 void ExtensionServiceTestBase::InitializeInstalledExtensionService(
538 const base::FilePath& prefs_file,
539 const base::FilePath& source_install_dir) {
540 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
541 base::FilePath path = temp_dir_.path();
542 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
543 EXPECT_TRUE(base::DeleteFile(path, true));
544 base::PlatformFileError error = base::PLATFORM_FILE_OK;
545 EXPECT_TRUE(file_util::CreateDirectoryAndGetError(path, &error)) << error;
546 base::FilePath temp_prefs = path.Append(FILE_PATH_LITERAL("Preferences"));
547 EXPECT_TRUE(base::CopyFile(prefs_file, temp_prefs));
549 base::FilePath extensions_install_dir =
550 path.Append(FILE_PATH_LITERAL("Extensions"));
551 EXPECT_TRUE(base::DeleteFile(extensions_install_dir, true));
553 base::CopyDirectory(source_install_dir, extensions_install_dir, true));
555 ExtensionServiceInitParams params;
556 params.profile_path = path;
557 params.pref_file = temp_prefs;
558 params.extensions_install_dir = extensions_install_dir;
559 InitializeExtensionService(params);
562 void ExtensionServiceTestBase::InitializeGoodInstalledExtensionService() {
563 base::FilePath source_install_dir = data_dir_
565 .AppendASCII("Extensions");
566 base::FilePath pref_path = source_install_dir
568 .AppendASCII("Preferences");
569 InitializeInstalledExtensionService(pref_path, source_install_dir);
572 void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
573 InitializeExtensionService(CreateDefaultInitParams());
576 void ExtensionServiceTestBase::InitializeExtensionProcessManager() {
577 static_cast<extensions::TestExtensionSystem*>(
578 ExtensionSystem::Get(profile_.get()))->
579 CreateExtensionProcessManager();
582 void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
583 ExtensionServiceInitParams params = CreateDefaultInitParams();
584 params.autoupdate_enabled = true;
585 InitializeExtensionService(params);
586 service_->updater()->Start();
589 void ExtensionServiceTestBase::InitializeExtensionSyncService() {
590 extension_sync_service_.reset(new ExtensionSyncService(
591 profile_.get(), service_->extension_prefs(), service_));
595 void ExtensionServiceTestBase::SetUpTestCase() {
596 ExtensionErrorReporter::Init(false); // no noisy errors
599 void ExtensionServiceTestBase::SetUp() {
600 ExtensionErrorReporter::GetInstance()->ClearErrors();
601 content::RenderProcessHost::SetRunRendererInProcess(true);
604 void ExtensionServiceTestBase::TearDown() {
605 content::RenderProcessHost::SetRunRendererInProcess(false);
608 ExtensionServiceTestBase::ExtensionServiceInitParams
609 ExtensionServiceTestBase::CreateDefaultInitParams() {
610 ExtensionServiceInitParams params;
611 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
612 base::FilePath path = temp_dir_.path();
613 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
614 EXPECT_TRUE(base::DeleteFile(path, true));
615 base::PlatformFileError error = base::PLATFORM_FILE_OK;
616 EXPECT_TRUE(file_util::CreateDirectoryAndGetError(path, &error)) << error;
617 base::FilePath prefs_filename =
618 path.Append(FILE_PATH_LITERAL("TestPreferences"));
619 base::FilePath extensions_install_dir =
620 path.Append(FILE_PATH_LITERAL("Extensions"));
621 EXPECT_TRUE(base::DeleteFile(extensions_install_dir, true));
622 EXPECT_TRUE(file_util::CreateDirectoryAndGetError(extensions_install_dir,
625 params.profile_path = path;
626 params.pref_file = prefs_filename;
627 params.extensions_install_dir = extensions_install_dir;
631 class ExtensionServiceTest
632 : public ExtensionServiceTestBase, public content::NotificationObserver {
634 ExtensionServiceTest()
637 override_external_install_prompt_(
638 FeatureSwitch::prompt_for_external_extensions(), false) {
639 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
640 content::NotificationService::AllSources());
641 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
642 content::NotificationService::AllSources());
643 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
644 content::NotificationService::AllSources());
647 virtual void Observe(int type,
648 const content::NotificationSource& source,
649 const content::NotificationDetails& details) OVERRIDE {
651 case chrome::NOTIFICATION_EXTENSION_LOADED: {
652 const Extension* extension =
653 content::Details<const Extension>(details).ptr();
654 loaded_.push_back(make_scoped_refptr(extension));
655 // The tests rely on the errors being in a certain order, which can vary
656 // depending on how filesystem iteration works.
657 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
661 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
663 content::Details<extensions::UnloadedExtensionInfo>(
665 unloaded_id_ = e->id();
666 extensions::ExtensionList::iterator i =
667 std::find(loaded_.begin(), loaded_.end(), e);
668 // TODO(erikkay) fix so this can be an assert. Right now the tests
669 // are manually calling clear() on loaded_, so this isn't doable.
670 if (i == loaded_.end())
675 case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
676 const extensions::InstalledExtensionInfo* installed_info =
677 content::Details<const extensions::InstalledExtensionInfo>(details)
679 installed_ = installed_info->extension;
680 was_update_ = installed_info->is_update;
681 old_name_ = installed_info->old_name;
690 void AddMockExternalProvider(
691 extensions::ExternalProviderInterface* provider) {
692 service_->AddProviderForTesting(provider);
695 void MockSyncStartFlare(bool* was_called,
696 syncer::ModelType* model_type_passed_in,
697 syncer::ModelType model_type) {
699 *model_type_passed_in = model_type;
703 // Paths to some of the fake extensions.
704 base::FilePath good0_path() {
705 return data_dir_.AppendASCII("good").AppendASCII("Extensions")
706 .AppendASCII(good0).AppendASCII("1.0.0.0");
709 base::FilePath good1_path() {
710 return data_dir_.AppendASCII("good").AppendASCII("Extensions")
711 .AppendASCII(good1).AppendASCII("2");
714 base::FilePath good2_path() {
715 return data_dir_.AppendASCII("good").AppendASCII("Extensions")
716 .AppendASCII(good2).AppendASCII("1.0");
719 void TestExternalProvider(MockExtensionProvider* provider,
720 Manifest::Location location);
722 void PackCRX(const base::FilePath& dir_path,
723 const base::FilePath& pem_path,
724 const base::FilePath& crx_path) {
725 // Use the existing pem key, if provided.
726 base::FilePath pem_output_path;
727 if (pem_path.value().empty()) {
728 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
730 ASSERT_TRUE(base::PathExists(pem_path));
733 ASSERT_TRUE(base::DeleteFile(crx_path, false));
735 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
736 ASSERT_TRUE(creator->Run(dir_path,
740 ExtensionCreator::kOverwriteCRX));
742 ASSERT_TRUE(base::PathExists(crx_path));
745 // Create a CrxInstaller and start installation. To allow the install
746 // to happen, use base::RunLoop().RunUntilIdle();. Most tests will not use
747 // this method directly. Instead, use InstallCrx(), which waits for
748 // the crx to be installed and does extra error checking.
749 void StartCRXInstall(const base::FilePath& crx_path) {
750 StartCRXInstall(crx_path, Extension::NO_FLAGS);
753 void StartCRXInstall(const base::FilePath& crx_path, int creation_flags) {
754 ASSERT_TRUE(base::PathExists(crx_path))
755 << "Path does not exist: "<< crx_path.value().c_str();
756 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
757 installer->set_creation_flags(creation_flags);
758 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT)) {
759 installer->set_allow_silent_install(true);
762 content::WindowedNotificationObserver windowed_observer(
763 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
764 content::Source<extensions::CrxInstaller>(installer));
766 installer->InstallCrx(crx_path);
773 INSTALL_WITHOUT_LOAD,
776 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
777 const base::FilePath& pem_path,
778 InstallState install_state,
779 int creation_flags) {
780 base::FilePath crx_path;
781 base::ScopedTempDir temp_dir;
782 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
783 crx_path = temp_dir.path().AppendASCII("temp.crx");
785 PackCRX(dir_path, pem_path, crx_path);
786 return InstallCRX(crx_path, install_state, creation_flags);
789 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
790 const base::FilePath& pem_path,
791 InstallState install_state) {
792 return PackAndInstallCRX(dir_path, pem_path, install_state,
793 Extension::NO_FLAGS);
796 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
797 InstallState install_state) {
798 return PackAndInstallCRX(dir_path, base::FilePath(), install_state,
799 Extension::NO_FLAGS);
802 // Attempts to install an extension. Use INSTALL_FAILED if the installation
803 // is expected to fail.
804 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
805 // non-empty, expects that the existing extension's title was
806 // |expected_old_name|.
807 const Extension* InstallCRX(const base::FilePath& path,
808 InstallState install_state,
810 const std::string& expected_old_name) {
811 StartCRXInstall(path, creation_flags);
812 return WaitForCrxInstall(path, install_state, expected_old_name);
815 // Attempts to install an extension. Use INSTALL_FAILED if the installation
816 // is expected to fail.
817 const Extension* InstallCRX(const base::FilePath& path,
818 InstallState install_state,
819 int creation_flags) {
820 return InstallCRX(path, install_state, creation_flags, "");
823 // Attempts to install an extension. Use INSTALL_FAILED if the installation
824 // is expected to fail.
825 const Extension* InstallCRX(const base::FilePath& path,
826 InstallState install_state) {
827 return InstallCRX(path, install_state, Extension::NO_FLAGS);
830 const Extension* InstallCRXFromWebStore(const base::FilePath& path,
831 InstallState install_state) {
832 StartCRXInstall(path, Extension::FROM_WEBSTORE);
833 return WaitForCrxInstall(path, install_state);
836 const Extension* InstallCRXWithLocation(const base::FilePath& crx_path,
837 Manifest::Location install_location,
838 InstallState install_state) {
839 EXPECT_TRUE(base::PathExists(crx_path))
840 << "Path does not exist: "<< crx_path.value().c_str();
841 // no client (silent install)
842 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
843 installer->set_install_source(install_location);
844 installer->InstallCrx(crx_path);
846 return WaitForCrxInstall(crx_path, install_state);
849 // Wait for a CrxInstaller to finish. Used by InstallCRX. Set the
850 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
851 // Returns an Extension pointer if the install succeeded, NULL otherwise.
852 const Extension* WaitForCrxInstall(const base::FilePath& path,
853 InstallState install_state) {
854 return WaitForCrxInstall(path, install_state, "");
857 // Wait for a CrxInstaller to finish. Used by InstallCRX. Set the
858 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
859 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
860 // non-empty, expects that the existing extension's title was
861 // |expected_old_name|.
862 // Returns an Extension pointer if the install succeeded, NULL otherwise.
863 const Extension* WaitForCrxInstall(const base::FilePath& path,
864 InstallState install_state,
865 const std::string& expected_old_name) {
866 content::WindowedNotificationObserver(
867 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
868 content::NotificationService::AllSources()).Wait();
870 std::vector<string16> errors = GetErrors();
871 const Extension* extension = NULL;
872 if (install_state != INSTALL_FAILED) {
873 if (install_state == INSTALL_NEW)
874 ++expected_extensions_count_;
876 EXPECT_TRUE(installed_) << path.value();
877 // If and only if INSTALL_UPDATED, it should have the is_update flag.
878 EXPECT_EQ(install_state == INSTALL_UPDATED, was_update_)
880 // If INSTALL_UPDATED, old_name_ should match the given string.
881 if (install_state == INSTALL_UPDATED && !expected_old_name.empty())
882 EXPECT_EQ(expected_old_name, old_name_);
883 EXPECT_EQ(0u, errors.size()) << path.value();
885 if (install_state == INSTALL_WITHOUT_LOAD) {
886 EXPECT_EQ(0u, loaded_.size()) << path.value();
888 EXPECT_EQ(1u, loaded_.size()) << path.value();
889 size_t actual_extension_count = service_->extensions()->size() +
890 service_->disabled_extensions()->size();
891 EXPECT_EQ(expected_extensions_count_, actual_extension_count) <<
893 extension = loaded_[0].get();
894 EXPECT_TRUE(service_->GetExtensionById(extension->id(), false))
898 for (std::vector<string16>::iterator err = errors.begin();
899 err != errors.end(); ++err) {
903 EXPECT_FALSE(installed_) << path.value();
904 EXPECT_EQ(0u, loaded_.size()) << path.value();
905 EXPECT_EQ(1u, errors.size()) << path.value();
912 ExtensionErrorReporter::GetInstance()->ClearErrors();
924 void BlackListWebGL() {
925 static const std::string json_blacklist =
927 " \"name\": \"gpu blacklist\",\n"
928 " \"version\": \"1.0\",\n"
932 " \"features\": [\"webgl\"]\n"
936 gpu::GPUInfo gpu_info;
937 content::GpuDataManager::GetInstance()->InitializeForTesting(
938 json_blacklist, gpu_info);
941 void UpdateExtension(const std::string& id, const base::FilePath& in_path,
942 UpdateState expected_state) {
943 ASSERT_TRUE(base::PathExists(in_path));
945 // We need to copy this to a temporary location because Update() will delete
947 base::FilePath path = temp_dir_.path();
948 path = path.Append(in_path.BaseName());
949 ASSERT_TRUE(base::CopyFile(in_path, path));
951 int previous_enabled_extension_count =
952 service_->extensions()->size();
953 int previous_installed_extension_count =
954 previous_enabled_extension_count +
955 service_->disabled_extensions()->size();
957 extensions::CrxInstaller* installer = NULL;
958 service_->UpdateExtension(id, path, GURL(), &installer);
961 content::WindowedNotificationObserver(
962 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
963 content::Source<extensions::CrxInstaller>(installer)).Wait();
965 base::RunLoop().RunUntilIdle();
968 std::vector<string16> errors = GetErrors();
969 int error_count = errors.size();
970 int enabled_extension_count =
971 service_->extensions()->size();
972 int installed_extension_count =
973 enabled_extension_count + service_->disabled_extensions()->size();
975 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
976 EXPECT_EQ(expected_error_count, error_count) << path.value();
978 if (expected_state <= FAILED) {
979 EXPECT_EQ(previous_enabled_extension_count,
980 enabled_extension_count);
981 EXPECT_EQ(previous_installed_extension_count,
982 installed_extension_count);
984 int expected_installed_extension_count =
985 (expected_state >= INSTALLED) ? 1 : 0;
986 int expected_enabled_extension_count =
987 (expected_state >= ENABLED) ? 1 : 0;
988 EXPECT_EQ(expected_installed_extension_count,
989 installed_extension_count);
990 EXPECT_EQ(expected_enabled_extension_count,
991 enabled_extension_count);
994 // Update() should the temporary input file.
995 EXPECT_FALSE(base::PathExists(path));
998 void TerminateExtension(const std::string& id) {
999 const Extension* extension = service_->GetInstalledExtension(id);
1004 service_->TrackTerminatedExtensionForTest(extension);
1007 size_t GetPrefKeyCount() {
1008 const DictionaryValue* dict =
1009 profile_->GetPrefs()->GetDictionary("extensions.settings");
1014 return dict->size();
1017 void UninstallExtension(const std::string& id, bool use_helper) {
1018 // Verify that the extension is installed.
1019 base::FilePath extension_path = extensions_install_dir_.AppendASCII(id);
1020 EXPECT_TRUE(base::PathExists(extension_path));
1021 size_t pref_key_count = GetPrefKeyCount();
1022 EXPECT_GT(pref_key_count, 0u);
1023 ValidateIntegerPref(id, "state", Extension::ENABLED);
1027 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(service_, id));
1029 EXPECT_TRUE(service_->UninstallExtension(id, false, NULL));
1031 --expected_extensions_count_;
1033 // We should get an unload notification.
1034 EXPECT_FALSE(unloaded_id_.empty());
1035 EXPECT_EQ(id, unloaded_id_);
1037 // Verify uninstalled state.
1038 size_t new_pref_key_count = GetPrefKeyCount();
1039 if (new_pref_key_count == pref_key_count) {
1040 ValidateIntegerPref(id, "location",
1041 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1043 EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
1046 // The extension should not be in the service anymore.
1047 EXPECT_FALSE(service_->GetInstalledExtension(id));
1048 base::RunLoop().RunUntilIdle();
1050 // The directory should be gone.
1051 EXPECT_FALSE(base::PathExists(extension_path));
1054 void ValidatePrefKeyCount(size_t count) {
1055 EXPECT_EQ(count, GetPrefKeyCount());
1058 testing::AssertionResult ValidateBooleanPref(
1059 const std::string& extension_id,
1060 const std::string& pref_path,
1061 bool expected_val) {
1062 std::string msg = "while checking: ";
1063 msg += extension_id;
1067 msg += expected_val ? "true" : "false";
1069 PrefService* prefs = profile_->GetPrefs();
1070 const DictionaryValue* dict =
1071 prefs->GetDictionary("extensions.settings");
1073 return testing::AssertionFailure()
1074 << "extension.settings does not exist " << msg;
1077 const DictionaryValue* pref = NULL;
1078 if (!dict->GetDictionary(extension_id, &pref)) {
1079 return testing::AssertionFailure()
1080 << "extension pref does not exist " << msg;
1084 if (!pref->GetBoolean(pref_path, &val)) {
1085 return testing::AssertionFailure()
1086 << pref_path << " pref not found " << msg;
1089 return expected_val == val
1090 ? testing::AssertionSuccess()
1091 : testing::AssertionFailure() << "Value is incorrect " << msg;
1094 bool IsPrefExist(const std::string& extension_id,
1095 const std::string& pref_path) {
1096 const DictionaryValue* dict =
1097 profile_->GetPrefs()->GetDictionary("extensions.settings");
1098 if (dict == NULL) return false;
1099 const DictionaryValue* pref = NULL;
1100 if (!dict->GetDictionary(extension_id, &pref)) {
1107 if (!pref->GetBoolean(pref_path, &val)) {
1113 void ValidateIntegerPref(const std::string& extension_id,
1114 const std::string& pref_path,
1116 std::string msg = " while checking: ";
1117 msg += extension_id;
1121 msg += base::IntToString(expected_val);
1123 PrefService* prefs = profile_->GetPrefs();
1124 const DictionaryValue* dict =
1125 prefs->GetDictionary("extensions.settings");
1126 ASSERT_TRUE(dict != NULL) << msg;
1127 const DictionaryValue* pref = NULL;
1128 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1129 EXPECT_TRUE(pref != NULL) << msg;
1131 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
1132 EXPECT_EQ(expected_val, val) << msg;
1135 void ValidateStringPref(const std::string& extension_id,
1136 const std::string& pref_path,
1137 const std::string& expected_val) {
1138 std::string msg = " while checking: ";
1139 msg += extension_id;
1140 msg += ".manifest.";
1143 msg += expected_val;
1145 const DictionaryValue* dict =
1146 profile_->GetPrefs()->GetDictionary("extensions.settings");
1147 ASSERT_TRUE(dict != NULL) << msg;
1148 const DictionaryValue* pref = NULL;
1149 std::string manifest_path = extension_id + ".manifest";
1150 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
1151 EXPECT_TRUE(pref != NULL) << msg;
1153 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
1154 EXPECT_EQ(expected_val, val) << msg;
1157 void SetPref(const std::string& extension_id,
1158 const std::string& pref_path,
1160 const std::string& msg) {
1161 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1162 DictionaryValue* dict = update.Get();
1163 ASSERT_TRUE(dict != NULL) << msg;
1164 DictionaryValue* pref = NULL;
1165 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1166 EXPECT_TRUE(pref != NULL) << msg;
1167 pref->Set(pref_path, value);
1170 void SetPrefInteg(const std::string& extension_id,
1171 const std::string& pref_path,
1173 std::string msg = " while setting: ";
1174 msg += extension_id;
1178 msg += base::IntToString(value);
1180 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1183 void SetPrefBool(const std::string& extension_id,
1184 const std::string& pref_path,
1186 std::string msg = " while setting: ";
1187 msg += extension_id + " " + pref_path;
1189 msg += (value ? "true" : "false");
1191 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1194 void ClearPref(const std::string& extension_id,
1195 const std::string& pref_path) {
1196 std::string msg = " while clearing: ";
1197 msg += extension_id + " " + pref_path;
1199 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1200 DictionaryValue* dict = update.Get();
1201 ASSERT_TRUE(dict != NULL) << msg;
1202 DictionaryValue* pref = NULL;
1203 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1204 EXPECT_TRUE(pref != NULL) << msg;
1205 pref->Remove(pref_path, NULL);
1208 void SetPrefStringSet(const std::string& extension_id,
1209 const std::string& pref_path,
1210 const std::set<std::string>& value) {
1211 std::string msg = " while setting: ";
1212 msg += extension_id + " " + pref_path;
1214 ListValue* list_value = new ListValue();
1215 for (std::set<std::string>::const_iterator iter = value.begin();
1216 iter != value.end(); ++iter)
1217 list_value->Append(new base::StringValue(*iter));
1219 SetPref(extension_id, pref_path, list_value, msg);
1222 void InitPluginService() {
1223 #if defined(ENABLE_PLUGINS)
1224 PluginService::GetInstance()->Init();
1229 extensions::ExtensionList loaded_;
1230 std::string unloaded_id_;
1231 const Extension* installed_;
1233 std::string old_name_;
1234 FeatureSwitch::ScopedOverride override_external_install_prompt_;
1237 content::NotificationRegistrar registrar_;
1240 // Receives notifications from a PackExtensionJob, indicating either that
1241 // packing succeeded or that there was some error.
1242 class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
1244 PackExtensionTestClient(const base::FilePath& expected_crx_path,
1245 const base::FilePath& expected_private_key_path);
1246 virtual void OnPackSuccess(const base::FilePath& crx_path,
1247 const base::FilePath& private_key_path) OVERRIDE;
1248 virtual void OnPackFailure(const std::string& error_message,
1249 ExtensionCreator::ErrorType type) OVERRIDE;
1252 const base::FilePath expected_crx_path_;
1253 const base::FilePath expected_private_key_path_;
1254 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
1257 PackExtensionTestClient::PackExtensionTestClient(
1258 const base::FilePath& expected_crx_path,
1259 const base::FilePath& expected_private_key_path)
1260 : expected_crx_path_(expected_crx_path),
1261 expected_private_key_path_(expected_private_key_path) {}
1263 // If packing succeeded, we make sure that the package names match our
1265 void PackExtensionTestClient::OnPackSuccess(
1266 const base::FilePath& crx_path,
1267 const base::FilePath& private_key_path) {
1268 // We got the notification and processed it; we don't expect any further tasks
1269 // to be posted to the current thread, so we should stop blocking and continue
1270 // on with the rest of the test.
1271 // This call to |Quit()| matches the call to |Run()| in the
1272 // |PackPunctuatedExtension| test.
1273 base::MessageLoop::current()->Quit();
1274 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
1275 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
1276 ASSERT_TRUE(base::PathExists(private_key_path));
1279 // The tests are designed so that we never expect to see a packing error.
1280 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1281 ExtensionCreator::ErrorType type) {
1282 if (type == ExtensionCreator::kCRXExists)
1283 FAIL() << "Packing should not fail.";
1285 FAIL() << "Existing CRX should have been overwritten.";
1288 // Test loading good extensions from the profile directory.
1289 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1290 InitPluginService();
1291 InitializeGoodInstalledExtensionService();
1294 uint32 expected_num_extensions = 3u;
1295 ASSERT_EQ(expected_num_extensions, loaded_.size());
1297 EXPECT_EQ(std::string(good0), loaded_[0]->id());
1298 EXPECT_EQ(std::string("My extension 1"),
1299 loaded_[0]->name());
1300 EXPECT_EQ(std::string("The first extension that I made."),
1301 loaded_[0]->description());
1302 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
1303 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false));
1304 EXPECT_EQ(expected_num_extensions, service_->extensions()->size());
1306 ValidatePrefKeyCount(3);
1307 ValidateIntegerPref(good0, "state", Extension::ENABLED);
1308 ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
1309 ValidateIntegerPref(good1, "state", Extension::ENABLED);
1310 ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
1311 ValidateIntegerPref(good2, "state", Extension::ENABLED);
1312 ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
1314 URLPatternSet expected_patterns;
1315 AddPattern(&expected_patterns, "file:///*");
1316 AddPattern(&expected_patterns, "http://*.google.com/*");
1317 AddPattern(&expected_patterns, "https://*.google.com/*");
1318 const Extension* extension = loaded_[0].get();
1319 const extensions::UserScriptList& scripts =
1320 extensions::ContentScriptsInfo::GetContentScripts(extension);
1321 ASSERT_EQ(2u, scripts.size());
1322 EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
1323 EXPECT_EQ(2u, scripts[0].js_scripts().size());
1324 ExtensionResource resource00(extension->id(),
1325 scripts[0].js_scripts()[0].extension_root(),
1326 scripts[0].js_scripts()[0].relative_path());
1327 base::FilePath expected_path =
1328 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
1329 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
1330 ExtensionResource resource01(extension->id(),
1331 scripts[0].js_scripts()[1].extension_root(),
1332 scripts[0].js_scripts()[1].relative_path());
1334 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
1335 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
1336 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension));
1337 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
1338 EXPECT_EQ("http://*.news.com/*",
1339 scripts[1].url_patterns().begin()->GetAsString());
1340 ExtensionResource resource10(extension->id(),
1341 scripts[1].js_scripts()[0].extension_root(),
1342 scripts[1].js_scripts()[0].relative_path());
1344 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
1345 expected_path = base::MakeAbsoluteFilePath(expected_path);
1346 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
1348 expected_patterns.ClearPatterns();
1349 AddPattern(&expected_patterns, "http://*.google.com/*");
1350 AddPattern(&expected_patterns, "https://*.google.com/*");
1351 EXPECT_EQ(expected_patterns,
1352 extension->GetActivePermissions()->explicit_hosts());
1354 EXPECT_EQ(std::string(good1), loaded_[1]->id());
1355 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
1356 EXPECT_EQ(std::string(), loaded_[1]->description());
1357 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
1358 extensions::BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
1360 extensions::ContentScriptsInfo::GetContentScripts(loaded_[1].get())
1363 // We don't parse the plugins section on Chrome OS.
1364 #if defined(OS_CHROMEOS)
1365 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1367 ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1368 const std::vector<extensions::PluginInfo>* plugins =
1369 extensions::PluginInfo::GetPlugins(loaded_[1].get());
1370 ASSERT_TRUE(plugins);
1371 ASSERT_EQ(2u, plugins->size());
1372 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
1373 plugins->at(0).path.value());
1374 EXPECT_TRUE(plugins->at(0).is_public);
1375 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1376 plugins->at(1).path.value());
1377 EXPECT_FALSE(plugins->at(1).is_public);
1380 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
1382 int index = expected_num_extensions - 1;
1383 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1384 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1385 EXPECT_EQ(std::string(), loaded_[index]->description());
1387 extensions::ContentScriptsInfo::GetContentScripts(
1388 loaded_[index].get()).size());
1389 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
1392 // Test loading bad extensions from the profile directory.
1393 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
1394 // Initialize the test dir with a bad Preferences/extensions.
1395 base::FilePath source_install_dir = data_dir_
1397 .AppendASCII("Extensions");
1398 base::FilePath pref_path = source_install_dir
1400 .AppendASCII("Preferences");
1402 InitializeInstalledExtensionService(pref_path, source_install_dir);
1406 ASSERT_EQ(4u, GetErrors().size());
1407 ASSERT_EQ(0u, loaded_.size());
1409 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[0]),
1410 std::string("Could not load extension from '*'. ") +
1411 extensions::manifest_errors::kManifestUnreadable)) <<
1412 UTF16ToUTF8(GetErrors()[0]);
1414 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[1]),
1415 std::string("Could not load extension from '*'. ") +
1416 extensions::manifest_errors::kManifestUnreadable)) <<
1417 UTF16ToUTF8(GetErrors()[1]);
1419 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[2]),
1420 std::string("Could not load extension from '*'. ") +
1421 extensions::manifest_errors::kMissingFile)) <<
1422 UTF16ToUTF8(GetErrors()[2]);
1424 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]),
1425 std::string("Could not load extension from '*'. ") +
1426 extensions::manifest_errors::kManifestUnreadable)) <<
1427 UTF16ToUTF8(GetErrors()[3]);
1430 // Test that partially deleted extensions are cleaned up during startup
1431 // Test loading bad extensions from the profile directory.
1432 TEST_F(ExtensionServiceTest, CleanupOnStartup) {
1433 InitPluginService();
1434 InitializeGoodInstalledExtensionService();
1436 // Simulate that one of them got partially deleted by clearing its pref.
1438 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1439 DictionaryValue* dict = update.Get();
1440 ASSERT_TRUE(dict != NULL);
1441 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
1445 // A delayed task to call GarbageCollectExtensions is posted by
1446 // ExtensionService::Init. As the test won't wait for the delayed task to
1447 // be called, call it manually instead.
1448 service_->GarbageCollectExtensions();
1449 // Wait for GarbageCollectExtensions task to complete.
1450 base::RunLoop().RunUntilIdle();
1452 base::FileEnumerator dirs(extensions_install_dir_, false,
1453 base::FileEnumerator::DIRECTORIES);
1455 while (!dirs.Next().empty())
1458 // We should have only gotten two extensions now.
1459 EXPECT_EQ(2u, count);
1461 // And extension1 dir should now be toast.
1462 base::FilePath extension_dir = extensions_install_dir_
1463 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1464 ASSERT_FALSE(base::PathExists(extension_dir));
1467 // Test that GarbageCollectExtensions deletes the right versions of an
1469 TEST_F(ExtensionServiceTest, GarbageCollectWithPendingUpdates) {
1470 InitPluginService();
1472 base::FilePath source_install_dir = data_dir_
1473 .AppendASCII("pending_updates")
1474 .AppendASCII("Extensions");
1475 base::FilePath pref_path = source_install_dir
1477 .AppendASCII("Preferences");
1479 InitializeInstalledExtensionService(pref_path, source_install_dir);
1481 // This is the directory that is going to be deleted, so make sure it actually
1482 // is there before the garbage collection.
1483 ASSERT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1484 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1486 service_->GarbageCollectExtensions();
1487 // Wait for GarbageCollectExtensions task to complete.
1488 base::RunLoop().RunUntilIdle();
1490 // Verify that the pending update for the first extension didn't get
1492 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1493 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1494 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1495 "bjafgdebaacbbbecmhlhpofkepfkgcpa/2.0")));
1496 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1497 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1498 EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
1499 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1502 // Test that pending updates are properly handled on startup.
1503 TEST_F(ExtensionServiceTest, UpdateOnStartup) {
1504 InitPluginService();
1506 base::FilePath source_install_dir = data_dir_
1507 .AppendASCII("pending_updates")
1508 .AppendASCII("Extensions");
1509 base::FilePath pref_path = source_install_dir
1511 .AppendASCII("Preferences");
1513 InitializeInstalledExtensionService(pref_path, source_install_dir);
1515 // This is the directory that is going to be deleted, so make sure it actually
1516 // is there before the garbage collection.
1517 ASSERT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1518 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1521 // A delayed task to call GarbageCollectExtensions is posted by
1522 // ExtensionService::Init. As the test won't wait for the delayed task to
1523 // be called, call it manually instead.
1524 service_->GarbageCollectExtensions();
1525 // Wait for GarbageCollectExtensions task to complete.
1526 base::RunLoop().RunUntilIdle();
1528 // Verify that the pending update for the first extension got installed.
1529 EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
1530 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1531 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1532 "bjafgdebaacbbbecmhlhpofkepfkgcpa/2.0")));
1533 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1534 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1535 EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
1536 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1538 // Make sure update information got deleted.
1539 ExtensionPrefs* prefs = service_->extension_prefs();
1541 prefs->GetDelayedInstallInfo("bjafgdebaacbbbecmhlhpofkepfkgcpa"));
1544 // Test various cases for delayed install because of missing imports.
1545 TEST_F(ExtensionServiceTest, PendingImports) {
1546 InitPluginService();
1548 base::FilePath source_install_dir = data_dir_
1549 .AppendASCII("pending_updates_with_imports")
1550 .AppendASCII("Extensions");
1551 base::FilePath pref_path = source_install_dir
1553 .AppendASCII("Preferences");
1555 InitializeInstalledExtensionService(pref_path, source_install_dir);
1557 // Verify there are no pending extensions initially.
1558 EXPECT_FALSE(service_->pending_extension_manager()->HasPendingExtensions());
1561 // Wait for GarbageCollectExtensions task to complete.
1562 base::RunLoop().RunUntilIdle();
1564 // These extensions are used by the extensions we test below, they must be
1566 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1567 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1568 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1569 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1571 // Each of these extensions should have been rejected because of dependencies
1572 // that cannot be satisfied.
1573 ExtensionPrefs* prefs = service_->extension_prefs();
1575 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1577 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1579 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1581 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1583 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
1585 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
1587 // Make sure the import started for the extension with a dependency.
1589 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1590 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1591 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1593 EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
1594 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
1596 EXPECT_TRUE(service_->pending_extension_manager()->HasPendingExtensions());
1597 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
1598 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(pending_id));
1599 // Remove it because we are not testing the pending extension manager's
1600 // ability to download and install extensions.
1601 EXPECT_TRUE(service_->pending_extension_manager()->Remove(pending_id));
1604 // Test installing extensions. This test tries to install few extensions using
1605 // crx files. If you need to change those crx files, feel free to repackage
1606 // them, throw away the key used and change the id's above.
1607 TEST_F(ExtensionServiceTest, InstallExtension) {
1608 InitializeEmptyExtensionService();
1610 // Extensions not enabled.
1611 set_extensions_enabled(false);
1612 base::FilePath path = data_dir_.AppendASCII("good.crx");
1613 InstallCRX(path, INSTALL_FAILED);
1614 set_extensions_enabled(true);
1616 ValidatePrefKeyCount(0);
1618 // A simple extension that should install without error.
1619 path = data_dir_.AppendASCII("good.crx");
1620 InstallCRX(path, INSTALL_NEW);
1621 // TODO(erikkay): verify the contents of the installed extension.
1624 ValidatePrefKeyCount(++pref_count);
1625 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1626 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
1628 // An extension with page actions.
1629 path = data_dir_.AppendASCII("page_action.crx");
1630 InstallCRX(path, INSTALL_NEW);
1631 ValidatePrefKeyCount(++pref_count);
1632 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1633 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
1636 path = data_dir_.AppendASCII("bad_signature.crx");
1637 InstallCRX(path, INSTALL_FAILED);
1638 ValidatePrefKeyCount(pref_count);
1640 // 0-length extension file.
1641 path = data_dir_.AppendASCII("not_an_extension.crx");
1642 InstallCRX(path, INSTALL_FAILED);
1643 ValidatePrefKeyCount(pref_count);
1645 // Bad magic number.
1646 path = data_dir_.AppendASCII("bad_magic.crx");
1647 InstallCRX(path, INSTALL_FAILED);
1648 ValidatePrefKeyCount(pref_count);
1650 // Packed extensions may have folders or files that have underscores.
1651 // This will only cause a warning, rather than a fatal error.
1652 path = data_dir_.AppendASCII("bad_underscore.crx");
1653 InstallCRX(path, INSTALL_NEW);
1654 ValidatePrefKeyCount(++pref_count);
1656 // A test for an extension with a 2048-bit public key.
1657 path = data_dir_.AppendASCII("good2048.crx");
1658 InstallCRX(path, INSTALL_NEW);
1659 ValidatePrefKeyCount(++pref_count);
1660 ValidateIntegerPref(good2048, "state", Extension::ENABLED);
1661 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
1663 // TODO(erikkay): add more tests for many of the failure cases.
1664 // TODO(erikkay): add tests for upgrade cases.
1667 struct MockInstallObserver : public extensions::InstallObserver {
1668 MockInstallObserver() {
1671 virtual ~MockInstallObserver() {
1674 virtual void OnBeginExtensionInstall(
1675 const std::string& extension_id,
1676 const std::string& extension_name,
1677 const gfx::ImageSkia& installing_icon,
1679 bool is_platform_app) OVERRIDE {
1682 virtual void OnDownloadProgress(const std::string& extension_id,
1683 int percent_downloaded) OVERRIDE {
1686 virtual void OnExtensionInstalled(const Extension* extension) OVERRIDE {
1687 last_extension_installed = extension->id();
1690 virtual void OnInstallFailure(const std::string& extension_id) OVERRIDE {
1693 virtual void OnExtensionLoaded(const Extension* extension) OVERRIDE {
1696 virtual void OnExtensionUnloaded(const Extension* extension) OVERRIDE {
1699 virtual void OnExtensionUninstalled(const Extension* extension) OVERRIDE {
1700 last_extension_uninstalled = extension->id();
1703 virtual void OnAppsReordered() OVERRIDE {
1706 virtual void OnAppInstalledToAppList(
1707 const std::string& extension_id) OVERRIDE {
1710 virtual void OnShutdown() OVERRIDE {
1713 std::string last_extension_installed;
1714 std::string last_extension_uninstalled;
1717 // Test that correct notifications are sent to InstallTracker observers on
1718 // extension install and uninstall.
1719 TEST_F(ExtensionServiceTest, InstallObserverNotified) {
1720 InitializeEmptyExtensionService();
1722 extensions::InstallTracker* tracker(
1723 extensions::InstallTrackerFactory::GetForProfile(profile_.get()));
1724 MockInstallObserver observer;
1725 tracker->AddObserver(&observer);
1727 // A simple extension that should install without error.
1728 ASSERT_TRUE(observer.last_extension_installed.empty());
1729 base::FilePath path = data_dir_.AppendASCII("good.crx");
1730 InstallCRX(path, INSTALL_NEW);
1731 ASSERT_EQ(good_crx, observer.last_extension_installed);
1733 // Uninstall the extension.
1734 ASSERT_TRUE(observer.last_extension_uninstalled.empty());
1735 UninstallExtension(good_crx, false);
1736 ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
1738 tracker->RemoveObserver(&observer);
1741 // Tests that flags passed to OnExternalExtensionFileFound() make it to the
1742 // extension object.
1743 TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
1744 const char kPrefFromBookmark[] = "from_bookmark";
1746 InitializeEmptyExtensionService();
1748 base::FilePath path = data_dir_.AppendASCII("good.crx");
1749 set_extensions_enabled(true);
1751 // Register and install an external extension.
1752 Version version("1.0.0.0");
1753 if (service_->OnExternalExtensionFileFound(
1757 Manifest::EXTERNAL_PREF,
1758 Extension::FROM_BOOKMARK,
1759 false /* mark_acknowledged */)) {
1760 content::WindowedNotificationObserver(
1761 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1762 content::NotificationService::AllSources()).Wait();
1765 const Extension* extension = service_->GetExtensionById(good_crx, false);
1766 ASSERT_TRUE(extension);
1767 ASSERT_TRUE(extension->from_bookmark());
1768 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1770 // Upgrade to version 2.0, the flag should be preserved.
1771 path = data_dir_.AppendASCII("good2.crx");
1772 UpdateExtension(good_crx, path, ENABLED);
1773 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1774 extension = service_->GetExtensionById(good_crx, false);
1775 ASSERT_TRUE(extension);
1776 ASSERT_TRUE(extension->from_bookmark());
1779 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1780 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
1781 InitializeEmptyExtensionService();
1783 base::FilePath path = data_dir_.AppendASCII("good.crx");
1784 set_extensions_enabled(true);
1786 Version version("1.0.0.0");
1787 // Install an external extension.
1788 if (service_->OnExternalExtensionFileFound(good_crx, &version,
1789 path, Manifest::EXTERNAL_PREF,
1790 Extension::NO_FLAGS, false)) {
1791 content::WindowedNotificationObserver(
1792 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1793 content::NotificationService::AllSources()).Wait();
1796 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1798 // Uninstall it and check that its killbit gets set.
1799 UninstallExtension(good_crx, false);
1800 ValidateIntegerPref(good_crx, "location",
1801 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1803 // Try to re-install it externally. This should fail because of the killbit.
1804 service_->OnExternalExtensionFileFound(good_crx, &version,
1805 path, Manifest::EXTERNAL_PREF,
1806 Extension::NO_FLAGS, false);
1807 base::RunLoop().RunUntilIdle();
1808 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
1809 ValidateIntegerPref(good_crx, "location",
1810 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1812 version = Version("1.0.0.1");
1813 // Repeat the same thing with a newer version of the extension.
1814 path = data_dir_.AppendASCII("good2.crx");
1815 service_->OnExternalExtensionFileFound(good_crx, &version,
1816 path, Manifest::EXTERNAL_PREF,
1817 Extension::NO_FLAGS, false);
1818 base::RunLoop().RunUntilIdle();
1819 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
1820 ValidateIntegerPref(good_crx, "location",
1821 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1823 // Try adding the same extension from an external update URL.
1824 ASSERT_FALSE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
1826 GURL("http:://fake.update/url"),
1827 Manifest::EXTERNAL_PREF_DOWNLOAD,
1828 Extension::NO_FLAGS,
1831 ASSERT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
1834 // Test that uninstalling an external extension does not crash when
1835 // the extension could not be loaded.
1836 // This extension shown in preferences file requires an experimental permission.
1837 // It could not be loaded without such permission.
1838 TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
1839 base::FilePath source_install_dir = data_dir_
1840 .AppendASCII("good")
1841 .AppendASCII("Extensions");
1842 // The preference contains an external extension
1843 // that requires 'experimental' permission.
1844 base::FilePath pref_path = source_install_dir
1846 .AppendASCII("PreferencesExperimental");
1848 // Aforementioned extension will not be loaded if
1849 // there is no '--enable-experimental-extension-apis' command line flag.
1850 InitializeInstalledExtensionService(pref_path, source_install_dir);
1854 // Check and try to uninstall it.
1855 // If we don't check whether the extension is loaded before we uninstall it
1856 // in CheckExternalUninstall, a crash will happen here because we will get or
1857 // dereference a NULL pointer (extension) inside UninstallExtension.
1858 MockExtensionProvider provider(NULL, Manifest::EXTERNAL_REGISTRY);
1859 service_->OnExternalProviderReady(&provider);
1862 // Test that external extensions with incorrect IDs are not installed.
1863 TEST_F(ExtensionServiceTest, FailOnWrongId) {
1864 InitializeEmptyExtensionService();
1865 base::FilePath path = data_dir_.AppendASCII("good.crx");
1866 set_extensions_enabled(true);
1868 Version version("1.0.0.0");
1870 const std::string wrong_id = all_zero;
1871 const std::string correct_id = good_crx;
1872 ASSERT_NE(correct_id, wrong_id);
1874 // Install an external extension with an ID from the external
1875 // source that is not equal to the ID in the extension manifest.
1876 service_->OnExternalExtensionFileFound(
1877 wrong_id, &version, path, Manifest::EXTERNAL_PREF,
1878 Extension::NO_FLAGS, false);
1880 content::WindowedNotificationObserver(
1881 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1882 content::NotificationService::AllSources()).Wait();
1883 ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1885 // Try again with the right ID. Expect success.
1886 if (service_->OnExternalExtensionFileFound(
1887 correct_id, &version, path, Manifest::EXTERNAL_PREF,
1888 Extension::NO_FLAGS, false)) {
1889 content::WindowedNotificationObserver(
1890 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1891 content::NotificationService::AllSources()).Wait();
1893 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1896 // Test that external extensions with incorrect versions are not installed.
1897 TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1898 InitializeEmptyExtensionService();
1899 base::FilePath path = data_dir_.AppendASCII("good.crx");
1900 set_extensions_enabled(true);
1902 // Install an external extension with a version from the external
1903 // source that is not equal to the version in the extension manifest.
1904 Version wrong_version("1.2.3.4");
1905 service_->OnExternalExtensionFileFound(
1906 good_crx, &wrong_version, path, Manifest::EXTERNAL_PREF,
1907 Extension::NO_FLAGS, false);
1909 content::WindowedNotificationObserver(
1910 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1911 content::NotificationService::AllSources()).Wait();
1912 ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1914 // Try again with the right version. Expect success.
1915 service_->pending_extension_manager()->Remove(good_crx);
1916 Version correct_version("1.0.0.0");
1917 if (service_->OnExternalExtensionFileFound(
1918 good_crx, &correct_version, path, Manifest::EXTERNAL_PREF,
1919 Extension::NO_FLAGS, false)) {
1920 content::WindowedNotificationObserver(
1921 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1922 content::NotificationService::AllSources()).Wait();
1924 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1927 // Install a user script (they get converted automatically to an extension)
1928 TEST_F(ExtensionServiceTest, InstallUserScript) {
1929 // The details of script conversion are tested elsewhere, this just tests
1930 // integration with ExtensionService.
1931 InitializeEmptyExtensionService();
1933 base::FilePath path = data_dir_
1934 .AppendASCII("user_script_basic.user.js");
1936 ASSERT_TRUE(base::PathExists(path));
1937 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
1938 installer->set_allow_silent_install(true);
1939 installer->InstallUserScript(
1941 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1943 base::RunLoop().RunUntilIdle();
1944 std::vector<string16> errors = GetErrors();
1945 EXPECT_TRUE(installed_) << "Nothing was installed.";
1946 EXPECT_FALSE(was_update_) << path.value();
1947 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1948 EXPECT_EQ(0u, errors.size()) << "There were errors: "
1949 << JoinString(errors, ',');
1950 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
1954 was_update_ = false;
1956 ExtensionErrorReporter::GetInstance()->ClearErrors();
1959 // Extensions don't install during shutdown.
1960 TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
1961 InitializeEmptyExtensionService();
1963 // Simulate shutdown.
1964 service_->set_browser_terminating_for_test(true);
1966 base::FilePath path = data_dir_.AppendASCII("good.crx");
1967 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
1968 installer->set_allow_silent_install(true);
1969 installer->InstallCrx(path);
1970 base::RunLoop().RunUntilIdle();
1972 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
1973 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
1976 // This tests that the granted permissions preferences are correctly set when
1977 // installing an extension.
1978 TEST_F(ExtensionServiceTest, GrantedPermissions) {
1979 InitializeEmptyExtensionService();
1980 base::FilePath path = data_dir_
1981 .AppendASCII("permissions");
1983 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1984 path = path.AppendASCII("unknown");
1986 ASSERT_TRUE(base::PathExists(pem_path));
1987 ASSERT_TRUE(base::PathExists(path));
1989 ExtensionPrefs* prefs = service_->extension_prefs();
1991 APIPermissionSet expected_api_perms;
1992 URLPatternSet expected_host_perms;
1994 // Make sure there aren't any granted permissions before the
1995 // extension is installed.
1996 scoped_refptr<PermissionSet> known_perms(
1997 prefs->GetGrantedPermissions(permissions_crx));
1998 EXPECT_FALSE(known_perms.get());
2000 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
2002 EXPECT_EQ(0u, GetErrors().size());
2003 ASSERT_EQ(1u, service_->extensions()->size());
2004 EXPECT_EQ(permissions_crx, extension->id());
2006 // Verify that the valid API permissions have been recognized.
2007 expected_api_perms.insert(APIPermission::kTab);
2009 AddPattern(&expected_host_perms, "http://*.google.com/*");
2010 AddPattern(&expected_host_perms, "https://*.google.com/*");
2011 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
2012 AddPattern(&expected_host_perms, "http://www.example.com/*");
2014 known_perms = prefs->GetGrantedPermissions(extension->id());
2015 EXPECT_TRUE(known_perms.get());
2016 EXPECT_FALSE(known_perms->IsEmpty());
2017 EXPECT_EQ(expected_api_perms, known_perms->apis());
2018 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
2019 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
2023 #if !defined(OS_CHROMEOS)
2024 // This tests that the granted permissions preferences are correctly set for
2026 TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
2027 InitializeEmptyExtensionService();
2028 base::FilePath path = data_dir_
2029 .AppendASCII("permissions");
2031 base::FilePath pem_path = path.AppendASCII("unknown.pem");
2032 path = path.AppendASCII("unknown");
2034 ASSERT_TRUE(base::PathExists(pem_path));
2035 ASSERT_TRUE(base::PathExists(path));
2037 ExtensionPrefs* prefs = service_->extension_prefs();
2039 APIPermissionSet expected_api_perms;
2040 URLPatternSet expected_host_perms;
2042 // Make sure there aren't any granted permissions before the
2043 // extension is installed.
2044 scoped_refptr<PermissionSet> known_perms(
2045 prefs->GetGrantedPermissions(permissions_crx));
2046 EXPECT_FALSE(known_perms.get());
2048 const Extension* extension = PackAndInstallCRX(
2049 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
2051 EXPECT_EQ(0u, GetErrors().size());
2052 ASSERT_EQ(1u, service_->extensions()->size());
2053 EXPECT_EQ(permissions_crx, extension->id());
2055 // Verify that the valid API permissions have been recognized.
2056 expected_api_perms.insert(APIPermission::kTab);
2058 known_perms = prefs->GetGrantedPermissions(extension->id());
2059 EXPECT_TRUE(known_perms.get());
2060 EXPECT_FALSE(known_perms->IsEmpty());
2061 EXPECT_EQ(expected_api_perms, known_perms->apis());
2062 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
2066 #if !defined(OS_CHROMEOS)
2067 // Tests that the granted permissions full_access bit gets set correctly when
2068 // an extension contains an NPAPI plugin. Don't run this test on Chrome OS
2069 // since they don't support plugins.
2070 TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
2071 InitPluginService();
2073 InitializeEmptyExtensionService();
2075 ASSERT_TRUE(base::PathExists(good1_path()));
2076 const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW);
2077 EXPECT_EQ(0u, GetErrors().size());
2078 EXPECT_EQ(1u, service_->extensions()->size());
2079 ExtensionPrefs* prefs = service_->extension_prefs();
2081 scoped_refptr<PermissionSet> permissions(
2082 prefs->GetGrantedPermissions(extension->id()));
2083 EXPECT_FALSE(permissions->IsEmpty());
2084 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
2085 EXPECT_FALSE(permissions->apis().empty());
2086 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
2088 // Full access implies full host access too...
2089 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
2093 // Tests that the extension is disabled when permissions are missing from
2094 // the extension's granted permissions preferences. (This simulates updating
2095 // the browser to a version which recognizes more permissions).
2096 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
2097 InitializeEmptyExtensionService();
2099 base::FilePath path = data_dir_
2100 .AppendASCII("permissions")
2101 .AppendASCII("unknown");
2103 ASSERT_TRUE(base::PathExists(path));
2105 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
2107 EXPECT_EQ(0u, GetErrors().size());
2108 EXPECT_EQ(1u, service_->extensions()->size());
2109 std::string extension_id = extension->id();
2111 ExtensionPrefs* prefs = service_->extension_prefs();
2113 APIPermissionSet expected_api_permissions;
2114 URLPatternSet expected_host_permissions;
2116 expected_api_permissions.insert(APIPermission::kTab);
2117 AddPattern(&expected_host_permissions, "http://*.google.com/*");
2118 AddPattern(&expected_host_permissions, "https://*.google.com/*");
2119 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
2120 AddPattern(&expected_host_permissions, "http://www.example.com/*");
2122 std::set<std::string> host_permissions;
2124 // Test that the extension is disabled when an API permission is missing from
2125 // the extension's granted api permissions preference. (This simulates
2126 // updating the browser to a version which recognizes a new API permission).
2127 SetPref(extension_id, "granted_permissions.api",
2128 new ListValue(), "granted_permissions.api");
2129 service_->ReloadExtensions();
2131 EXPECT_EQ(1u, service_->disabled_extensions()->size());
2132 extension = service_->disabled_extensions()->begin()->get();
2134 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2135 ASSERT_FALSE(service_->IsExtensionEnabled(extension_id));
2136 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2138 // Now grant and re-enable the extension, making sure the prefs are updated.
2139 service_->GrantPermissionsAndEnableExtension(extension);
2141 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
2142 ASSERT_TRUE(service_->IsExtensionEnabled(extension_id));
2143 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2145 scoped_refptr<PermissionSet> current_perms(
2146 prefs->GetGrantedPermissions(extension_id));
2147 ASSERT_TRUE(current_perms.get());
2148 ASSERT_FALSE(current_perms->IsEmpty());
2149 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2150 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2151 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2153 // Tests that the extension is disabled when a host permission is missing from
2154 // the extension's granted host permissions preference. (This simulates
2155 // updating the browser to a version which recognizes additional host
2157 host_permissions.clear();
2158 current_perms = NULL;
2160 host_permissions.insert("http://*.google.com/*");
2161 host_permissions.insert("https://*.google.com/*");
2162 host_permissions.insert("http://*.google.com.hk/*");
2164 ListValue* api_permissions = new ListValue();
2165 api_permissions->Append(
2166 new base::StringValue("tabs"));
2167 SetPref(extension_id, "granted_permissions.api",
2168 api_permissions, "granted_permissions.api");
2170 extension_id, "granted_permissions.scriptable_host", host_permissions);
2172 service_->ReloadExtensions();
2174 EXPECT_EQ(1u, service_->disabled_extensions()->size());
2175 extension = service_->disabled_extensions()->begin()->get();
2177 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2178 ASSERT_FALSE(service_->IsExtensionEnabled(extension_id));
2179 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2181 // Now grant and re-enable the extension, making sure the prefs are updated.
2182 service_->GrantPermissionsAndEnableExtension(extension);
2184 ASSERT_TRUE(service_->IsExtensionEnabled(extension_id));
2185 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2187 current_perms = prefs->GetGrantedPermissions(extension_id);
2188 ASSERT_TRUE(current_perms.get());
2189 ASSERT_FALSE(current_perms->IsEmpty());
2190 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2191 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2192 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2195 // Test Packaging and installing an extension.
2196 TEST_F(ExtensionServiceTest, PackExtension) {
2197 InitializeEmptyExtensionService();
2198 base::FilePath input_directory = data_dir_
2199 .AppendASCII("good")
2200 .AppendASCII("Extensions")
2201 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2202 .AppendASCII("1.0.0.0");
2204 base::ScopedTempDir temp_dir;
2205 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2206 base::FilePath output_directory = temp_dir.path();
2208 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2209 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2211 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2212 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2213 privkey_path, ExtensionCreator::kNoRunFlags));
2214 ASSERT_TRUE(base::PathExists(crx_path));
2215 ASSERT_TRUE(base::PathExists(privkey_path));
2217 // Repeat the run with the pem file gone, and no special flags
2218 // Should refuse to overwrite the existing crx.
2219 base::DeleteFile(privkey_path, false);
2220 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2221 privkey_path, ExtensionCreator::kNoRunFlags));
2223 // OK, now try it with a flag to overwrite existing crx. Should work.
2224 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2225 privkey_path, ExtensionCreator::kOverwriteCRX));
2227 // Repeat the run allowing existing crx, but the existing pem is still
2228 // an error. Should fail.
2229 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2230 privkey_path, ExtensionCreator::kOverwriteCRX));
2232 ASSERT_TRUE(base::PathExists(privkey_path));
2233 InstallCRX(crx_path, INSTALL_NEW);
2235 // Try packing with invalid paths.
2236 creator.reset(new ExtensionCreator());
2238 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
2239 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2241 // Try packing an empty directory. Should fail because an empty directory is
2242 // not a valid extension.
2243 base::ScopedTempDir temp_dir2;
2244 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
2245 creator.reset(new ExtensionCreator());
2246 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2247 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2249 // Try packing with an invalid manifest.
2250 std::string invalid_manifest_content = "I am not a manifest.";
2251 ASSERT_TRUE(file_util::WriteFile(
2252 temp_dir2.path().Append(extensions::kManifestFilename),
2253 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
2254 creator.reset(new ExtensionCreator());
2255 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2256 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2258 // Try packing with a private key that is a valid key, but invalid for the
2260 base::FilePath bad_private_key_dir = data_dir_.AppendASCII("bad_private_key");
2261 crx_path = output_directory.AppendASCII("bad_private_key.crx");
2262 privkey_path = data_dir_.AppendASCII("bad_private_key.pem");
2263 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
2264 privkey_path, ExtensionCreator::kOverwriteCRX));
2267 // Test Packaging and installing an extension whose name contains punctuation.
2268 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
2269 InitializeEmptyExtensionService();
2270 base::FilePath input_directory = data_dir_
2271 .AppendASCII("good")
2272 .AppendASCII("Extensions")
2274 .AppendASCII("1.0.0.0");
2276 base::ScopedTempDir temp_dir;
2277 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2279 // Extension names containing punctuation, and the expected names for the
2280 // packed extensions.
2281 const base::FilePath punctuated_names[] = {
2282 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2283 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2284 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
2285 NormalizePathSeparators(),
2287 const base::FilePath expected_crx_names[] = {
2288 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2290 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2291 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
2293 const base::FilePath expected_private_key_names[] = {
2294 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2296 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2297 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
2300 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
2301 SCOPED_TRACE(punctuated_names[i].value().c_str());
2302 base::FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
2304 // Copy the extension into the output directory, as PackExtensionJob doesn't
2305 // let us choose where to output the packed extension.
2306 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
2308 base::FilePath expected_crx_path =
2309 temp_dir.path().Append(expected_crx_names[i]);
2310 base::FilePath expected_private_key_path =
2311 temp_dir.path().Append(expected_private_key_names[i]);
2312 PackExtensionTestClient pack_client(expected_crx_path,
2313 expected_private_key_path);
2314 scoped_refptr<extensions::PackExtensionJob> packer(
2315 new extensions::PackExtensionJob(&pack_client, output_dir,
2317 ExtensionCreator::kOverwriteCRX));
2320 // The packer will post a notification task to the current thread's message
2321 // loop when it is finished. We manually run the loop here so that we
2322 // block and catch the notification; otherwise, the process would exit.
2323 // This call to |Run()| is matched by a call to |Quit()| in the
2324 // |PackExtensionTestClient|'s notification handling code.
2325 base::MessageLoop::current()->Run();
2327 if (HasFatalFailure())
2330 InstallCRX(expected_crx_path, INSTALL_NEW);
2334 TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
2335 InitializeEmptyExtensionService();
2337 base::ScopedTempDir extension_temp_dir;
2338 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
2339 base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
2340 ASSERT_TRUE(base::CopyDirectory(
2342 .AppendASCII("good")
2343 .AppendASCII("Extensions")
2344 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2345 .AppendASCII("1.0.0.0"),
2347 /*recursive=*/true));
2349 base::ScopedTempDir output_temp_dir;
2350 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
2351 base::FilePath output_directory = output_temp_dir.path();
2353 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2354 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2356 // Pack the extension once to get a private key.
2357 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2358 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2359 privkey_path, ExtensionCreator::kNoRunFlags))
2360 << creator->error_message();
2361 ASSERT_TRUE(base::PathExists(crx_path));
2362 ASSERT_TRUE(base::PathExists(privkey_path));
2364 base::DeleteFile(crx_path, false);
2365 // Move the pem file into the extension.
2366 base::Move(privkey_path,
2367 input_directory.AppendASCII("privkey.pem"));
2369 // This pack should fail because of the contained private key.
2370 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2371 privkey_path, ExtensionCreator::kNoRunFlags));
2372 EXPECT_THAT(creator->error_message(),
2373 testing::ContainsRegex(
2374 "extension includes the key file.*privkey.pem"));
2377 // Test Packaging and installing an extension using an openssl generated key.
2378 // The openssl is generated with the following:
2379 // > openssl genrsa -out privkey.pem 1024
2380 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
2381 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
2382 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
2383 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
2384 InitializeEmptyExtensionService();
2385 base::FilePath input_directory = data_dir_
2386 .AppendASCII("good")
2387 .AppendASCII("Extensions")
2388 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2389 .AppendASCII("1.0.0.0");
2390 base::FilePath privkey_path(data_dir_.AppendASCII(
2391 "openssl_privkey_asn1.pem"));
2392 ASSERT_TRUE(base::PathExists(privkey_path));
2394 base::ScopedTempDir temp_dir;
2395 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2396 base::FilePath output_directory = temp_dir.path();
2398 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2400 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2401 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
2402 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2404 InstallCRX(crx_path, INSTALL_NEW);
2407 TEST_F(ExtensionServiceTest, InstallTheme) {
2408 InitializeEmptyExtensionService();
2412 base::FilePath path = data_dir_.AppendASCII("theme.crx");
2413 InstallCRX(path, INSTALL_NEW);
2415 ValidatePrefKeyCount(++pref_count);
2416 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2417 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2419 // A theme when extensions are disabled. Themes can be installed, even when
2420 // extensions are disabled.
2421 set_extensions_enabled(false);
2422 path = data_dir_.AppendASCII("theme2.crx");
2423 InstallCRX(path, INSTALL_NEW);
2424 ValidatePrefKeyCount(++pref_count);
2425 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
2426 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
2428 // A theme with extension elements. Themes cannot have extension elements,
2429 // so any such elements (like content scripts) should be ignored.
2430 set_extensions_enabled(true);
2432 path = data_dir_.AppendASCII("theme_with_extension.crx");
2433 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2434 ValidatePrefKeyCount(++pref_count);
2435 ASSERT_TRUE(extension);
2436 EXPECT_TRUE(extension->is_theme());
2439 extensions::ContentScriptsInfo::GetContentScripts(extension).size());
2442 // A theme with image resources missing (misspelt path).
2443 path = data_dir_.AppendASCII("theme_missing_image.crx");
2444 InstallCRX(path, INSTALL_FAILED);
2445 ValidatePrefKeyCount(pref_count);
2448 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
2450 InitializeEmptyExtensionService();
2453 base::FilePath extension_path = data_dir_
2454 .AppendASCII("theme_i18n");
2456 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2457 base::RunLoop().RunUntilIdle();
2458 EXPECT_EQ(0u, GetErrors().size());
2459 ASSERT_EQ(1u, loaded_.size());
2460 EXPECT_EQ(1u, service_->extensions()->size());
2461 const Extension* theme = service_->extensions()->begin()->get();
2462 EXPECT_EQ("name", theme->name());
2463 EXPECT_EQ("description", theme->description());
2465 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a
2466 // temporary directory, but it automatically installs to the extension's
2467 // directory, and we don't want to copy the whole extension for a unittest.
2468 base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
2469 ASSERT_TRUE(base::PathExists(theme_file));
2470 ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive.
2473 // Tests that we can change the ID of an unpacked extension by adding a key
2475 TEST_F(ExtensionServiceTest, UnpackedExtensionCanChangeID) {
2476 InitializeEmptyExtensionService();
2478 base::ScopedTempDir temp;
2479 ASSERT_TRUE(temp.CreateUniqueTempDir());
2481 base::FilePath extension_path = temp.path();
2482 base::FilePath manifest_path =
2483 extension_path.Append(extensions::kManifestFilename);
2484 base::FilePath manifest_no_key = data_dir_.
2485 AppendASCII("unpacked").
2486 AppendASCII("manifest_no_key.json");
2488 base::FilePath manifest_with_key = data_dir_.
2489 AppendASCII("unpacked").
2490 AppendASCII("manifest_with_key.json");
2492 ASSERT_TRUE(base::PathExists(manifest_no_key));
2493 ASSERT_TRUE(base::PathExists(manifest_with_key));
2495 // Load the unpacked extension with no key.
2496 base::CopyFile(manifest_no_key, manifest_path);
2497 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2499 base::RunLoop().RunUntilIdle();
2500 EXPECT_EQ(0u, GetErrors().size());
2501 ASSERT_EQ(1u, loaded_.size());
2502 EXPECT_EQ(1u, service_->extensions()->size());
2504 // Add the key to the manifest.
2505 base::CopyFile(manifest_with_key, manifest_path);
2508 // Reload the extensions.
2509 service_->ReloadExtensions();
2510 const Extension* extension = service_->GetExtensionById(unpacked, false);
2511 EXPECT_EQ(unpacked, extension->id());
2512 ASSERT_EQ(1u, loaded_.size());
2514 // TODO(jstritar): Right now this just makes sure we don't crash and burn, but
2515 // we should also test that preferences are preserved.
2518 #if defined(OS_POSIX)
2519 TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
2520 base::FilePath source_data_dir = data_dir_.
2521 AppendASCII("unpacked").
2522 AppendASCII("symlinks_allowed");
2524 // Paths to test data files.
2525 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2526 ASSERT_TRUE(base::PathExists(source_manifest));
2527 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2528 ASSERT_TRUE(base::PathExists(source_icon));
2530 // Set up the temporary extension directory.
2531 base::ScopedTempDir temp;
2532 ASSERT_TRUE(temp.CreateUniqueTempDir());
2533 base::FilePath extension_path = temp.path();
2534 base::FilePath manifest = extension_path.Append(
2535 extensions::kManifestFilename);
2536 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2537 base::CopyFile(source_manifest, manifest);
2538 file_util::CreateSymbolicLink(source_icon, icon_symlink);
2541 InitializeEmptyExtensionService();
2542 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2543 base::RunLoop().RunUntilIdle();
2545 EXPECT_TRUE(GetErrors().empty());
2546 ASSERT_EQ(1u, loaded_.size());
2547 EXPECT_EQ(1u, service_->extensions()->size());
2551 TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
2552 InitializeEmptyExtensionService();
2553 base::FilePath extension_path = data_dir_
2554 .AppendASCII("underscore_name");
2555 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2556 base::RunLoop().RunUntilIdle();
2557 EXPECT_EQ(1u, GetErrors().size());
2558 EXPECT_EQ(0u, service_->extensions()->size());
2561 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
2562 InitializeEmptyExtensionService();
2565 base::FilePath theme_path = data_dir_
2566 .AppendASCII("theme_i18n");
2568 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
2570 EXPECT_EQ(0u, GetErrors().size());
2571 EXPECT_EQ(1u, service_->extensions()->size());
2572 EXPECT_EQ("name", theme->name());
2573 EXPECT_EQ("description", theme->description());
2576 TEST_F(ExtensionServiceTest, InstallApps) {
2577 InitializeEmptyExtensionService();
2580 const Extension* app = PackAndInstallCRX(data_dir_.AppendASCII("app1"),
2583 ValidatePrefKeyCount(++pref_count);
2584 ASSERT_EQ(1u, service_->extensions()->size());
2585 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2586 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
2588 // Another app with non-overlapping extent. Should succeed.
2589 PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
2590 ValidatePrefKeyCount(++pref_count);
2592 // A third app whose extent overlaps the first. Should fail.
2593 PackAndInstallCRX(data_dir_.AppendASCII("app3"), INSTALL_FAILED);
2594 ValidatePrefKeyCount(pref_count);
2597 // Tests that file access is OFF by default.
2598 TEST_F(ExtensionServiceTest, DefaultFileAccess) {
2599 InitializeEmptyExtensionService();
2600 const Extension* extension =
2601 PackAndInstallCRX(data_dir_
2602 .AppendASCII("permissions")
2603 .AppendASCII("files"),
2605 EXPECT_EQ(0u, GetErrors().size());
2606 EXPECT_EQ(1u, service_->extensions()->size());
2607 EXPECT_FALSE(service_->extension_prefs()->AllowFileAccess(extension->id()));
2610 TEST_F(ExtensionServiceTest, UpdateApps) {
2611 InitializeEmptyExtensionService();
2612 base::FilePath extensions_path = data_dir_.AppendASCII("app_update");
2614 // First install v1 of a hosted app.
2615 const Extension* extension =
2616 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2617 ASSERT_EQ(1u, service_->extensions()->size());
2618 std::string id = extension->id();
2619 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2621 // Now try updating to v2.
2623 extensions_path.AppendASCII("v2.crx"),
2625 ASSERT_EQ(std::string("2"),
2626 service_->GetExtensionById(id, false)->version()->GetString());
2629 // Verifies that the NTP page and launch ordinals are kept when updating apps.
2630 TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
2631 InitializeEmptyExtensionService();
2632 ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
2633 base::FilePath extensions_path = data_dir_.AppendASCII("app_update");
2635 // First install v1 of a hosted app.
2636 const Extension* extension =
2637 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2638 ASSERT_EQ(1u, service_->extensions()->size());
2639 std::string id = extension->id();
2640 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2642 // Modify the ordinals so we can distinguish them from the defaults.
2643 syncer::StringOrdinal new_page_ordinal =
2644 sorting->GetPageOrdinal(id).CreateAfter();
2645 syncer::StringOrdinal new_launch_ordinal =
2646 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2648 sorting->SetPageOrdinal(id, new_page_ordinal);
2649 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2651 // Now try updating to v2.
2652 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2653 ASSERT_EQ(std::string("2"),
2654 service_->GetExtensionById(id, false)->version()->GetString());
2656 // Verify that the ordinals match.
2657 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2658 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
2661 // Ensures that the CWS has properly initialized ordinals.
2662 TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
2663 InitializeEmptyExtensionService();
2664 service_->component_loader()->Add(
2665 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
2668 ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
2670 sorting->GetPageOrdinal(extension_misc::kWebStoreAppId).IsValid());
2672 sorting->GetAppLaunchOrdinal(extension_misc::kWebStoreAppId).IsValid());
2675 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
2676 InitializeEmptyExtensionService();
2677 EXPECT_TRUE(service_->extensions()->is_empty());
2681 // Install app1 with unlimited storage.
2682 const Extension* extension =
2683 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
2684 ValidatePrefKeyCount(++pref_count);
2685 ASSERT_EQ(1u, service_->extensions()->size());
2686 const std::string id1 = extension->id();
2687 EXPECT_TRUE(extension->HasAPIPermission(
2688 APIPermission::kUnlimitedStorage));
2689 EXPECT_TRUE(extension->web_extent().MatchesURL(
2690 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2692 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2693 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2694 IsStorageUnlimited(origin1));
2696 // Install app2 from the same origin with unlimited storage.
2697 extension = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
2698 ValidatePrefKeyCount(++pref_count);
2699 ASSERT_EQ(2u, service_->extensions()->size());
2700 const std::string id2 = extension->id();
2701 EXPECT_TRUE(extension->HasAPIPermission(
2702 APIPermission::kUnlimitedStorage));
2703 EXPECT_TRUE(extension->web_extent().MatchesURL(
2704 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2706 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2707 EXPECT_EQ(origin1, origin2);
2708 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2709 IsStorageUnlimited(origin2));
2712 // Uninstall one of them, unlimited storage should still be granted
2714 UninstallExtension(id1, false);
2715 EXPECT_EQ(1u, service_->extensions()->size());
2716 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2717 IsStorageUnlimited(origin1));
2719 // Uninstall the other, unlimited storage should be revoked.
2720 UninstallExtension(id2, false);
2721 EXPECT_EQ(0u, service_->extensions()->size());
2722 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2723 IsStorageUnlimited(origin2));
2726 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
2727 InitializeEmptyExtensionService();
2728 EXPECT_TRUE(service_->extensions()->is_empty());
2732 const Extension* extension =
2733 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
2734 ValidatePrefKeyCount(++pref_count);
2735 ASSERT_EQ(1u, service_->extensions()->size());
2736 EXPECT_TRUE(extension->is_app());
2737 const std::string id1 = extension->id();
2739 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2740 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2741 IsStorageProtected(origin1));
2743 // App 4 has a different origin (maps.google.com).
2744 extension = PackAndInstallCRX(data_dir_.AppendASCII("app4"), INSTALL_NEW);
2745 ValidatePrefKeyCount(++pref_count);
2746 ASSERT_EQ(2u, service_->extensions()->size());
2747 const std::string id2 = extension->id();
2749 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2750 ASSERT_NE(origin1, origin2);
2751 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2752 IsStorageProtected(origin2));
2754 UninstallExtension(id1, false);
2755 EXPECT_EQ(1u, service_->extensions()->size());
2757 UninstallExtension(id2, false);
2759 EXPECT_TRUE(service_->extensions()->is_empty());
2760 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2761 IsStorageProtected(origin1));
2762 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2763 IsStorageProtected(origin2));
2766 // Test that when an extension version is reinstalled, nothing happens.
2767 TEST_F(ExtensionServiceTest, Reinstall) {
2768 InitializeEmptyExtensionService();
2770 // A simple extension that should install without error.
2771 base::FilePath path = data_dir_.AppendASCII("good.crx");
2772 InstallCRX(path, INSTALL_NEW);
2774 ValidatePrefKeyCount(1);
2775 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2776 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2778 // Reinstall the same version, it should overwrite the previous one.
2779 InstallCRX(path, INSTALL_UPDATED);
2781 ValidatePrefKeyCount(1);
2782 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2783 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2786 // Test that we can determine if extensions came from the
2787 // Chrome web store.
2788 TEST_F(ExtensionServiceTest, FromWebStore) {
2789 InitializeEmptyExtensionService();
2791 // A simple extension that should install without error.
2792 base::FilePath path = data_dir_.AppendASCII("good.crx");
2793 // Not from web store.
2794 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2795 std::string id = extension->id();
2797 ValidatePrefKeyCount(1);
2798 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
2799 ASSERT_FALSE(extension->from_webstore());
2801 // Test install from web store.
2802 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
2804 ValidatePrefKeyCount(1);
2805 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2807 // Reload so extension gets reinitialized with new value.
2808 service_->ReloadExtensions();
2809 extension = service_->GetExtensionById(id, false);
2810 ASSERT_TRUE(extension->from_webstore());
2812 // Upgrade to version 2.0
2813 path = data_dir_.AppendASCII("good2.crx");
2814 UpdateExtension(good_crx, path, ENABLED);
2815 ValidatePrefKeyCount(1);
2816 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2819 // Test upgrading a signed extension.
2820 TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
2821 InitializeEmptyExtensionService();
2823 base::FilePath path = data_dir_.AppendASCII("good.crx");
2824 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2825 std::string id = extension->id();
2827 ASSERT_EQ("1.0.0.0", extension->version()->GetString());
2828 ASSERT_EQ(0u, GetErrors().size());
2830 // Upgrade to version 1.0.0.1.
2831 // Also test that the extension's old and new title are correctly retrieved.
2832 path = data_dir_.AppendASCII("good2.crx");
2833 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
2834 extension = service_->GetExtensionById(id, false);
2836 ASSERT_EQ("1.0.0.1", extension->version()->GetString());
2837 ASSERT_EQ("My updated extension 1", extension->name());
2838 ASSERT_EQ(0u, GetErrors().size());
2841 // Test upgrading a signed extension with a bad signature.
2842 TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
2843 InitializeEmptyExtensionService();
2845 base::FilePath path = data_dir_.AppendASCII("good.crx");
2846 InstallCRX(path, INSTALL_NEW);
2848 // Try upgrading with a bad signature. This should fail during the unpack,
2849 // because the key will not match the signature.
2850 path = data_dir_.AppendASCII("bad_signature.crx");
2851 InstallCRX(path, INSTALL_FAILED);
2854 // Test a normal update via the UpdateExtension API
2855 TEST_F(ExtensionServiceTest, UpdateExtension) {
2856 InitializeEmptyExtensionService();
2858 base::FilePath path = data_dir_.AppendASCII("good.crx");
2860 const Extension* good = InstallCRX(path, INSTALL_NEW);
2861 ASSERT_EQ("1.0.0.0", good->VersionString());
2862 ASSERT_EQ(good_crx, good->id());
2864 path = data_dir_.AppendASCII("good2.crx");
2865 UpdateExtension(good_crx, path, ENABLED);
2866 ASSERT_EQ("1.0.0.1",
2867 service_->GetExtensionById(good_crx, false)->
2868 version()->GetString());
2871 // Extensions should not be updated during browser shutdown.
2872 TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
2873 InitializeEmptyExtensionService();
2875 // Install an extension.
2876 base::FilePath path = data_dir_.AppendASCII("good.crx");
2877 const Extension* good = InstallCRX(path, INSTALL_NEW);
2878 ASSERT_EQ(good_crx, good->id());
2880 // Simulate shutdown.
2881 service_->set_browser_terminating_for_test(true);
2883 // Update should fail and extension should not be updated.
2884 path = data_dir_.AppendASCII("good2.crx");
2885 bool updated = service_->UpdateExtension(good_crx, path, GURL(), NULL);
2886 ASSERT_FALSE(updated);
2887 ASSERT_EQ("1.0.0.0",
2888 service_->GetExtensionById(good_crx, false)->
2889 version()->GetString());
2892 // Test updating a not-already-installed extension - this should fail
2893 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
2894 InitializeEmptyExtensionService();
2896 base::FilePath path = data_dir_.AppendASCII("good.crx");
2897 UpdateExtension(good_crx, path, UPDATED);
2898 base::RunLoop().RunUntilIdle();
2900 ASSERT_EQ(0u, service_->extensions()->size());
2901 ASSERT_FALSE(installed_);
2902 ASSERT_EQ(0u, loaded_.size());
2905 // Makes sure you can't downgrade an extension via UpdateExtension
2906 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
2907 InitializeEmptyExtensionService();
2909 base::FilePath path = data_dir_.AppendASCII("good2.crx");
2911 const Extension* good = InstallCRX(path, INSTALL_NEW);
2912 ASSERT_EQ("1.0.0.1", good->VersionString());
2913 ASSERT_EQ(good_crx, good->id());
2915 // Change path from good2.crx -> good.crx
2916 path = data_dir_.AppendASCII("good.crx");
2917 UpdateExtension(good_crx, path, FAILED);
2918 ASSERT_EQ("1.0.0.1",
2919 service_->GetExtensionById(good_crx, false)->
2920 version()->GetString());
2923 // Make sure calling update with an identical version does nothing
2924 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
2925 InitializeEmptyExtensionService();
2927 base::FilePath path = data_dir_.AppendASCII("good.crx");
2929 const Extension* good = InstallCRX(path, INSTALL_NEW);
2930 ASSERT_EQ(good_crx, good->id());
2931 UpdateExtension(good_crx, path, FAILED_SILENTLY);
2934 // Tests that updating an extension does not clobber old state.
2935 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
2936 InitializeEmptyExtensionService();
2938 base::FilePath path = data_dir_.AppendASCII("good.crx");
2940 const Extension* good = InstallCRX(path, INSTALL_NEW);
2941 ASSERT_EQ("1.0.0.0", good->VersionString());
2942 ASSERT_EQ(good_crx, good->id());
2944 // Disable it and allow it to run in incognito. These settings should carry
2945 // over to the updated version.
2946 service_->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
2947 extension_util::SetIsIncognitoEnabled(good->id(), service_, true);
2948 service_->extension_prefs()->SetDidExtensionEscalatePermissions(good, true);
2950 path = data_dir_.AppendASCII("good2.crx");
2951 UpdateExtension(good_crx, path, INSTALLED);
2952 ASSERT_EQ(1u, service_->disabled_extensions()->size());\
2953 const Extension* good2 = service_->GetExtensionById(good_crx, true);
2954 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2955 EXPECT_TRUE(extension_util::IsIncognitoEnabled(good2->id(), service_));
2956 EXPECT_TRUE(service_->extension_prefs()->DidExtensionEscalatePermissions(
2960 // Tests that updating preserves extension location.
2961 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
2962 InitializeEmptyExtensionService();
2964 base::FilePath path = data_dir_.AppendASCII("good.crx");
2966 const Extension* good =
2967 InstallCRXWithLocation(path, Manifest::EXTERNAL_PREF, INSTALL_NEW);
2969 ASSERT_EQ("1.0.0.0", good->VersionString());
2970 ASSERT_EQ(good_crx, good->id());
2972 path = data_dir_.AppendASCII("good2.crx");
2973 UpdateExtension(good_crx, path, ENABLED);
2974 const Extension* good2 = service_->GetExtensionById(good_crx, false);
2975 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2976 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
2979 // Makes sure that LOAD extension types can downgrade.
2980 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
2981 InitializeEmptyExtensionService();
2983 base::ScopedTempDir temp;
2984 ASSERT_TRUE(temp.CreateUniqueTempDir());
2986 // We'll write the extension manifest dynamically to a temporary path
2987 // to make it easier to change the version number.
2988 base::FilePath extension_path = temp.path();
2989 base::FilePath manifest_path =
2990 extension_path.Append(extensions::kManifestFilename);
2991 ASSERT_FALSE(base::PathExists(manifest_path));
2993 // Start with version 2.0.
2994 DictionaryValue manifest;
2995 manifest.SetString("version", "2.0");
2996 manifest.SetString("name", "LOAD Downgrade Test");
2997 manifest.SetInteger("manifest_version", 2);
2999 JSONFileValueSerializer serializer(manifest_path);
3000 ASSERT_TRUE(serializer.Serialize(manifest));
3002 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
3003 base::RunLoop().RunUntilIdle();
3005 EXPECT_EQ(0u, GetErrors().size());
3006 ASSERT_EQ(1u, loaded_.size());
3007 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
3008 EXPECT_EQ(1u, service_->extensions()->size());
3009 EXPECT_EQ("2.0", loaded_[0]->VersionString());
3011 // Now set the version number to 1.0, reload the extensions and verify that
3012 // the downgrade was accepted.
3013 manifest.SetString("version", "1.0");
3014 ASSERT_TRUE(serializer.Serialize(manifest));
3016 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
3017 base::RunLoop().RunUntilIdle();
3019 EXPECT_EQ(0u, GetErrors().size());
3020 ASSERT_EQ(1u, loaded_.size());
3021 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
3022 EXPECT_EQ(1u, service_->extensions()->size());
3023 EXPECT_EQ("1.0", loaded_[0]->VersionString());
3026 #if !defined(OS_CHROMEOS)
3027 // LOAD extensions with plugins require approval.
3028 TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
3029 base::FilePath extension_with_plugin_path = good1_path();
3030 base::FilePath extension_no_plugin_path = good2_path();
3032 InitPluginService();
3033 InitializeEmptyExtensionService();
3034 InitializeExtensionProcessManager();
3035 service_->set_show_extensions_prompts(true);
3037 // Start by canceling any install prompts.
3038 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
3039 switches::kAppsGalleryInstallAutoConfirmForTests,
3042 // The extension that has a plugin should not install.
3043 extensions::UnpackedInstaller::Create(service_)->Load(
3044 extension_with_plugin_path);
3045 base::RunLoop().RunUntilIdle();
3046 EXPECT_EQ(0u, GetErrors().size());
3047 EXPECT_EQ(0u, loaded_.size());
3048 EXPECT_EQ(0u, service_->extensions()->size());
3049 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3051 // But the extension with no plugin should since there's no prompt.
3052 ExtensionErrorReporter::GetInstance()->ClearErrors();
3053 extensions::UnpackedInstaller::Create(service_)->Load(
3054 extension_no_plugin_path);
3055 base::RunLoop().RunUntilIdle();
3056 EXPECT_EQ(0u, GetErrors().size());
3057 EXPECT_EQ(1u, loaded_.size());
3058 EXPECT_EQ(1u, service_->extensions()->size());
3059 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3060 EXPECT_TRUE(service_->extensions()->Contains(good2));
3062 // The plugin extension should install if we accept the dialog.
3063 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
3064 switches::kAppsGalleryInstallAutoConfirmForTests,
3067 ExtensionErrorReporter::GetInstance()->ClearErrors();
3068 extensions::UnpackedInstaller::Create(service_)->Load(
3069 extension_with_plugin_path);
3070 base::RunLoop().RunUntilIdle();
3071 EXPECT_EQ(0u, GetErrors().size());
3072 EXPECT_EQ(2u, loaded_.size());
3073 EXPECT_EQ(2u, service_->extensions()->size());
3074 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3075 EXPECT_TRUE(service_->extensions()->Contains(good1));
3076 EXPECT_TRUE(service_->extensions()->Contains(good2));
3078 // Make sure the granted permissions have been setup.
3079 scoped_refptr<PermissionSet> permissions(
3080 service_->extension_prefs()->GetGrantedPermissions(good1));
3081 EXPECT_FALSE(permissions->IsEmpty());
3082 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
3083 EXPECT_FALSE(permissions->apis().empty());
3084 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
3086 // We should be able to reload the extension without getting another prompt.
3088 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
3089 switches::kAppsGalleryInstallAutoConfirmForTests,
3092 service_->ReloadExtension(good1);
3093 base::RunLoop().RunUntilIdle();
3094 EXPECT_EQ(1u, loaded_.size());
3095 EXPECT_EQ(2u, service_->extensions()->size());
3096 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3102 bool IsExtension(const Extension* extension) {
3103 return extension->GetType() == Manifest::TYPE_EXTENSION;
3108 // Test adding a pending extension.
3109 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
3110 InitializeEmptyExtensionService();
3112 const std::string kFakeId(all_zero);
3113 const GURL kFakeUpdateURL("http:://fake.update/url");
3114 const bool kFakeInstallSilently(true);
3116 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
3117 kFakeId, kFakeUpdateURL, &IsExtension,
3118 kFakeInstallSilently));
3120 const extensions::PendingExtensionInfo* pending_extension_info;
3121 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
3123 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
3124 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
3125 EXPECT_EQ(kFakeInstallSilently, pending_extension_info->install_silently());
3129 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
3130 const char kGoodUpdateURL[] = "http://good.update/url";
3131 const bool kGoodIsFromSync = true;
3132 const bool kGoodInstallSilently = true;
3135 // Test updating a pending extension.
3136 TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
3137 InitializeEmptyExtensionService();
3138 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
3139 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
3140 kGoodInstallSilently));
3141 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3143 base::FilePath path = data_dir_.AppendASCII("good.crx");
3144 UpdateExtension(kGoodId, path, ENABLED);
3146 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3148 const Extension* extension = service_->GetExtensionById(kGoodId, true);
3149 ASSERT_TRUE(extension);
3154 bool IsTheme(const Extension* extension) {
3155 return extension->is_theme();
3160 // Test updating a pending theme.
3161 // Disabled due to ASAN failure. http://crbug.com/108320
3162 TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
3163 InitializeEmptyExtensionService();
3164 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
3165 theme_crx, GURL(), &IsTheme, false));
3166 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3168 base::FilePath path = data_dir_.AppendASCII("theme.crx");
3169 UpdateExtension(theme_crx, path, ENABLED);
3171 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3173 const Extension* extension = service_->GetExtensionById(theme_crx, true);
3174 ASSERT_TRUE(extension);
3177 service_->extension_prefs()->IsExtensionDisabled(extension->id()));
3178 EXPECT_TRUE(service_->IsExtensionEnabled(theme_crx));
3181 #if defined(OS_CHROMEOS)
3182 // Always fails on ChromeOS: http://crbug.com/79737
3183 #define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
3185 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
3187 // Test updating a pending CRX as if the source is an external extension
3188 // with an update URL. In this case we don't know if the CRX is a theme
3190 TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
3191 InitializeEmptyExtensionService();
3192 EXPECT_TRUE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
3193 theme_crx, GURL(), Manifest::EXTERNAL_PREF_DOWNLOAD, Extension::NO_FLAGS,
3196 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3198 base::FilePath path = data_dir_.AppendASCII("theme.crx");
3199 UpdateExtension(theme_crx, path, ENABLED);
3201 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3203 const Extension* extension = service_->GetExtensionById(theme_crx, true);
3204 ASSERT_TRUE(extension);
3207 service_->extension_prefs()->IsExtensionDisabled(extension->id()));
3208 EXPECT_TRUE(service_->IsExtensionEnabled(extension->id()));
3209 EXPECT_FALSE(extension_util::IsIncognitoEnabled(extension->id(), service_));
3212 // Test updating a pending CRX as if the source is an external extension
3213 // with an update URL. The external update should overwrite a sync update,
3214 // but a sync update should not overwrite a non-sync update.
3215 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
3216 InitializeEmptyExtensionService();
3218 // Add a crx to be installed from the update mechanism.
3219 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
3220 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
3221 kGoodInstallSilently));
3223 // Check that there is a pending crx, with is_from_sync set to true.
3224 const extensions::PendingExtensionInfo* pending_extension_info;
3225 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
3227 EXPECT_TRUE(pending_extension_info->is_from_sync());
3229 // Add a crx to be updated, with the same ID, from a non-sync source.
3230 EXPECT_TRUE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
3231 kGoodId, GURL(kGoodUpdateURL), Manifest::EXTERNAL_PREF_DOWNLOAD,
3232 Extension::NO_FLAGS, false));
3234 // Check that there is a pending crx, with is_from_sync set to false.
3235 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
3237 EXPECT_FALSE(pending_extension_info->is_from_sync());
3238 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3239 pending_extension_info->install_source());
3241 // Add a crx to be installed from the update mechanism.
3242 EXPECT_FALSE(service_->pending_extension_manager()->AddFromSync(
3243 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
3244 kGoodInstallSilently));
3246 // Check that the external, non-sync update was not overridden.
3247 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
3249 EXPECT_FALSE(pending_extension_info->is_from_sync());
3250 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3251 pending_extension_info->install_source());
3254 // Updating a theme should fail if the updater is explicitly told that
3255 // the CRX is not a theme.
3256 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
3257 InitializeEmptyExtensionService();
3258 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
3259 theme_crx, GURL(), &IsExtension, true));
3261 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3263 base::FilePath path = data_dir_.AppendASCII("theme.crx");
3264 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
3266 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3268 const Extension* extension = service_->GetExtensionById(theme_crx, true);
3269 ASSERT_FALSE(extension);
3272 // TODO(akalin): Test updating a pending extension non-silently once
3273 // we can mock out ExtensionInstallUI and inject our version into
3274 // UpdateExtension().
3276 // Test updating a pending extension which fails the should-install test.
3277 TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
3278 InitializeEmptyExtensionService();
3279 // Add pending extension with a flipped is_theme.
3280 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
3281 kGoodId, GURL(kGoodUpdateURL), &IsTheme, kGoodInstallSilently));
3282 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3284 base::FilePath path = data_dir_.AppendASCII("good.crx");
3285 UpdateExtension(kGoodId, path, UPDATED);
3287 // TODO(akalin): Figure out how to check that the extensions
3288 // directory is cleaned up properly in OnExtensionInstalled().
3290 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3293 // TODO(akalin): Figure out how to test that installs of pending
3294 // unsyncable extensions are blocked.
3296 // Test updating a pending extension for one that is not pending.
3297 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
3298 InitializeEmptyExtensionService();
3300 base::FilePath path = data_dir_.AppendASCII("good.crx");
3301 UpdateExtension(kGoodId, path, UPDATED);
3303 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3306 // Test updating a pending extension for one that is already
3308 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
3309 InitializeEmptyExtensionService();
3311 base::FilePath path = data_dir_.AppendASCII("good.crx");
3312 const Extension* good = InstallCRX(path, INSTALL_NEW);
3313 ASSERT_EQ(1u, service_->extensions()->size());
3315 EXPECT_FALSE(good->is_theme());
3317 // Use AddExtensionImpl() as AddFrom*() would balk.
3318 service_->pending_extension_manager()->AddExtensionImpl(
3319 good->id(), extensions::ManifestURL::GetUpdateURL(good),
3320 Version(), &IsExtension, kGoodIsFromSync,
3321 kGoodInstallSilently, Manifest::INTERNAL,
3322 Extension::NO_FLAGS, false);
3323 UpdateExtension(good->id(), path, ENABLED);
3325 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3328 #if defined(ENABLE_BLACKLIST_TESTS)
3329 // Tests blacklisting then unblacklisting extensions after the service has been
3331 TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
3332 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3333 new FakeSafeBrowsingDatabaseManager(true));
3334 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3336 // A profile with 3 extensions installed: good0, good1, and good2.
3337 InitializeGoodInstalledExtensionService();
3340 const ExtensionSet* extensions = service_->extensions();
3341 const ExtensionSet* blacklisted_extensions =
3342 service_->blacklisted_extensions();
3344 EXPECT_TRUE( extensions->Contains(good0) &&
3345 !blacklisted_extensions->Contains(good0));
3346 EXPECT_TRUE( extensions->Contains(good1) &&
3347 !blacklisted_extensions->Contains(good1));
3348 EXPECT_TRUE( extensions->Contains(good2) &&
3349 !blacklisted_extensions->Contains(good2));
3351 EXPECT_FALSE(IsPrefExist(good0, "blacklist"));
3352 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3353 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3354 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3356 // Blacklist good0 and good1 (and an invalid extension ID).
3357 blacklist_db->SetUnsafe(good0, good1, "invalid_id").NotifyUpdate();
3358 base::RunLoop().RunUntilIdle();
3360 EXPECT_TRUE(!extensions->Contains(good0) &&
3361 blacklisted_extensions->Contains(good0));
3362 EXPECT_TRUE(!extensions->Contains(good1) &&
3363 blacklisted_extensions->Contains(good1));
3364 EXPECT_TRUE( extensions->Contains(good2) &&
3365 !blacklisted_extensions->Contains(good2));
3367 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3368 EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true));
3369 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3370 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3372 // Un-blacklist good1 and blacklist good2.
3373 blacklist_db->SetUnsafe(good0, good2, "invalid_id").NotifyUpdate();
3374 base::RunLoop().RunUntilIdle();
3376 EXPECT_TRUE(!extensions->Contains(good0) &&
3377 blacklisted_extensions->Contains(good0));
3378 EXPECT_TRUE( extensions->Contains(good1) &&
3379 !blacklisted_extensions->Contains(good1));
3380 EXPECT_TRUE(!extensions->Contains(good2) &&
3381 blacklisted_extensions->Contains(good2));
3383 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3384 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3385 EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true));
3386 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3388 #endif // defined(ENABLE_BLACKLIST_TESTS)
3390 #if defined(ENABLE_BLACKLIST_TESTS)
3391 // Tests trying to install a blacklisted extension.
3392 TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
3393 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3394 new FakeSafeBrowsingDatabaseManager(true));
3395 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3397 InitializeEmptyExtensionService();
3400 // After blacklisting good_crx, we cannot install it.
3401 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
3402 base::RunLoop().RunUntilIdle();
3404 base::FilePath path = data_dir_.AppendASCII("good.crx");
3405 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3406 // decide to install this silently. Somebody should fix these tests, all
3407 // 6,000 lines of them. Hah!
3408 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
3409 EXPECT_EQ(0u, service_->extensions()->size());
3411 #endif // defined(ENABLE_BLACKLIST_TESTS)
3413 #if defined(ENABLE_BLACKLIST_TESTS)
3414 // Unload blacklisted extension on policy change.
3415 TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
3416 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3417 new FakeSafeBrowsingDatabaseManager(true));
3418 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3420 // A profile with no extensions installed.
3421 InitializeEmptyExtensionService();
3423 base::FilePath path = data_dir_.AppendASCII("good.crx");
3425 const Extension* good = InstallCRX(path, INSTALL_NEW);
3426 EXPECT_EQ(good_crx, good->id());
3427 UpdateExtension(good_crx, path, FAILED_SILENTLY);
3428 EXPECT_EQ(1u, service_->extensions()->size());
3430 base::ListValue whitelist;
3431 PrefService* prefs = service_->extension_prefs()->pref_service();
3432 whitelist.Append(new base::StringValue(good_crx));
3433 prefs->Set(prefs::kExtensionInstallAllowList, whitelist);
3435 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
3436 base::RunLoop().RunUntilIdle();
3438 // The good_crx is blacklisted and the whitelist doesn't negate it.
3439 ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true));
3440 EXPECT_EQ(0u, service_->extensions()->size());
3442 #endif // defined(ENABLE_BLACKLIST_TESTS)
3444 #if defined(ENABLE_BLACKLIST_TESTS)
3445 // Tests that a blacklisted extension is eventually unloaded on startup, if it
3447 TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
3448 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3449 new FakeSafeBrowsingDatabaseManager(true));
3450 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3452 // A profile with 3 extensions installed: good0, good1, and good2.
3453 InitializeGoodInstalledExtensionService();
3455 // Blacklist good1 before the service initializes.
3456 blacklist_db->SetUnsafe(good1);
3460 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet
3462 base::RunLoop().RunUntilIdle();
3463 ASSERT_EQ(1u, service_->blacklisted_extensions()->size());
3464 ASSERT_EQ(2u, service_->extensions()->size());
3466 ASSERT_TRUE(service_->extensions()->Contains(good0));
3467 ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good1));
3468 ASSERT_TRUE(service_->extensions()->Contains(good2));
3470 #endif // defined(ENABLE_BLACKLIST_TESTS)
3472 #if defined(ENABLE_BLACKLIST_TESTS)
3473 // Tests extensions blacklisted in prefs on startup; one still blacklisted by
3474 // safe browsing, the other not. The not-blacklisted one should recover.
3475 TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) {
3476 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3477 new FakeSafeBrowsingDatabaseManager(true));
3478 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3480 InitializeGoodInstalledExtensionService();
3481 service_->extension_prefs()->SetExtensionBlacklisted(good0, true);
3482 service_->extension_prefs()->SetExtensionBlacklisted(good1, true);
3484 blacklist_db->SetUnsafe(good1);
3488 ASSERT_EQ(2u, service_->blacklisted_extensions()->size());
3489 ASSERT_EQ(1u, service_->extensions()->size());
3491 ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good0));
3492 ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good1));
3493 ASSERT_TRUE(service_->extensions()->Contains(good2));
3495 // Give time for the blacklist to update.
3496 base::RunLoop().RunUntilIdle();
3498 ASSERT_EQ(1u, service_->blacklisted_extensions()->size());
3499 ASSERT_EQ(2u, service_->extensions()->size());
3501 ASSERT_TRUE(service_->extensions()->Contains(good0));
3502 ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good1));
3503 ASSERT_TRUE(service_->extensions()->Contains(good2));
3505 #endif // defined(ENABLE_BLACKLIST_TESTS)
3507 // Will not install extension blacklisted by policy.
3508 TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
3509 InitializeEmptyExtensionService();
3511 // Blacklist everything.
3513 ListPrefUpdate update(profile_->GetPrefs(),
3514 prefs::kExtensionInstallDenyList);
3515 ListValue* blacklist = update.Get();
3516 blacklist->Append(new base::StringValue("*"));
3519 // Blacklist prevents us from installing good_crx.
3520 base::FilePath path = data_dir_.AppendASCII("good.crx");
3521 InstallCRX(path, INSTALL_FAILED);
3522 EXPECT_EQ(0u, service_->extensions()->size());
3524 // Now whitelist this particular extension.
3526 ListPrefUpdate update(profile_->GetPrefs(),
3527 prefs::kExtensionInstallAllowList);
3528 ListValue* whitelist = update.Get();
3529 whitelist->Append(new base::StringValue(good_crx));
3532 // Ensure we can now install good_crx.
3533 InstallCRX(path, INSTALL_NEW);
3534 EXPECT_EQ(1u, service_->extensions()->size());
3537 // Extension blacklisted by policy get unloaded after installing.
3538 TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
3539 InitializeEmptyExtensionService();
3541 // Install good_crx.
3542 base::FilePath path = data_dir_.AppendASCII("good.crx");
3543 InstallCRX(path, INSTALL_NEW);
3544 EXPECT_EQ(1u, service_->extensions()->size());
3546 { // Scope for pref update notification.
3547 PrefService* prefs = profile_->GetPrefs();
3548 ListPrefUpdate update(prefs, prefs::kExtensionInstallDenyList);
3549 ListValue* blacklist = update.Get();
3550 ASSERT_TRUE(blacklist != NULL);
3552 // Blacklist this extension.
3553 blacklist->Append(new base::StringValue(good_crx));
3556 // Extension should not be running now.
3557 base::RunLoop().RunUntilIdle();
3558 EXPECT_EQ(0u, service_->extensions()->size());
3561 // Tests that component extensions are not blacklisted by policy.
3562 TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
3563 InitializeEmptyExtensionService();
3565 // Blacklist everything.
3567 ListPrefUpdate update(profile_->GetPrefs(),
3568 prefs::kExtensionInstallDenyList);
3569 ListValue* blacklist = update.Get();
3570 blacklist->Append(new base::StringValue("*"));
3573 // Install a component extension.
3574 base::FilePath path = data_dir_
3575 .AppendASCII("good")
3576 .AppendASCII("Extensions")
3578 .AppendASCII("1.0.0.0");
3579 std::string manifest;
3580 ASSERT_TRUE(base::ReadFileToString(
3581 path.Append(extensions::kManifestFilename), &manifest));
3582 service_->component_loader()->Add(manifest, path);
3585 // Extension should be installed despite blacklist.
3586 ASSERT_EQ(1u, service_->extensions()->size());
3587 EXPECT_TRUE(service_->GetExtensionById(good0, false));
3589 // Poke external providers and make sure the extension is still present.
3590 service_->CheckForExternalUpdates();
3591 ASSERT_EQ(1u, service_->extensions()->size());
3592 EXPECT_TRUE(service_->GetExtensionById(good0, false));
3594 // Extension should not be uninstalled on blacklist changes.
3596 ListPrefUpdate update(profile_->GetPrefs(),
3597 prefs::kExtensionInstallDenyList);
3598 ListValue* blacklist = update.Get();
3599 blacklist->Append(new base::StringValue(good0));
3601 base::RunLoop().RunUntilIdle();
3602 ASSERT_EQ(1u, service_->extensions()->size());
3603 EXPECT_TRUE(service_->GetExtensionById(good0, false));
3606 // Tests that policy-installed extensions are not blacklisted by policy.
3607 TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
3608 InitializeEmptyExtensionService();
3611 // Blacklist everything.
3612 ListPrefUpdate blacklist_update(profile_->GetPrefs(),
3613 prefs::kExtensionInstallDenyList);
3614 ListValue* blacklist = blacklist_update.Get();
3615 blacklist->AppendString("*");
3617 // Mark good.crx for force-installation.
3618 DictionaryPrefUpdate forcelist_update(profile_->GetPrefs(),
3619 prefs::kExtensionInstallForceList);
3620 extensions::ExternalPolicyLoader::AddExtension(
3621 forcelist_update.Get(), good_crx, "http://example.com/update_url");
3624 // Have policy force-install an extension.
3625 MockExtensionProvider* provider =
3626 new MockExtensionProvider(service_,
3627 Manifest::EXTERNAL_POLICY_DOWNLOAD);
3628 AddMockExternalProvider(provider);
3629 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
3630 data_dir_.AppendASCII("good.crx"));
3632 // Reloading extensions should find our externally registered extension
3634 service_->CheckForExternalUpdates();
3635 content::WindowedNotificationObserver(
3636 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
3637 content::NotificationService::AllSources()).Wait();
3639 // Extension should be installed despite blacklist.
3640 ASSERT_EQ(1u, service_->extensions()->size());
3641 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3643 // Blacklist update should not uninstall the extension.
3645 ListPrefUpdate update(profile_->GetPrefs(),
3646 prefs::kExtensionInstallDenyList);
3647 ListValue* blacklist = update.Get();
3648 blacklist->Append(new base::StringValue(good0));
3650 base::RunLoop().RunUntilIdle();
3651 ASSERT_EQ(1u, service_->extensions()->size());
3652 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3655 // Tests that extensions cannot be installed if the policy provider prohibits
3656 // it. This functionality is implemented in CrxInstaller::ConfirmInstall().
3657 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
3658 InitializeEmptyExtensionService();
3660 management_policy_->UnregisterAllProviders();
3661 extensions::TestManagementPolicyProvider provider_(
3662 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3663 management_policy_->RegisterProvider(&provider_);
3665 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_FAILED);
3666 EXPECT_EQ(0u, service_->extensions()->size());
3669 // Tests that extensions cannot be loaded from prefs if the policy provider
3670 // prohibits it. This functionality is implemented in InstalledLoader::Load().
3671 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
3672 InitializeEmptyExtensionService();
3674 // Create a fake extension to be loaded as though it were read from prefs.
3675 base::FilePath path = data_dir_.AppendASCII("management")
3676 .AppendASCII("simple_extension");
3677 DictionaryValue manifest;
3678 manifest.SetString(keys::kName, "simple_extension");
3679 manifest.SetString(keys::kVersion, "1");
3680 // UNPACKED is for extensions loaded from a directory. We use it here, even
3681 // though we're testing loading from prefs, so that we don't need to provide
3682 // an extension key.
3683 extensions::ExtensionInfo extension_info(
3684 &manifest, std::string(), path, Manifest::UNPACKED);
3686 // Ensure we can load it with no management policy in place.
3687 management_policy_->UnregisterAllProviders();
3688 EXPECT_EQ(0u, service_->extensions()->size());
3689 extensions::InstalledLoader(service_).Load(extension_info, false);
3690 EXPECT_EQ(1u, service_->extensions()->size());
3692 const Extension* extension = (service_->extensions()->begin())->get();
3693 EXPECT_TRUE(service_->UninstallExtension(extension->id(), false, NULL));
3694 EXPECT_EQ(0u, service_->extensions()->size());
3696 // Ensure we cannot load it if management policy prohibits installation.
3697 extensions::TestManagementPolicyProvider provider_(
3698 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3699 management_policy_->RegisterProvider(&provider_);
3701 extensions::InstalledLoader(service_).Load(extension_info, false);
3702 EXPECT_EQ(0u, service_->extensions()->size());
3705 // Tests disabling an extension when prohibited by the ManagementPolicy.
3706 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
3707 InitializeEmptyExtensionService();
3709 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3710 EXPECT_EQ(1u, service_->extensions()->size());
3711 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3713 management_policy_->UnregisterAllProviders();
3714 extensions::TestManagementPolicyProvider provider(
3715 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3716 management_policy_->RegisterProvider(&provider);
3718 // Attempt to disable it.
3719 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3721 EXPECT_EQ(1u, service_->extensions()->size());
3722 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3723 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3726 // Tests uninstalling an extension when prohibited by the ManagementPolicy.
3727 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
3728 InitializeEmptyExtensionService();
3730 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3731 EXPECT_EQ(1u, service_->extensions()->size());
3732 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3734 management_policy_->UnregisterAllProviders();
3735 extensions::TestManagementPolicyProvider provider(
3736 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3737 management_policy_->RegisterProvider(&provider);
3739 // Attempt to uninstall it.
3740 EXPECT_FALSE(service_->UninstallExtension(good_crx, false, NULL));
3742 EXPECT_EQ(1u, service_->extensions()->size());
3743 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3746 // Tests that previously installed extensions that are now prohibited from
3747 // being installed are removed.
3748 TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
3749 InitializeEmptyExtensionService();
3751 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3752 InstallCRX(data_dir_.AppendASCII("page_action.crx"), INSTALL_NEW);
3753 EXPECT_EQ(2u, service_->extensions()->size());
3754 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3756 management_policy_->UnregisterAllProviders();
3757 extensions::TestManagementPolicyProvider provider(
3758 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3759 management_policy_->RegisterProvider(&provider);
3761 // Run the policy check.
3762 service_->CheckManagementPolicy();
3763 EXPECT_EQ(0u, service_->extensions()->size());
3764 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3767 // Tests that previously disabled extensions that are now required to be
3768 // enabled are re-enabled on reinstall.
3769 TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
3770 InitializeEmptyExtensionService();
3772 // Install, then disable, an extension.
3773 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3774 EXPECT_EQ(1u, service_->extensions()->size());
3775 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3776 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3778 // Register an ExtensionMnagementPolicy that requires the extension to remain
3780 management_policy_->UnregisterAllProviders();
3781 extensions::TestManagementPolicyProvider provider(
3782 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
3783 management_policy_->RegisterProvider(&provider);
3785 // Reinstall the extension.
3786 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_UPDATED);
3787 EXPECT_EQ(1u, service_->extensions()->size());
3788 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3791 // Flaky on windows; http://crbug.com/309833
3793 #define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
3795 #define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
3797 TEST_F(ExtensionServiceTest, ExternalExtensionAutoAcknowledgement) {
3798 InitializeEmptyExtensionService();
3799 set_extensions_enabled(true);
3802 // Register and install an external extension.
3803 MockExtensionProvider* provider =
3804 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
3805 AddMockExternalProvider(provider);
3806 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
3807 data_dir_.AppendASCII("good.crx"));
3810 // Have policy force-install an extension.
3811 MockExtensionProvider* provider =
3812 new MockExtensionProvider(service_,
3813 Manifest::EXTERNAL_POLICY_DOWNLOAD);
3814 AddMockExternalProvider(provider);
3815 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
3816 data_dir_.AppendASCII("page_action.crx"));
3819 // Providers are set up. Let them run.
3820 service_->CheckForExternalUpdates();
3823 content::WindowedNotificationObserver(
3824 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
3825 base::Bind(&WaitForCountNotificationsCallback, &count)).Wait();
3827 ASSERT_EQ(2u, service_->extensions()->size());
3828 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3829 EXPECT_TRUE(service_->GetExtensionById(page_action, false));
3830 ExtensionPrefs* prefs = service_->extension_prefs();
3831 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
3832 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
3835 #if !defined(OS_CHROMEOS)
3836 // This tests if default apps are installed correctly.
3837 TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
3838 InitializeEmptyExtensionService();
3839 set_extensions_enabled(true);
3842 std::string json_data =
3844 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
3845 " \"external_crx\": \"good.crx\","
3846 " \"external_version\": \"1.0.0.0\","
3847 " \"is_bookmark_app\": false"
3850 default_apps::Provider* provider =
3851 new default_apps::Provider(
3854 new extensions::ExternalTestingLoader(json_data, data_dir_),
3856 Manifest::INVALID_LOCATION,
3857 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
3859 AddMockExternalProvider(provider);
3862 ASSERT_EQ(0u, service_->extensions()->size());
3863 service_->CheckForExternalUpdates();
3864 content::WindowedNotificationObserver(
3865 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
3866 content::NotificationService::AllSources()).Wait();
3868 ASSERT_EQ(1u, service_->extensions()->size());
3869 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3870 const Extension* extension = service_->GetExtensionById(good_crx, false);
3871 EXPECT_TRUE(extension->from_webstore());
3872 EXPECT_TRUE(extension->was_installed_by_default());
3876 // Tests disabling extensions
3877 TEST_F(ExtensionServiceTest, DisableExtension) {
3878 InitializeEmptyExtensionService();
3880 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3881 EXPECT_FALSE(service_->extensions()->is_empty());
3882 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3883 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3884 EXPECT_TRUE(service_->disabled_extensions()->is_empty());
3887 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3889 EXPECT_TRUE(service_->extensions()->is_empty());
3890 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3891 EXPECT_FALSE(service_->GetExtensionById(good_crx, false));
3892 EXPECT_FALSE(service_->disabled_extensions()->is_empty());
3895 TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
3896 InitializeEmptyExtensionService();
3898 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3899 TerminateExtension(good_crx);
3900 EXPECT_TRUE(service_->GetTerminatedExtension(good_crx));
3903 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3905 EXPECT_FALSE(service_->GetTerminatedExtension(good_crx));
3906 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3907 EXPECT_FALSE(service_->disabled_extensions()->is_empty());
3910 // Tests disabling all extensions (simulating --disable-extensions flag).
3911 TEST_F(ExtensionServiceTest, DisableAllExtensions) {
3912 InitializeEmptyExtensionService();
3914 base::FilePath path = data_dir_.AppendASCII("good.crx");
3915 InstallCRX(path, INSTALL_NEW);
3917 EXPECT_EQ(1u, service_->extensions()->size());
3918 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3920 // Disable extensions.
3921 service_->set_extensions_enabled(false);
3922 service_->ReloadExtensions();
3924 // There shouldn't be extensions in either list.
3925 EXPECT_EQ(0u, service_->extensions()->size());
3926 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3928 // This shouldn't do anything when all extensions are disabled.
3929 service_->EnableExtension(good_crx);
3930 service_->ReloadExtensions();
3932 // There still shouldn't be extensions in either list.
3933 EXPECT_EQ(0u, service_->extensions()->size());
3934 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3936 // And then re-enable the extensions.
3937 service_->set_extensions_enabled(true);
3938 service_->ReloadExtensions();
3940 EXPECT_EQ(1u, service_->extensions()->size());
3941 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3944 // Tests reloading extensions.
3945 TEST_F(ExtensionServiceTest, ReloadExtensions) {
3946 InitializeEmptyExtensionService();
3948 // Simple extension that should install without error.
3949 base::FilePath path = data_dir_.AppendASCII("good.crx");
3950 InstallCRX(path, INSTALL_NEW,
3951 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
3952 const char* extension_id = good_crx;
3953 service_->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
3955 EXPECT_EQ(0u, service_->extensions()->size());
3956 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3958 service_->ReloadExtensions();
3960 // The creation flags should not change when reloading the extension.
3961 const Extension* extension = service_->GetExtensionById(good_crx, true);
3962 EXPECT_TRUE(extension->from_webstore());
3963 EXPECT_TRUE(extension->was_installed_by_default());
3964 EXPECT_FALSE(extension->from_bookmark());
3966 // Extension counts shouldn't change.
3967 EXPECT_EQ(0u, service_->extensions()->size());
3968 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3970 service_->EnableExtension(extension_id);
3972 EXPECT_EQ(1u, service_->extensions()->size());
3973 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3975 // Need to clear |loaded_| manually before reloading as the
3976 // EnableExtension() call above inserted into it and
3977 // UnloadAllExtensions() doesn't send out notifications.
3979 service_->ReloadExtensions();
3981 // Extension counts shouldn't change.
3982 EXPECT_EQ(1u, service_->extensions()->size());
3983 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3986 // Tests reloading an extension.
3987 TEST_F(ExtensionServiceTest, ReloadExtension) {
3988 InitializeEmptyExtensionService();
3989 InitializeExtensionProcessManager();
3991 // Simple extension that should install without error.
3992 const char* extension_id = "behllobkkfkfnphdnhnkndlbkcpglgmj";
3993 base::FilePath ext = data_dir_
3994 .AppendASCII("good")
3995 .AppendASCII("Extensions")
3996 .AppendASCII(extension_id)
3997 .AppendASCII("1.0.0.0");
3998 extensions::UnpackedInstaller::Create(service_)->Load(ext);
3999 base::RunLoop().RunUntilIdle();
4001 EXPECT_EQ(1u, service_->extensions()->size());
4002 EXPECT_EQ(0u, service_->disabled_extensions()->size());
4004 service_->ReloadExtension(extension_id);
4006 // Extension should be disabled now, waiting to be reloaded.
4007 EXPECT_EQ(0u, service_->extensions()->size());
4008 EXPECT_EQ(1u, service_->disabled_extensions()->size());
4009 EXPECT_EQ(Extension::DISABLE_RELOAD,
4010 service_->extension_prefs()->GetDisableReasons(extension_id));
4012 // Reloading again should not crash.
4013 service_->ReloadExtension(extension_id);
4016 base::RunLoop().RunUntilIdle();
4018 // Extension should be enabled again.
4019 EXPECT_EQ(1u, service_->extensions()->size());
4020 EXPECT_EQ(0u, service_->disabled_extensions()->size());
4023 TEST_F(ExtensionServiceTest, UninstallExtension) {
4024 InitializeEmptyExtensionService();
4025 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
4026 EXPECT_EQ(1u, service_->extensions()->size());
4027 UninstallExtension(good_crx, false);
4028 EXPECT_EQ(0u, service_->extensions()->size());
4031 TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
4032 InitializeEmptyExtensionService();
4033 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
4034 TerminateExtension(good_crx);
4035 UninstallExtension(good_crx, false);
4038 // Tests the uninstaller helper.
4039 TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
4040 InitializeEmptyExtensionService();
4041 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
4042 UninstallExtension(good_crx, true);
4045 TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
4046 InitializeEmptyExtensionService();
4047 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
4048 TerminateExtension(good_crx);
4049 UninstallExtension(good_crx, true);
4052 // An extension disabled because of unsupported requirements should re-enabled
4053 // if updated to a version with supported requirements as long as there are no
4054 // other disable reasons.
4055 TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
4056 InitializeEmptyExtensionService();
4059 base::FilePath path = data_dir_.AppendASCII("requirements");
4060 base::FilePath pem_path = data_dir_.AppendASCII("requirements")
4061 .AppendASCII("v1_good.pem");
4062 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4065 std::string id = extension_v1->id();
4066 EXPECT_TRUE(service_->IsExtensionEnabled(id));
4068 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4070 PackCRX(path.AppendASCII("v2_bad_requirements"),
4072 v2_bad_requirements_crx);
4073 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4074 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4076 base::FilePath v3_good_crx = GetTemporaryFile();
4078 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4079 UpdateExtension(id, v3_good_crx, ENABLED);
4080 EXPECT_TRUE(service_->IsExtensionEnabled(id));
4083 // Extensions disabled through user action should stay disabled.
4084 TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
4085 InitializeEmptyExtensionService();
4088 base::FilePath path = data_dir_.AppendASCII("requirements");
4089 base::FilePath pem_path = data_dir_.AppendASCII("requirements")
4090 .AppendASCII("v1_good.pem");
4091 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4094 std::string id = extension_v1->id();
4095 service_->DisableExtension(id, Extension::DISABLE_USER_ACTION);
4096 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4098 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4100 PackCRX(path.AppendASCII("v2_bad_requirements"),
4102 v2_bad_requirements_crx);
4103 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4104 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4106 base::FilePath v3_good_crx = GetTemporaryFile();
4108 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4109 UpdateExtension(id, v3_good_crx, INSTALLED);
4110 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4113 // The extension should not re-enabled because it was disabled from a
4114 // permission increase.
4115 TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
4116 InitializeEmptyExtensionService();
4119 base::FilePath path = data_dir_.AppendASCII("requirements");
4120 base::FilePath pem_path = data_dir_.AppendASCII("requirements")
4121 .AppendASCII("v1_good.pem");
4122 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4125 std::string id = extension_v1->id();
4126 EXPECT_TRUE(service_->IsExtensionEnabled(id));
4128 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
4130 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
4132 v2_bad_requirements_and_permissions_crx);
4133 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
4134 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4136 base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
4138 PackCRX(path.AppendASCII("v3_bad_permissions"),
4140 v3_bad_permissions_crx);
4141 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
4142 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4145 // Unpacked extensions are not allowed to be installed if they have unsupported
4147 TEST_F(ExtensionServiceTest, UnpackedRequirements) {
4148 InitializeEmptyExtensionService();
4151 base::FilePath path = data_dir_.AppendASCII("requirements")
4152 .AppendASCII("v2_bad_requirements");
4153 extensions::UnpackedInstaller::Create(service_)->Load(path);
4154 base::RunLoop().RunUntilIdle();
4155 EXPECT_EQ(1u, GetErrors().size());
4156 EXPECT_EQ(0u, service_->extensions()->size());
4159 class ExtensionCookieCallback {
4161 ExtensionCookieCallback()
4163 weak_factory_(base::MessageLoop::current()) {}
4165 void SetCookieCallback(bool result) {
4166 base::MessageLoop::current()->PostTask(FROM_HERE,
4167 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4171 void GetAllCookiesCallback(const net::CookieList& list) {
4172 base::MessageLoop::current()->PostTask(FROM_HERE,
4173 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4176 net::CookieList list_;
4178 base::WeakPtrFactory<base::MessageLoop> weak_factory_;
4181 // Verifies extension state is removed upon uninstall.
4182 TEST_F(ExtensionServiceTest, ClearExtensionData) {
4183 InitializeEmptyExtensionService();
4184 ExtensionCookieCallback callback;
4186 // Load a test extension.
4187 base::FilePath path = data_dir_;
4188 path = path.AppendASCII("good.crx");
4189 const Extension* extension = InstallCRX(path, INSTALL_NEW);
4190 ASSERT_TRUE(extension);
4191 GURL ext_url(extension->url());
4192 std::string origin_id = webkit_database::GetIdentifierFromOrigin(ext_url);
4194 // Set a cookie for the extension.
4195 net::CookieMonster* cookie_monster =
4196 profile_->GetRequestContextForExtensions()->GetURLRequestContext()->
4197 cookie_store()->GetCookieMonster();
4198 ASSERT_TRUE(cookie_monster);
4199 net::CookieOptions options;
4200 cookie_monster->SetCookieWithOptionsAsync(
4201 ext_url, "dummy=value", options,
4202 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4203 base::Unretained(&callback)));
4204 base::RunLoop().RunUntilIdle();
4205 EXPECT_TRUE(callback.result_);
4207 cookie_monster->GetAllCookiesForURLAsync(
4209 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4210 base::Unretained(&callback)));
4211 base::RunLoop().RunUntilIdle();
4212 EXPECT_EQ(1U, callback.list_.size());
4215 webkit_database::DatabaseTracker* db_tracker =
4216 BrowserContext::GetDefaultStoragePartition(profile_.get())->
4217 GetDatabaseTracker();
4218 string16 db_name = UTF8ToUTF16("db");
4219 string16 description = UTF8ToUTF16("db_description");
4221 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4222 db_tracker->DatabaseClosed(origin_id, db_name);
4223 std::vector<webkit_database::OriginInfo> origins;
4224 db_tracker->GetAllOriginsInfo(&origins);
4225 EXPECT_EQ(1U, origins.size());
4226 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4228 // Create local storage. We only simulate this by creating the backing files.
4229 // Note: This test depends on details of how the dom_storage library
4230 // stores data in the host file system.
4231 base::FilePath lso_dir_path =
4232 profile_->GetPath().AppendASCII("Local Storage");
4233 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4234 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4235 EXPECT_TRUE(file_util::CreateDirectory(lso_dir_path));
4236 EXPECT_EQ(0, file_util::WriteFile(lso_file_path, NULL, 0));
4237 EXPECT_TRUE(base::PathExists(lso_file_path));
4239 // Create indexed db. Similarly, it is enough to only simulate this by
4240 // creating the directory on the disk.
4241 IndexedDBContext* idb_context =
4242 BrowserContext::GetDefaultStoragePartition(profile_.get())->
4243 GetIndexedDBContext();
4244 idb_context->SetTaskRunnerForTesting(
4245 base::MessageLoop::current()->message_loop_proxy().get());
4246 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4247 EXPECT_TRUE(file_util::CreateDirectory(idb_path));
4248 EXPECT_TRUE(base::DirectoryExists(idb_path));
4250 // Uninstall the extension.
4251 service_->UninstallExtension(good_crx, false, NULL);
4252 base::RunLoop().RunUntilIdle();
4254 // Check that the cookie is gone.
4255 cookie_monster->GetAllCookiesForURLAsync(
4257 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4258 base::Unretained(&callback)));
4259 base::RunLoop().RunUntilIdle();
4260 EXPECT_EQ(0U, callback.list_.size());
4262 // The database should have vanished as well.
4264 db_tracker->GetAllOriginsInfo(&origins);
4265 EXPECT_EQ(0U, origins.size());
4267 // Check that the LSO file has been removed.
4268 EXPECT_FALSE(base::PathExists(lso_file_path));
4270 // Check if the indexed db has disappeared too.
4271 EXPECT_FALSE(base::DirectoryExists(idb_path));
4274 // Verifies app state is removed upon uninstall.
4275 TEST_F(ExtensionServiceTest, ClearAppData) {
4276 InitializeEmptyExtensionService();
4277 ExtensionCookieCallback callback;
4281 // Install app1 with unlimited storage.
4282 const Extension* extension =
4283 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
4284 ValidatePrefKeyCount(++pref_count);
4285 ASSERT_EQ(1u, service_->extensions()->size());
4286 const std::string id1 = extension->id();
4287 EXPECT_TRUE(extension->HasAPIPermission(
4288 APIPermission::kUnlimitedStorage));
4290 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4291 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
4292 IsStorageUnlimited(origin1));
4293 std::string origin_id = webkit_database::GetIdentifierFromOrigin(origin1);
4295 // Install app2 from the same origin with unlimited storage.
4296 extension = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
4297 ValidatePrefKeyCount(++pref_count);
4298 ASSERT_EQ(2u, service_->extensions()->size());
4299 const std::string id2 = extension->id();
4300 EXPECT_TRUE(extension->HasAPIPermission(
4301 APIPermission::kUnlimitedStorage));
4302 EXPECT_TRUE(extension->web_extent().MatchesURL(
4303 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
4305 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4306 EXPECT_EQ(origin1, origin2);
4307 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
4308 IsStorageUnlimited(origin2));
4310 // Set a cookie for the extension.
4311 net::CookieMonster* cookie_monster =
4312 profile_->GetRequestContext()->GetURLRequestContext()->
4313 cookie_store()->GetCookieMonster();
4314 ASSERT_TRUE(cookie_monster);
4315 net::CookieOptions options;
4316 cookie_monster->SetCookieWithOptionsAsync(
4317 origin1, "dummy=value", options,
4318 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4319 base::Unretained(&callback)));
4320 base::RunLoop().RunUntilIdle();
4321 EXPECT_TRUE(callback.result_);
4323 cookie_monster->GetAllCookiesForURLAsync(
4325 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4326 base::Unretained(&callback)));
4327 base::RunLoop().RunUntilIdle();
4328 EXPECT_EQ(1U, callback.list_.size());
4331 webkit_database::DatabaseTracker* db_tracker =
4332 BrowserContext::GetDefaultStoragePartition(profile_.get())->
4333 GetDatabaseTracker();
4334 string16 db_name = UTF8ToUTF16("db");
4335 string16 description = UTF8ToUTF16("db_description");
4337 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4338 db_tracker->DatabaseClosed(origin_id, db_name);
4339 std::vector<webkit_database::OriginInfo> origins;
4340 db_tracker->GetAllOriginsInfo(&origins);
4341 EXPECT_EQ(1U, origins.size());
4342 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4344 // Create local storage. We only simulate this by creating the backing files.
4345 // Note: This test depends on details of how the dom_storage library
4346 // stores data in the host file system.
4347 base::FilePath lso_dir_path =
4348 profile_->GetPath().AppendASCII("Local Storage");
4349 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4350 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4351 EXPECT_TRUE(file_util::CreateDirectory(lso_dir_path));
4352 EXPECT_EQ(0, file_util::WriteFile(lso_file_path, NULL, 0));
4353 EXPECT_TRUE(base::PathExists(lso_file_path));
4355 // Create indexed db. Similarly, it is enough to only simulate this by
4356 // creating the directory on the disk.
4357 IndexedDBContext* idb_context =
4358 BrowserContext::GetDefaultStoragePartition(profile_.get())->
4359 GetIndexedDBContext();
4360 idb_context->SetTaskRunnerForTesting(
4361 base::MessageLoop::current()->message_loop_proxy().get());
4362 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4363 EXPECT_TRUE(file_util::CreateDirectory(idb_path));
4364 EXPECT_TRUE(base::DirectoryExists(idb_path));
4366 // Uninstall one of them, unlimited storage should still be granted
4368 UninstallExtension(id1, false);
4369 EXPECT_EQ(1u, service_->extensions()->size());
4370 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
4371 IsStorageUnlimited(origin1));
4373 // Check that the cookie is still there.
4374 cookie_monster->GetAllCookiesForURLAsync(
4376 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4377 base::Unretained(&callback)));
4378 base::RunLoop().RunUntilIdle();
4379 EXPECT_EQ(1U, callback.list_.size());
4381 // Now uninstall the other. Storage should be cleared for the apps.
4382 UninstallExtension(id2, false);
4383 EXPECT_EQ(0u, service_->extensions()->size());
4384 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
4385 IsStorageUnlimited(origin1));
4387 // Check that the cookie is gone.
4388 cookie_monster->GetAllCookiesForURLAsync(
4390 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4391 base::Unretained(&callback)));
4392 base::RunLoop().RunUntilIdle();
4393 EXPECT_EQ(0U, callback.list_.size());
4395 // The database should have vanished as well.
4397 db_tracker->GetAllOriginsInfo(&origins);
4398 EXPECT_EQ(0U, origins.size());
4400 // Check that the LSO file has been removed.
4401 EXPECT_FALSE(base::PathExists(lso_file_path));
4403 // Check if the indexed db has disappeared too.
4404 EXPECT_FALSE(base::DirectoryExists(idb_path));
4407 // Tests loading single extensions (like --load-extension)
4408 // Flaky crashes. http://crbug.com/231806
4409 TEST_F(ExtensionServiceTest, DISABLED_LoadExtension) {
4410 InitializeEmptyExtensionService();
4412 base::FilePath ext1 = data_dir_
4413 .AppendASCII("good")
4414 .AppendASCII("Extensions")
4415 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4416 .AppendASCII("1.0.0.0");
4417 extensions::UnpackedInstaller::Create(service_)->Load(ext1);
4418 base::RunLoop().RunUntilIdle();
4419 EXPECT_EQ(0u, GetErrors().size());
4420 ASSERT_EQ(1u, loaded_.size());
4421 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
4422 EXPECT_EQ(1u, service_->extensions()->size());
4424 ValidatePrefKeyCount(1);
4426 base::FilePath no_manifest = data_dir_
4428 // .AppendASCII("Extensions")
4429 .AppendASCII("cccccccccccccccccccccccccccccccc")
4431 extensions::UnpackedInstaller::Create(service_)->Load(no_manifest);
4432 base::RunLoop().RunUntilIdle();
4433 EXPECT_EQ(1u, GetErrors().size());
4434 ASSERT_EQ(1u, loaded_.size());
4435 EXPECT_EQ(1u, service_->extensions()->size());
4438 std::string id = loaded_[0]->id();
4439 EXPECT_FALSE(unloaded_id_.length());
4440 service_->UninstallExtension(id, false, NULL);
4441 base::RunLoop().RunUntilIdle();
4442 EXPECT_EQ(id, unloaded_id_);
4443 ASSERT_EQ(0u, loaded_.size());
4444 EXPECT_EQ(0u, service_->extensions()->size());
4447 // Tests that we generate IDs when they are not specified in the manifest for
4448 // --load-extension.
4449 TEST_F(ExtensionServiceTest, GenerateID) {
4450 InitializeEmptyExtensionService();
4452 base::FilePath no_id_ext = data_dir_.AppendASCII("no_id");
4453 extensions::UnpackedInstaller::Create(service_)->Load(no_id_ext);
4454 base::RunLoop().RunUntilIdle();
4455 EXPECT_EQ(0u, GetErrors().size());
4456 ASSERT_EQ(1u, loaded_.size());
4457 ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id()));
4458 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
4460 ValidatePrefKeyCount(1);
4462 std::string previous_id = loaded_[0]->id();
4464 // If we reload the same path, we should get the same extension ID.
4465 extensions::UnpackedInstaller::Create(service_)->Load(no_id_ext);
4466 base::RunLoop().RunUntilIdle();
4467 ASSERT_EQ(1u, loaded_.size());
4468 ASSERT_EQ(previous_id, loaded_[0]->id());
4471 TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
4472 InitializeEmptyExtensionService();
4474 base::FilePath bad_locale = data_dir_.AppendASCII("unpacked").
4475 AppendASCII("bad_messages_file");
4476 extensions::UnpackedInstaller::Create(service_)->Load(bad_locale);
4477 base::RunLoop().RunUntilIdle();
4478 EXPECT_EQ(1u, GetErrors().size());
4479 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
4481 .AppendASCII("messages.json");
4482 EXPECT_THAT(UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
4483 testing::HasSubstr(UTF16ToUTF8(ms_messages_file.LossyDisplayName())),
4484 testing::HasSubstr("Dictionary keys must be quoted.")));
4485 ASSERT_EQ(0u, loaded_.size());
4488 void ExtensionServiceTest::TestExternalProvider(
4489 MockExtensionProvider* provider, Manifest::Location location) {
4490 // Verify that starting with no providers loads no extensions.
4492 ASSERT_EQ(0u, loaded_.size());
4494 provider->set_visit_count(0);
4496 // Register a test extension externally using the mock registry provider.
4497 base::FilePath source_path = data_dir_.AppendASCII("good.crx");
4499 // Add the extension.
4500 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
4502 // Reloading extensions should find our externally registered extension
4504 service_->CheckForExternalUpdates();
4505 content::WindowedNotificationObserver(
4506 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
4507 content::NotificationService::AllSources()).Wait();
4509 ASSERT_EQ(0u, GetErrors().size());
4510 ASSERT_EQ(1u, loaded_.size());
4511 ASSERT_EQ(location, loaded_[0]->location());
4512 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
4513 ValidatePrefKeyCount(1);
4514 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4515 ValidateIntegerPref(good_crx, "location", location);
4517 // Reload extensions without changing anything. The extension should be
4520 service_->ReloadExtensions();
4521 base::RunLoop().RunUntilIdle();
4522 ASSERT_EQ(0u, GetErrors().size());
4523 ASSERT_EQ(1u, loaded_.size());
4524 ValidatePrefKeyCount(1);
4525 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4526 ValidateIntegerPref(good_crx, "location", location);
4528 // Now update the extension with a new version. We should get upgraded.
4529 source_path = source_path.DirName().AppendASCII("good2.crx");
4530 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
4533 service_->CheckForExternalUpdates();
4534 content::WindowedNotificationObserver(
4535 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
4536 content::NotificationService::AllSources()).Wait();
4537 ASSERT_EQ(0u, GetErrors().size());
4538 ASSERT_EQ(1u, loaded_.size());
4539 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
4540 ValidatePrefKeyCount(1);
4541 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4542 ValidateIntegerPref(good_crx, "location", location);
4544 // Uninstall the extension and reload. Nothing should happen because the
4545 // preference should prevent us from reinstalling.
4546 std::string id = loaded_[0]->id();
4548 management_policy_->MustRemainEnabled(loaded_[0].get(), NULL);
4549 service_->UninstallExtension(id, false, NULL);
4550 base::RunLoop().RunUntilIdle();
4552 base::FilePath install_path = extensions_install_dir_.AppendASCII(id);
4554 // Policy controlled extensions should not have been touched by uninstall.
4555 ASSERT_TRUE(base::PathExists(install_path));
4557 // The extension should also be gone from the install directory.
4558 ASSERT_FALSE(base::PathExists(install_path));
4560 service_->CheckForExternalUpdates();
4561 base::RunLoop().RunUntilIdle();
4562 ASSERT_EQ(0u, loaded_.size());
4563 ValidatePrefKeyCount(1);
4564 ValidateIntegerPref(good_crx, "state",
4565 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
4566 ValidateIntegerPref(good_crx, "location", location);
4568 // Now clear the preference and reinstall.
4569 SetPrefInteg(good_crx, "state", Extension::ENABLED);
4572 service_->CheckForExternalUpdates();
4573 content::WindowedNotificationObserver(
4574 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
4575 content::NotificationService::AllSources()).Wait();
4576 ASSERT_EQ(1u, loaded_.size());
4578 ValidatePrefKeyCount(1);
4579 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4580 ValidateIntegerPref(good_crx, "location", location);
4582 if (management_policy_->MustRemainEnabled(loaded_[0].get(), NULL)) {
4583 EXPECT_EQ(2, provider->visit_count());
4585 // Now test an externally triggered uninstall (deleting the registry key or
4587 provider->RemoveExtension(good_crx);
4590 service_->OnExternalProviderReady(provider);
4591 base::RunLoop().RunUntilIdle();
4592 ASSERT_EQ(0u, loaded_.size());
4593 ValidatePrefKeyCount(0);
4595 // The extension should also be gone from the install directory.
4596 ASSERT_FALSE(base::PathExists(install_path));
4598 // Now test the case where user uninstalls and then the extension is removed
4599 // from the external provider.
4600 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
4601 service_->CheckForExternalUpdates();
4602 content::WindowedNotificationObserver(
4603 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
4604 content::NotificationService::AllSources()).Wait();
4606 ASSERT_EQ(1u, loaded_.size());
4607 ASSERT_EQ(0u, GetErrors().size());
4611 service_->UninstallExtension(id, false, NULL);
4612 base::RunLoop().RunUntilIdle();
4613 ASSERT_EQ(0u, loaded_.size());
4615 // Then remove the extension from the extension provider.
4616 provider->RemoveExtension(good_crx);
4618 // Should still be at 0.
4620 extensions::InstalledLoader(service_).LoadAllExtensions();
4621 base::RunLoop().RunUntilIdle();
4622 ASSERT_EQ(0u, loaded_.size());
4623 ValidatePrefKeyCount(1);
4625 EXPECT_EQ(5, provider->visit_count());
4629 // Tests the external installation feature
4631 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
4632 // This should all work, even when normal extension installation is disabled.
4633 InitializeEmptyExtensionService();
4634 set_extensions_enabled(false);
4636 // Now add providers. Extension system takes ownership of the objects.
4637 MockExtensionProvider* reg_provider =
4638 new MockExtensionProvider(service_, Manifest::EXTERNAL_REGISTRY);
4639 AddMockExternalProvider(reg_provider);
4640 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
4644 TEST_F(ExtensionServiceTest, ExternalInstallPref) {
4645 InitializeEmptyExtensionService();
4647 // Now add providers. Extension system takes ownership of the objects.
4648 MockExtensionProvider* pref_provider =
4649 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
4651 AddMockExternalProvider(pref_provider);
4652 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
4655 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
4656 // This should all work, even when normal extension installation is disabled.
4657 InitializeEmptyExtensionService();
4658 set_extensions_enabled(false);
4660 // TODO(skerner): The mock provider is not a good model of a provider
4661 // that works with update URLs, because it adds file and version info.
4662 // Extend the mock to work with update URLs. This test checks the
4663 // behavior that is common to all external extension visitors. The
4664 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4665 // what the visitor does results in an extension being downloaded and
4667 MockExtensionProvider* pref_provider =
4668 new MockExtensionProvider(service_,
4669 Manifest::EXTERNAL_PREF_DOWNLOAD);
4670 AddMockExternalProvider(pref_provider);
4671 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
4674 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
4675 // This should all work, even when normal extension installation is disabled.
4676 InitializeEmptyExtensionService();
4677 set_extensions_enabled(false);
4679 // TODO(skerner): The mock provider is not a good model of a provider
4680 // that works with update URLs, because it adds file and version info.
4681 // Extend the mock to work with update URLs. This test checks the
4682 // behavior that is common to all external extension visitors. The
4683 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4684 // what the visitor does results in an extension being downloaded and
4686 MockExtensionProvider* pref_provider =
4687 new MockExtensionProvider(service_,
4688 Manifest::EXTERNAL_POLICY_DOWNLOAD);
4689 AddMockExternalProvider(pref_provider);
4690 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
4693 // Tests that external extensions get uninstalled when the external extension
4694 // providers can't account for them.
4695 TEST_F(ExtensionServiceTest, ExternalUninstall) {
4696 // Start the extensions service with one external extension already installed.
4697 base::FilePath source_install_dir = data_dir_
4698 .AppendASCII("good")
4699 .AppendASCII("Extensions");
4700 base::FilePath pref_path = source_install_dir
4702 .AppendASCII("PreferencesExternal");
4704 // This initializes the extensions service with no ExternalProviders.
4705 InitializeInstalledExtensionService(pref_path, source_install_dir);
4706 set_extensions_enabled(false);
4710 ASSERT_EQ(0u, GetErrors().size());
4711 ASSERT_EQ(0u, loaded_.size());
4713 // Verify that it's not the disabled extensions flag causing it not to load.
4714 set_extensions_enabled(true);
4715 service_->ReloadExtensions();
4716 base::RunLoop().RunUntilIdle();
4718 ASSERT_EQ(0u, GetErrors().size());
4719 ASSERT_EQ(0u, loaded_.size());
4722 // Test that running multiple update checks simultaneously does not
4723 // keep the update from succeeding.
4724 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
4725 InitializeEmptyExtensionService();
4727 MockExtensionProvider* provider =
4728 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
4729 AddMockExternalProvider(provider);
4731 // Verify that starting with no providers loads no extensions.
4733 ASSERT_EQ(0u, loaded_.size());
4735 // Start two checks for updates.
4736 provider->set_visit_count(0);
4737 service_->CheckForExternalUpdates();
4738 service_->CheckForExternalUpdates();
4739 base::RunLoop().RunUntilIdle();
4741 // Two calls should cause two checks for external extensions.
4742 EXPECT_EQ(2, provider->visit_count());
4743 EXPECT_EQ(0u, GetErrors().size());
4744 EXPECT_EQ(0u, loaded_.size());
4746 // Register a test extension externally using the mock registry provider.
4747 base::FilePath source_path = data_dir_.AppendASCII("good.crx");
4748 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
4750 // Two checks for external updates should find the extension, and install it
4752 provider->set_visit_count(0);
4753 service_->CheckForExternalUpdates();
4754 service_->CheckForExternalUpdates();
4755 content::WindowedNotificationObserver(
4756 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
4757 content::NotificationService::AllSources()).Wait();
4758 EXPECT_EQ(2, provider->visit_count());
4759 ASSERT_EQ(0u, GetErrors().size());
4760 ASSERT_EQ(1u, loaded_.size());
4761 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
4762 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
4763 ValidatePrefKeyCount(1);
4764 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4765 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
4767 provider->RemoveExtension(good_crx);
4768 provider->set_visit_count(0);
4769 service_->CheckForExternalUpdates();
4770 service_->CheckForExternalUpdates();
4771 base::RunLoop().RunUntilIdle();
4773 // Two calls should cause two checks for external extensions.
4774 // Because the external source no longer includes good_crx,
4775 // good_crx will be uninstalled. So, expect that no extensions
4777 EXPECT_EQ(2, provider->visit_count());
4778 EXPECT_EQ(0u, GetErrors().size());
4779 EXPECT_EQ(0u, loaded_.size());
4782 TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
4783 InitializeEmptyExtensionService();
4785 // Test some valid extension records.
4786 // Set a base path to avoid erroring out on relative paths.
4787 // Paths starting with // are absolute on every platform we support.
4788 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
4789 ASSERT_TRUE(base_path.IsAbsolute());
4790 MockProviderVisitor visitor(base_path);
4791 std::string json_data =
4793 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4794 " \"external_crx\": \"RandomExtension.crx\","
4795 " \"external_version\": \"1.0\""
4797 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4798 " \"external_crx\": \"RandomExtension2.crx\","
4799 " \"external_version\": \"2.0\""
4801 " \"cccccccccccccccccccccccccccccccc\": {"
4802 " \"external_update_url\": \"http:\\\\foo.com/update\""
4805 EXPECT_EQ(3, visitor.Visit(json_data));
4807 // Simulate an external_extensions.json file that contains seven invalid
4809 // - One that is missing the 'external_crx' key.
4810 // - One that is missing the 'external_version' key.
4811 // - One that is specifying .. in the path.
4812 // - One that specifies both a file and update URL.
4813 // - One that specifies no file or update URL.
4814 // - One that has an update URL that is not well formed.
4815 // - One that contains a malformed version.
4816 // - One that has an invalid id.
4817 // - One that has a non-dictionary value.
4818 // - One that has an integer 'external_version' instead of a string.
4819 // The final extension is valid, and we check that it is read to make sure
4820 // failures don't stop valid records from being read.
4823 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4824 " \"external_version\": \"1.0\""
4826 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4827 " \"external_crx\": \"RandomExtension.crx\""
4829 " \"cccccccccccccccccccccccccccccccc\": {"
4830 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
4831 " \"external_version\": \"2.0\""
4833 " \"dddddddddddddddddddddddddddddddd\": {"
4834 " \"external_crx\": \"RandomExtension2.crx\","
4835 " \"external_version\": \"2.0\","
4836 " \"external_update_url\": \"http:\\\\foo.com/update\""
4838 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
4840 " \"ffffffffffffffffffffffffffffffff\": {"
4841 " \"external_update_url\": \"This string is not a valid URL\""
4843 " \"gggggggggggggggggggggggggggggggg\": {"
4844 " \"external_crx\": \"RandomExtension3.crx\","
4845 " \"external_version\": \"This is not a valid version!\""
4847 " \"This is not a valid id!\": {},"
4848 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
4849 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
4850 " \"external_crx\": \"RandomExtension4.crx\","
4851 " \"external_version\": 1.0"
4853 " \"pppppppppppppppppppppppppppppppp\": {"
4854 " \"external_crx\": \"RandomValidExtension.crx\","
4855 " \"external_version\": \"1.0\""
4858 EXPECT_EQ(1, visitor.Visit(json_data));
4860 // Check that if a base path is not provided, use of a relative
4862 base::FilePath empty;
4863 MockProviderVisitor visitor_no_relative_paths(empty);
4865 // Use absolute paths. Expect success.
4868 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4869 " \"external_crx\": \"//RandomExtension1.crx\","
4870 " \"external_version\": \"3.0\""
4872 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4873 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
4874 " \"external_version\": \"3.0\""
4877 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
4879 // Use a relative path. Expect that it will error out.
4882 " \"cccccccccccccccccccccccccccccccc\": {"
4883 " \"external_crx\": \"RandomExtension2.crx\","
4884 " \"external_version\": \"3.0\""
4887 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
4889 // Test supported_locales.
4892 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4893 " \"external_crx\": \"RandomExtension.crx\","
4894 " \"external_version\": \"1.0\","
4895 " \"supported_locales\": [ \"en\" ]"
4897 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4898 " \"external_crx\": \"RandomExtension2.crx\","
4899 " \"external_version\": \"2.0\","
4900 " \"supported_locales\": [ \"en-GB\" ]"
4902 " \"cccccccccccccccccccccccccccccccc\": {"
4903 " \"external_crx\": \"RandomExtension2.crx\","
4904 " \"external_version\": \"3.0\","
4905 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
4909 ScopedBrowserLocale guard("en-US");
4910 EXPECT_EQ(2, visitor.Visit(json_data));
4913 // Test keep_if_present.
4916 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4917 " \"external_crx\": \"RandomExtension.crx\","
4918 " \"external_version\": \"1.0\","
4919 " \"keep_if_present\": true"
4923 EXPECT_EQ(0, visitor.Visit(json_data));
4926 // Test is_bookmark_app.
4927 MockProviderVisitor from_bookmark_visitor(
4928 base_path, Extension::FROM_BOOKMARK);
4931 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4932 " \"external_crx\": \"RandomExtension.crx\","
4933 " \"external_version\": \"1.0\","
4934 " \"is_bookmark_app\": true"
4937 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
4939 // Test is_from_webstore.
4940 MockProviderVisitor from_webstore_visitor(
4941 base_path, Extension::FROM_WEBSTORE);
4944 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4945 " \"external_crx\": \"RandomExtension.crx\","
4946 " \"external_version\": \"1.0\","
4947 " \"is_from_webstore\": true"
4950 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
4953 // Test loading good extensions from the profile directory.
4954 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
4955 // Ensure we're testing in "en" and leave global state untouched.
4956 extension_l10n_util::ScopedLocaleForTest testLocale("en");
4958 // Initialize the test dir with a good Preferences/extensions.
4959 base::FilePath source_install_dir = data_dir_
4960 .AppendASCII("l10n");
4961 base::FilePath pref_path = source_install_dir.AppendASCII("Preferences");
4962 InitializeInstalledExtensionService(pref_path, source_install_dir);
4966 ASSERT_EQ(3u, loaded_.size());
4968 // This was equal to "sr" on load.
4969 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
4971 // These are untouched by re-localization.
4972 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
4973 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
4975 // This one starts with Serbian name, and gets re-localized into English.
4976 EXPECT_EQ("My name is simple.", loaded_[0]->name());
4978 // These are untouched by re-localization.
4979 EXPECT_EQ("My name is simple.", loaded_[1]->name());
4980 EXPECT_EQ("no l10n", loaded_[2]->name());
4983 class ExtensionsReadyRecorder : public content::NotificationObserver {
4985 ExtensionsReadyRecorder() : ready_(false) {
4986 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
4987 content::NotificationService::AllSources());
4990 void set_ready(bool value) { ready_ = value; }
4991 bool ready() { return ready_; }
4994 virtual void Observe(int type,
4995 const content::NotificationSource& source,
4996 const content::NotificationDetails& details) OVERRIDE {
4998 case chrome::NOTIFICATION_EXTENSIONS_READY:
5006 content::NotificationRegistrar registrar_;
5010 // Test that we get enabled/disabled correctly for all the pref/command-line
5011 // combinations. We don't want to derive from the ExtensionServiceTest class
5012 // for this test, so we use ExtensionServiceTestSimple.
5014 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
5016 TEST(ExtensionServiceTestSimple, Enabledness) {
5017 // Make sure the PluginService singleton is destroyed at the end of the test.
5018 base::ShadowingAtExitManager at_exit_manager;
5019 #if defined(ENABLE_PLUGINS)
5020 content::PluginService::GetInstance()->Init();
5021 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
5024 ExtensionErrorReporter::Init(false); // no noisy errors
5025 ExtensionsReadyRecorder recorder;
5026 scoped_ptr<TestingProfile> profile(new TestingProfile());
5027 content::TestBrowserThreadBundle thread_bundle_;
5028 #if defined OS_CHROMEOS
5029 chromeos::ScopedTestDeviceSettingsService device_settings_service;
5030 chromeos::ScopedTestCrosSettings cros_settings;
5031 scoped_ptr<chromeos::ScopedTestUserManager> user_manager(
5032 new chromeos::ScopedTestUserManager);
5034 scoped_ptr<CommandLine> command_line;
5035 base::FilePath install_dir = profile->GetPath()
5036 .AppendASCII(extensions::kInstallDirectoryName);
5038 // By default, we are enabled.
5039 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
5040 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
5041 ExtensionSystem::Get(profile.get()))->
5042 CreateExtensionService(
5046 EXPECT_TRUE(service->extensions_enabled());
5048 base::RunLoop().RunUntilIdle();
5049 EXPECT_TRUE(recorder.ready());
5050 #if defined OS_CHROMEOS
5051 user_manager.reset();
5054 // If either the command line or pref is set, we are disabled.
5055 recorder.set_ready(false);
5056 profile.reset(new TestingProfile());
5057 command_line->AppendSwitch(switches::kDisableExtensions);
5058 service = static_cast<extensions::TestExtensionSystem*>(
5059 ExtensionSystem::Get(profile.get()))->
5060 CreateExtensionService(
5064 EXPECT_FALSE(service->extensions_enabled());
5066 base::RunLoop().RunUntilIdle();
5067 EXPECT_TRUE(recorder.ready());
5069 recorder.set_ready(false);
5070 profile.reset(new TestingProfile());
5071 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5072 service = static_cast<extensions::TestExtensionSystem*>(
5073 ExtensionSystem::Get(profile.get()))->
5074 CreateExtensionService(
5078 EXPECT_FALSE(service->extensions_enabled());
5080 base::RunLoop().RunUntilIdle();
5081 EXPECT_TRUE(recorder.ready());
5083 recorder.set_ready(false);
5084 profile.reset(new TestingProfile());
5085 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5086 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
5087 service = static_cast<extensions::TestExtensionSystem*>(
5088 ExtensionSystem::Get(profile.get()))->
5089 CreateExtensionService(
5093 EXPECT_FALSE(service->extensions_enabled());
5095 base::RunLoop().RunUntilIdle();
5096 EXPECT_TRUE(recorder.ready());
5098 // Explicitly delete all the resources used in this test.
5101 // Execute any pending deletion tasks.
5102 base::RunLoop().RunUntilIdle();
5105 // Test loading extensions that require limited and unlimited storage quotas.
5106 TEST_F(ExtensionServiceTest, StorageQuota) {
5107 InitializeEmptyExtensionService();
5109 base::FilePath extensions_path = data_dir_
5110 .AppendASCII("storage_quota");
5112 base::FilePath limited_quota_ext =
5113 extensions_path.AppendASCII("limited_quota")
5114 .AppendASCII("1.0");
5116 // The old permission name for unlimited quota was "unlimited_storage", but
5117 // we changed it to "unlimitedStorage". This tests both versions.
5118 base::FilePath unlimited_quota_ext =
5119 extensions_path.AppendASCII("unlimited_quota")
5120 .AppendASCII("1.0");
5121 base::FilePath unlimited_quota_ext2 =
5122 extensions_path.AppendASCII("unlimited_quota")
5123 .AppendASCII("2.0");
5124 extensions::UnpackedInstaller::Create(service_)->Load(limited_quota_ext);
5125 extensions::UnpackedInstaller::Create(service_)->Load(unlimited_quota_ext);
5126 extensions::UnpackedInstaller::Create(service_)->Load(unlimited_quota_ext2);
5127 base::RunLoop().RunUntilIdle();
5129 ASSERT_EQ(3u, loaded_.size());
5130 EXPECT_TRUE(profile_.get());
5131 EXPECT_FALSE(profile_->IsOffTheRecord());
5132 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5133 loaded_[0]->url()));
5134 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5135 loaded_[1]->url()));
5136 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5137 loaded_[2]->url()));
5140 // Tests ComponentLoader::Add().
5141 TEST_F(ExtensionServiceTest, ComponentExtensions) {
5142 InitializeEmptyExtensionService();
5144 // Component extensions should work even when extensions are disabled.
5145 set_extensions_enabled(false);
5147 base::FilePath path = data_dir_
5148 .AppendASCII("good")
5149 .AppendASCII("Extensions")
5150 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
5151 .AppendASCII("1.0.0.0");
5153 std::string manifest;
5154 ASSERT_TRUE(base::ReadFileToString(
5155 path.Append(extensions::kManifestFilename), &manifest));
5157 service_->component_loader()->Add(manifest, path);
5160 // Note that we do not pump messages -- the extension should be loaded
5163 EXPECT_EQ(0u, GetErrors().size());
5164 ASSERT_EQ(1u, loaded_.size());
5165 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
5166 EXPECT_EQ(1u, service_->extensions()->size());
5168 // Component extensions get a prefs entry on first install.
5169 ValidatePrefKeyCount(1);
5171 // Reload all extensions, and make sure it comes back.
5172 std::string extension_id = (*service_->extensions()->begin())->id();
5174 service_->ReloadExtensions();
5175 ASSERT_EQ(1u, service_->extensions()->size());
5176 EXPECT_EQ(extension_id, (*service_->extensions()->begin())->id());
5181 class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
5182 virtual syncer::SyncError ProcessSyncChanges(
5183 const tracked_objects::Location& from_here,
5184 const syncer::SyncChangeList& change_list) OVERRIDE {
5185 return syncer::SyncError();
5188 virtual syncer::SyncDataList GetAllSyncData(
5189 syncer::ModelType type) const OVERRIDE {
5190 return syncer::SyncDataList();
5196 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
5197 InitializeEmptyExtensionService();
5198 InitializeExtensionSyncService();
5200 bool flare_was_called = false;
5201 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5202 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5203 extension_sync_service_->SetSyncStartFlare(
5204 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5205 factory.GetWeakPtr(),
5206 &flare_was_called, // Safe due to WeakPtrFactory scope.
5207 &triggered_type)); // Safe due to WeakPtrFactory scope.
5209 // Install a component extension.
5210 std::string manifest;
5211 ASSERT_TRUE(base::ReadFileToString(
5212 good0_path().Append(extensions::kManifestFilename), &manifest));
5213 service_->component_loader()->Add(manifest, good0_path());
5214 ASSERT_FALSE(service_->is_ready());
5216 ASSERT_TRUE(service_->is_ready());
5218 // Extensions added before service is_ready() don't trigger sync startup.
5219 EXPECT_FALSE(flare_was_called);
5220 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5223 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
5224 InitializeGoodInstalledExtensionService();
5225 InitializeExtensionSyncService();
5227 bool flare_was_called = false;
5228 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5229 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5230 extension_sync_service_->SetSyncStartFlare(
5231 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5232 factory.GetWeakPtr(),
5233 &flare_was_called, // Safe due to WeakPtrFactory scope.
5234 &triggered_type)); // Safe due to WeakPtrFactory scope.
5236 ASSERT_FALSE(service_->is_ready());
5238 ASSERT_EQ(3u, loaded_.size());
5239 ASSERT_TRUE(service_->is_ready());
5241 // Extensions added before service is_ready() don't trigger sync startup.
5242 EXPECT_FALSE(flare_was_called);
5243 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5246 TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
5247 InitializeEmptyExtensionService();
5248 InitializeExtensionSyncService();
5250 ASSERT_TRUE(service_->is_ready());
5252 bool flare_was_called = false;
5253 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5254 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5255 extension_sync_service_->SetSyncStartFlare(
5256 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5257 factory.GetWeakPtr(),
5258 &flare_was_called, // Safe due to WeakPtrFactory scope.
5259 &triggered_type)); // Safe due to WeakPtrFactory scope.
5261 base::FilePath path = data_dir_.AppendASCII("good.crx");
5262 InstallCRX(path, INSTALL_NEW);
5264 EXPECT_TRUE(flare_was_called);
5265 EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
5268 flare_was_called = false;
5269 triggered_type = syncer::UNSPECIFIED;
5271 // Once sync starts, flare should no longer be invoked.
5272 extension_sync_service_->MergeDataAndStartSyncing(
5273 syncer::EXTENSIONS, syncer::SyncDataList(),
5274 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5275 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5276 path = data_dir_.AppendASCII("page_action.crx");
5277 InstallCRX(path, INSTALL_NEW);
5278 EXPECT_FALSE(flare_was_called);
5279 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5282 TEST_F(ExtensionServiceTest, DisableExtensionFromSync) {
5283 // Start the extensions service with one external extension already installed.
5284 base::FilePath source_install_dir = data_dir_
5285 .AppendASCII("good")
5286 .AppendASCII("Extensions");
5287 base::FilePath pref_path = source_install_dir
5289 .AppendASCII("Preferences");
5291 InitializeInstalledExtensionService(pref_path, source_install_dir);
5292 InitializeExtensionSyncService();
5294 // The user has enabled sync.
5295 ProfileSyncService* sync_service =
5296 ProfileSyncServiceFactory::GetForProfile(profile_.get());
5297 sync_service->SetSyncSetupCompleted();
5300 ASSERT_TRUE(service_->is_ready());
5302 ASSERT_EQ(3u, loaded_.size());
5304 // We start enabled.
5305 const Extension* extension = service_->GetExtensionById(good0, true);
5306 ASSERT_TRUE(extension);
5307 ASSERT_TRUE(service_->IsExtensionEnabled(good0));
5308 extensions::ExtensionSyncData disable_good_crx(*extension, false, false);
5310 // Then sync data arrives telling us to disable |good0|.
5311 syncer::SyncDataList sync_data;
5312 sync_data.push_back(disable_good_crx.GetSyncData());
5313 extension_sync_service_->MergeDataAndStartSyncing(
5314 syncer::EXTENSIONS, sync_data,
5315 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5316 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5317 ASSERT_FALSE(service_->IsExtensionEnabled(good0));
5320 TEST_F(ExtensionServiceTest, DontDisableExtensionWithPendingEnableFromSync) {
5321 // Start the extensions service with one external extension already installed.
5322 base::FilePath source_install_dir = data_dir_
5323 .AppendASCII("good")
5324 .AppendASCII("Extensions");
5325 base::FilePath pref_path = source_install_dir
5327 .AppendASCII("Preferences");
5329 InitializeInstalledExtensionService(pref_path, source_install_dir);
5330 InitializeExtensionSyncService();
5332 // The user has enabled sync.
5333 ProfileSyncService* sync_service =
5334 ProfileSyncServiceFactory::GetForProfile(profile_.get());
5335 sync_service->SetSyncSetupCompleted();
5338 ASSERT_TRUE(service_->is_ready());
5339 ASSERT_EQ(3u, loaded_.size());
5341 const Extension* extension = service_->GetExtensionById(good0, true);
5342 ASSERT_TRUE(service_->IsExtensionEnabled(good0));
5344 // Disable extension before first sync data arrives.
5345 service_->DisableExtension(good0, Extension::DISABLE_USER_ACTION);
5346 ASSERT_FALSE(service_->IsExtensionEnabled(good0));
5348 // Enable extension - this is now the most recent state.
5349 service_->EnableExtension(good0);
5350 ASSERT_TRUE(service_->IsExtensionEnabled(good0));
5352 // Now sync data comes in that says to disable good0. This should be
5354 extensions::ExtensionSyncData disable_good_crx(*extension, false, false);
5355 syncer::SyncDataList sync_data;
5356 sync_data.push_back(disable_good_crx.GetSyncData());
5357 extension_sync_service_->MergeDataAndStartSyncing(
5358 syncer::EXTENSIONS, sync_data,
5359 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5360 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5362 // The extension was enabled locally before the sync data arrived, so it
5363 // should still be enabled now.
5364 ASSERT_TRUE(service_->IsExtensionEnabled(good0));
5367 TEST_F(ExtensionServiceTest, GetSyncData) {
5368 InitializeEmptyExtensionService();
5369 InitializeExtensionSyncService();
5370 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5371 const Extension* extension = service_->GetInstalledExtension(good_crx);
5372 ASSERT_TRUE(extension);
5374 extension_sync_service_->MergeDataAndStartSyncing(
5375 syncer::EXTENSIONS, syncer::SyncDataList(),
5376 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5377 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5379 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5380 syncer::EXTENSIONS);
5381 ASSERT_EQ(list.size(), 1U);
5382 extensions::ExtensionSyncData data(list[0]);
5383 EXPECT_EQ(extension->id(), data.id());
5384 EXPECT_FALSE(data.uninstalled());
5385 EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
5386 EXPECT_EQ(extension_util::IsIncognitoEnabled(good_crx, service_),
5387 data.incognito_enabled());
5388 EXPECT_TRUE(data.version().Equals(*extension->version()));
5389 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
5391 EXPECT_EQ(extension->name(), data.name());
5394 TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
5395 InitializeEmptyExtensionService();
5396 InitializeExtensionSyncService();
5397 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5398 TerminateExtension(good_crx);
5399 const Extension* extension = service_->GetInstalledExtension(good_crx);
5400 ASSERT_TRUE(extension);
5402 TestSyncProcessorStub processor;
5403 extension_sync_service_->MergeDataAndStartSyncing(
5404 syncer::EXTENSIONS, syncer::SyncDataList(),
5405 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5406 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5408 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5409 syncer::EXTENSIONS);
5410 ASSERT_EQ(list.size(), 1U);
5411 extensions::ExtensionSyncData data(list[0]);
5412 EXPECT_EQ(extension->id(), data.id());
5413 EXPECT_FALSE(data.uninstalled());
5414 EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
5415 EXPECT_EQ(extension_util::IsIncognitoEnabled(good_crx, service_),
5416 data.incognito_enabled());
5417 EXPECT_TRUE(data.version().Equals(*extension->version()));
5418 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
5420 EXPECT_EQ(extension->name(), data.name());
5423 TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
5424 InitializeEmptyExtensionService();
5425 InitializeExtensionSyncService();
5426 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5427 const Extension* extension = service_->GetInstalledExtension(good_crx);
5428 ASSERT_TRUE(extension);
5430 TestSyncProcessorStub processor;
5431 extension_sync_service_->MergeDataAndStartSyncing(syncer::APPS,
5432 syncer::SyncDataList(),
5433 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5434 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5436 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5437 syncer::EXTENSIONS);
5438 ASSERT_EQ(list.size(), 0U);
5441 TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
5442 InitializeEmptyExtensionService();
5443 InitializeExtensionProcessManager();
5444 InitializeExtensionSyncService();
5445 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5446 const Extension* extension = service_->GetInstalledExtension(good_crx);
5447 ASSERT_TRUE(extension);
5449 TestSyncProcessorStub processor;
5450 extension_sync_service_->MergeDataAndStartSyncing(
5451 syncer::EXTENSIONS, syncer::SyncDataList(),
5452 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5453 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5456 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5457 syncer::EXTENSIONS);
5458 ASSERT_EQ(list.size(), 1U);
5459 extensions::ExtensionSyncData data(list[0]);
5460 EXPECT_TRUE(data.enabled());
5461 EXPECT_FALSE(data.incognito_enabled());
5464 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
5466 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5467 syncer::EXTENSIONS);
5468 ASSERT_EQ(list.size(), 1U);
5469 extensions::ExtensionSyncData data(list[0]);
5470 EXPECT_FALSE(data.enabled());
5471 EXPECT_FALSE(data.incognito_enabled());
5474 extension_util::SetIsIncognitoEnabled(good_crx, service_, true);
5476 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5477 syncer::EXTENSIONS);
5478 ASSERT_EQ(list.size(), 1U);
5479 extensions::ExtensionSyncData data(list[0]);
5480 EXPECT_FALSE(data.enabled());
5481 EXPECT_TRUE(data.incognito_enabled());
5484 service_->EnableExtension(good_crx);
5486 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5487 syncer::EXTENSIONS);
5488 ASSERT_EQ(list.size(), 1U);
5489 extensions::ExtensionSyncData data(list[0]);
5490 EXPECT_TRUE(data.enabled());
5491 EXPECT_TRUE(data.incognito_enabled());
5495 TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
5496 InitializeEmptyExtensionService();
5497 InitializeExtensionSyncService();
5498 InstallCRXWithLocation(data_dir_.AppendASCII("good.crx"),
5499 Manifest::EXTERNAL_PREF, INSTALL_NEW);
5500 const Extension* extension = service_->GetInstalledExtension(good_crx);
5501 ASSERT_TRUE(extension);
5503 TestSyncProcessorStub processor;
5504 extension_sync_service_->MergeDataAndStartSyncing(
5505 syncer::EXTENSIONS, syncer::SyncDataList(),
5506 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5507 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5509 UninstallExtension(good_crx, false);
5510 EXPECT_TRUE(service_->IsExternalExtensionUninstalled(good_crx));
5512 sync_pb::EntitySpecifics specifics;
5513 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
5514 sync_pb::ExtensionSpecifics* extension_specifics =
5515 app_specifics->mutable_extension();
5516 extension_specifics->set_id(good_crx);
5517 extension_specifics->set_version("1.0");
5518 extension_specifics->set_enabled(true);
5520 syncer::SyncData sync_data =
5521 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5522 syncer::SyncChange sync_change(FROM_HERE,
5523 syncer::SyncChange::ACTION_UPDATE,
5525 syncer::SyncChangeList list(1);
5526 list[0] = sync_change;
5528 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5529 EXPECT_TRUE(service_->IsExternalExtensionUninstalled(good_crx));
5532 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
5533 InitializeEmptyExtensionService();
5534 InitializeExtensionSyncService();
5535 const Extension* app =
5536 PackAndInstallCRX(data_dir_.AppendASCII("app"), INSTALL_NEW);
5538 ASSERT_TRUE(app->is_app());
5540 TestSyncProcessorStub processor;
5541 extension_sync_service_->MergeDataAndStartSyncing(syncer::APPS,
5542 syncer::SyncDataList(),
5543 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5544 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5546 syncer::StringOrdinal initial_ordinal =
5547 syncer::StringOrdinal::CreateInitialOrdinal();
5549 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5551 ASSERT_EQ(list.size(), 1U);
5553 extensions::AppSyncData app_sync_data(list[0]);
5554 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.app_launch_ordinal()));
5555 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
5558 ExtensionSorting* sorting = service_->extension_prefs()->extension_sorting();
5559 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
5561 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5563 ASSERT_EQ(list.size(), 1U);
5565 extensions::AppSyncData app_sync_data(list[0]);
5566 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
5567 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
5570 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
5572 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5574 ASSERT_EQ(list.size(), 1U);
5576 extensions::AppSyncData app_sync_data(list[0]);
5577 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
5578 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.page_ordinal()));
5582 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
5583 InitializeEmptyExtensionService();
5584 InitializeExtensionSyncService();
5585 const size_t kAppCount = 3;
5586 const Extension* apps[kAppCount];
5587 apps[0] = PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
5588 apps[1] = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
5589 apps[2] = PackAndInstallCRX(data_dir_.AppendASCII("app4"), INSTALL_NEW);
5590 for (size_t i = 0; i < kAppCount; ++i) {
5591 ASSERT_TRUE(apps[i]);
5592 ASSERT_TRUE(apps[i]->is_app());
5595 TestSyncProcessorStub processor;
5596 extension_sync_service_->MergeDataAndStartSyncing(syncer::APPS,
5597 syncer::SyncDataList(),
5598 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5599 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5601 service_->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
5603 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5605 ASSERT_EQ(list.size(), 3U);
5607 extensions::AppSyncData data[kAppCount];
5608 for (size_t i = 0; i < kAppCount; ++i) {
5609 data[i] = extensions::AppSyncData(list[i]);
5612 // The sync data is not always in the same order our apps were installed in,
5613 // so we do that sorting here so we can make sure the values are changed as
5615 syncer::StringOrdinal app_launch_ordinals[kAppCount];
5616 for (size_t i = 0; i < kAppCount; ++i) {
5617 for (size_t j = 0; j < kAppCount; ++j) {
5618 if (apps[i]->id() == data[j].id())
5619 app_launch_ordinals[i] = data[j].app_launch_ordinal();
5623 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
5624 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
5628 TEST_F(ExtensionServiceTest, GetSyncDataList) {
5629 InitializeEmptyExtensionService();
5630 InitializeExtensionSyncService();
5631 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5632 InstallCRX(data_dir_.AppendASCII("page_action.crx"), INSTALL_NEW);
5633 InstallCRX(data_dir_.AppendASCII("theme.crx"), INSTALL_NEW);
5634 InstallCRX(data_dir_.AppendASCII("theme2.crx"), INSTALL_NEW);
5636 TestSyncProcessorStub processor;
5637 extension_sync_service_->MergeDataAndStartSyncing(
5638 syncer::APPS, syncer::SyncDataList(),
5639 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5640 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5641 extension_sync_service_->MergeDataAndStartSyncing(
5642 syncer::EXTENSIONS, syncer::SyncDataList(),
5643 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5644 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5646 service_->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
5647 TerminateExtension(theme2_crx);
5649 EXPECT_EQ(0u, extension_sync_service_->GetAllSyncData(syncer::APPS).size());
5650 EXPECT_EQ(2u, extension_sync_service_->
5651 GetAllSyncData(syncer::EXTENSIONS).size());
5654 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
5655 InitializeEmptyExtensionService();
5656 InitializeExtensionSyncService();
5657 TestSyncProcessorStub processor;
5658 extension_sync_service_->MergeDataAndStartSyncing(
5659 syncer::EXTENSIONS, syncer::SyncDataList(),
5660 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5661 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5663 sync_pb::EntitySpecifics specifics;
5664 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5665 ext_specifics->set_id(good_crx);
5666 ext_specifics->set_version("1.0");
5667 syncer::SyncData sync_data =
5668 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5669 syncer::SyncChange sync_change(FROM_HERE,
5670 syncer::SyncChange::ACTION_DELETE,
5672 syncer::SyncChangeList list(1);
5673 list[0] = sync_change;
5675 // Should do nothing.
5676 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5677 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
5679 // Install the extension.
5680 base::FilePath extension_path = data_dir_.AppendASCII("good.crx");
5681 InstallCRX(extension_path, INSTALL_NEW);
5682 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
5684 // Should uninstall the extension.
5685 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5686 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
5688 // Should again do nothing.
5689 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5690 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
5693 TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
5694 InitializeEmptyExtensionService();
5695 InitializeExtensionSyncService();
5697 // Install the extension.
5698 base::FilePath extension_path = data_dir_.AppendASCII("good.crx");
5699 InstallCRX(extension_path, INSTALL_NEW);
5700 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
5702 sync_pb::EntitySpecifics specifics;
5703 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
5704 sync_pb::ExtensionSpecifics* extension_specifics =
5705 app_specifics->mutable_extension();
5706 extension_specifics->set_id(good_crx);
5707 extension_specifics->set_version(
5708 service_->GetInstalledExtension(good_crx)->version()->GetString());
5711 extension_specifics->set_enabled(true);
5712 syncer::SyncData sync_data =
5713 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5714 syncer::SyncChange sync_change(FROM_HERE,
5715 syncer::SyncChange::ACTION_DELETE,
5717 syncer::SyncChangeList list(1);
5718 list[0] = sync_change;
5720 // Should do nothing
5721 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5722 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
5726 extension_specifics->set_enabled(false);
5727 syncer::SyncData sync_data =
5728 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5729 syncer::SyncChange sync_change(FROM_HERE,
5730 syncer::SyncChange::ACTION_UPDATE,
5732 syncer::SyncChangeList list(1);
5733 list[0] = sync_change;
5735 // Should again do nothing.
5736 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5737 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
5741 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
5742 InitializeEmptyExtensionService();
5743 InitializeExtensionProcessManager();
5744 InitializeExtensionSyncService();
5745 TestSyncProcessorStub processor;
5746 extension_sync_service_->MergeDataAndStartSyncing(
5747 syncer::EXTENSIONS, syncer::SyncDataList(),
5748 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5749 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5751 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5752 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5753 EXPECT_FALSE(extension_util::IsIncognitoEnabled(good_crx, service_));
5755 sync_pb::EntitySpecifics specifics;
5756 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5757 ext_specifics->set_id(good_crx);
5758 ext_specifics->set_version(
5759 service_->GetInstalledExtension(good_crx)->version()->GetString());
5760 ext_specifics->set_enabled(false);
5763 syncer::SyncData sync_data =
5764 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5765 syncer::SyncChange sync_change(FROM_HERE,
5766 syncer::SyncChange::ACTION_UPDATE,
5768 syncer::SyncChangeList list(1);
5769 list[0] = sync_change;
5770 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5771 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5772 EXPECT_FALSE(extension_util::IsIncognitoEnabled(good_crx, service_));
5776 ext_specifics->set_enabled(true);
5777 ext_specifics->set_incognito_enabled(true);
5778 syncer::SyncData sync_data =
5779 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5780 syncer::SyncChange sync_change(FROM_HERE,
5781 syncer::SyncChange::ACTION_UPDATE,
5783 syncer::SyncChangeList list(1);
5784 list[0] = sync_change;
5785 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5786 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5787 EXPECT_TRUE(extension_util::IsIncognitoEnabled(good_crx, service_));
5791 ext_specifics->set_enabled(false);
5792 ext_specifics->set_incognito_enabled(true);
5793 syncer::SyncData sync_data =
5794 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5795 syncer::SyncChange sync_change(FROM_HERE,
5796 syncer::SyncChange::ACTION_UPDATE,
5798 syncer::SyncChangeList list(1);
5799 list[0] = sync_change;
5800 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5801 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5802 EXPECT_TRUE(extension_util::IsIncognitoEnabled(good_crx, service_));
5805 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5808 TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
5809 InitializeExtensionServiceWithUpdater();
5810 InitializeExtensionSyncService();
5811 TestSyncProcessorStub processor;
5812 extension_sync_service_->MergeDataAndStartSyncing(
5813 syncer::EXTENSIONS, syncer::SyncDataList(),
5814 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5815 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5817 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5818 TerminateExtension(good_crx);
5819 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5820 EXPECT_FALSE(extension_util::IsIncognitoEnabled(good_crx, service_));
5822 sync_pb::EntitySpecifics specifics;
5823 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5824 ext_specifics->set_id(good_crx);
5825 ext_specifics->set_version(
5826 service_->GetInstalledExtension(good_crx)->version()->GetString());
5827 ext_specifics->set_enabled(false);
5828 ext_specifics->set_incognito_enabled(true);
5829 syncer::SyncData sync_data =
5830 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5831 syncer::SyncChange sync_change(FROM_HERE,
5832 syncer::SyncChange::ACTION_UPDATE,
5834 syncer::SyncChangeList list(1);
5835 list[0] = sync_change;
5837 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5838 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5839 EXPECT_TRUE(extension_util::IsIncognitoEnabled(good_crx, service_));
5841 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5844 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
5845 InitializeExtensionServiceWithUpdater();
5846 InitializeExtensionSyncService();
5847 TestSyncProcessorStub processor;
5848 extension_sync_service_->MergeDataAndStartSyncing(
5849 syncer::EXTENSIONS, syncer::SyncDataList(),
5850 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5851 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5853 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5854 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5855 EXPECT_FALSE(extension_util::IsIncognitoEnabled(good_crx, service_));
5857 sync_pb::EntitySpecifics specifics;
5858 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5859 ext_specifics->set_id(good_crx);
5860 ext_specifics->set_enabled(true);
5863 ext_specifics->set_version(
5864 service_->GetInstalledExtension(good_crx)->version()->GetString());
5865 syncer::SyncData sync_data =
5866 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5867 syncer::SyncChange sync_change(FROM_HERE,
5868 syncer::SyncChange::ACTION_UPDATE,
5870 syncer::SyncChangeList list(1);
5871 list[0] = sync_change;
5873 // Should do nothing if extension version == sync version.
5874 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5875 EXPECT_FALSE(service_->updater()->WillCheckSoon());
5878 // Should do nothing if extension version > sync version (but see
5879 // the TODO in ProcessExtensionSyncData).
5881 ext_specifics->set_version("0.0.0.0");
5882 syncer::SyncData sync_data =
5883 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5884 syncer::SyncChange sync_change(FROM_HERE,
5885 syncer::SyncChange::ACTION_UPDATE,
5887 syncer::SyncChangeList list(1);
5888 list[0] = sync_change;
5890 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5891 EXPECT_FALSE(service_->updater()->WillCheckSoon());
5894 // Should kick off an update if extension version < sync version.
5896 ext_specifics->set_version("9.9.9.9");
5897 syncer::SyncData sync_data =
5898 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5899 syncer::SyncChange sync_change(FROM_HERE,
5900 syncer::SyncChange::ACTION_UPDATE,
5902 syncer::SyncChangeList list(1);
5903 list[0] = sync_change;
5905 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5906 EXPECT_TRUE(service_->updater()->WillCheckSoon());
5909 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5912 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
5913 InitializeExtensionServiceWithUpdater();
5914 InitializeExtensionSyncService();
5915 TestSyncProcessorStub processor;
5916 extension_sync_service_->MergeDataAndStartSyncing(
5917 syncer::EXTENSIONS, syncer::SyncDataList(),
5918 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5919 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5921 sync_pb::EntitySpecifics specifics;
5922 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5923 ext_specifics->set_id(good_crx);
5924 ext_specifics->set_enabled(false);
5925 ext_specifics->set_incognito_enabled(true);
5926 ext_specifics->set_update_url("http://www.google.com/");
5927 ext_specifics->set_version("1.2.3.4");
5928 syncer::SyncData sync_data =
5929 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5930 syncer::SyncChange sync_change(FROM_HERE,
5931 syncer::SyncChange::ACTION_UPDATE,
5933 syncer::SyncChangeList list(1);
5934 list[0] = sync_change;
5937 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5938 EXPECT_FALSE(extension_util::IsIncognitoEnabled(good_crx, service_));
5939 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5940 EXPECT_TRUE(service_->updater()->WillCheckSoon());
5941 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5942 EXPECT_TRUE(extension_util::IsIncognitoEnabled(good_crx, service_));
5944 const extensions::PendingExtensionInfo* info;
5945 EXPECT_TRUE((info = service_->pending_extension_manager()->
5946 GetById(good_crx)));
5947 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
5948 EXPECT_TRUE(info->is_from_sync());
5949 EXPECT_TRUE(info->install_silently());
5950 EXPECT_EQ(Manifest::INTERNAL, info->install_source());
5951 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
5954 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
5955 InitializeEmptyExtensionService();
5957 base::FilePath path = data_dir_.AppendASCII("good.crx");
5958 InstallCRX(path, INSTALL_NEW);
5959 ValidatePrefKeyCount(1u);
5960 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5961 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
5963 extensions::PendingExtensionManager* pending =
5964 service_->pending_extension_manager();
5965 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5967 // Skip install when the location is the same.
5969 service_->OnExternalExtensionUpdateUrlFound(
5970 kGoodId, GURL(kGoodUpdateURL), Manifest::INTERNAL,
5971 Extension::NO_FLAGS, false));
5972 EXPECT_FALSE(pending->IsIdPending(kGoodId));
5974 // Install when the location has higher priority.
5976 service_->OnExternalExtensionUpdateUrlFound(
5977 kGoodId, GURL(kGoodUpdateURL), Manifest::EXTERNAL_POLICY_DOWNLOAD,
5978 Extension::NO_FLAGS, false));
5979 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5981 // Try the low priority again. Should be rejected.
5983 service_->OnExternalExtensionUpdateUrlFound(
5984 kGoodId, GURL(kGoodUpdateURL), Manifest::EXTERNAL_PREF_DOWNLOAD,
5985 Extension::NO_FLAGS, false));
5986 // The existing record should still be present in the pending extension
5988 EXPECT_TRUE(pending->IsIdPending(kGoodId));
5990 pending->Remove(kGoodId);
5992 // Skip install when the location has the same priority as the installed
5994 EXPECT_FALSE(service_->OnExternalExtensionUpdateUrlFound(
5995 kGoodId, GURL(kGoodUpdateURL), Manifest::INTERNAL,
5996 Extension::NO_FLAGS, false));
5998 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6001 TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
6002 Version older_version("0.1.0.0");
6003 Version newer_version("2.0.0.0");
6005 // We don't want the extension to be installed. A path that doesn't
6006 // point to a valid CRX ensures this.
6007 const base::FilePath kInvalidPathToCrx = base::FilePath();
6009 const int kCreationFlags = 0;
6010 const bool kDontMarkAcknowledged = false;
6012 InitializeEmptyExtensionService();
6014 // The test below uses install source constants to test that
6015 // priority is enforced. It assumes a specific ranking of install
6016 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
6017 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
6018 // The following assertions verify these assumptions:
6019 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
6020 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
6021 Manifest::EXTERNAL_PREF));
6022 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
6023 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
6024 Manifest::INTERNAL));
6025 ASSERT_EQ(Manifest::EXTERNAL_PREF,
6026 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
6027 Manifest::INTERNAL));
6029 extensions::PendingExtensionManager* pending =
6030 service_->pending_extension_manager();
6031 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6033 // Simulate an external source adding the extension as INTERNAL.
6035 service_->OnExternalExtensionFileFound(
6036 kGoodId, &older_version, kInvalidPathToCrx,
6037 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6038 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6039 WaitForCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6041 // Simulate an external source adding the extension as EXTERNAL_PREF.
6043 service_->OnExternalExtensionFileFound(
6044 kGoodId, &older_version, kInvalidPathToCrx,
6045 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6046 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6047 WaitForCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6049 // Simulate an external source adding as EXTERNAL_PREF again.
6050 // This is rejected because the version and the location are the same as
6051 // the previous installation, which is still pending.
6053 service_->OnExternalExtensionFileFound(
6054 kGoodId, &older_version, kInvalidPathToCrx,
6055 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6056 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6058 // Try INTERNAL again. Should fail.
6060 service_->OnExternalExtensionFileFound(
6061 kGoodId, &older_version, kInvalidPathToCrx,
6062 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6063 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6065 // Now the registry adds the extension.
6067 service_->OnExternalExtensionFileFound(
6068 kGoodId, &older_version, kInvalidPathToCrx,
6069 Manifest::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
6070 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6071 WaitForCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6073 // Registry outranks both external pref and internal, so both fail.
6075 service_->OnExternalExtensionFileFound(
6076 kGoodId, &older_version, kInvalidPathToCrx,
6077 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6078 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6081 service_->OnExternalExtensionFileFound(
6082 kGoodId, &older_version, kInvalidPathToCrx,
6083 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6084 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6086 pending->Remove(kGoodId);
6088 // Install the extension.
6089 base::FilePath path = data_dir_.AppendASCII("good.crx");
6090 const Extension* ext = InstallCRX(path, INSTALL_NEW);
6091 ValidatePrefKeyCount(1u);
6092 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
6093 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
6095 // Now test the logic of OnExternalExtensionFileFound() when the extension
6096 // being added is already installed.
6098 // Tests assume |older_version| is less than the installed version, and
6099 // |newer_version| is greater. Verify this:
6100 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
6101 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
6103 // An external install for the same location should fail if the version is
6104 // older, or the same, and succeed if the version is newer.
6106 // Older than the installed version...
6108 service_->OnExternalExtensionFileFound(
6109 kGoodId, &older_version, kInvalidPathToCrx,
6110 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6111 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6113 // Same version as the installed version...
6115 service_->OnExternalExtensionFileFound(
6116 kGoodId, ext->version(), kInvalidPathToCrx,
6117 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6118 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6120 // Newer than the installed version...
6122 service_->OnExternalExtensionFileFound(
6123 kGoodId, &newer_version, kInvalidPathToCrx,
6124 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6125 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6127 // An external install for a higher priority install source should succeed
6128 // if the version is greater. |older_version| is not...
6130 service_->OnExternalExtensionFileFound(
6131 kGoodId, &older_version, kInvalidPathToCrx,
6132 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6133 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6135 // |newer_version| is newer.
6137 service_->OnExternalExtensionFileFound(
6138 kGoodId, &newer_version, kInvalidPathToCrx,
6139 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6140 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6142 // An external install for an even higher priority install source should
6143 // succeed if the version is greater.
6145 service_->OnExternalExtensionFileFound(
6146 kGoodId, &newer_version, kInvalidPathToCrx,
6147 Manifest::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
6148 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6150 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
6151 // adding from external pref will now fail.
6153 service_->OnExternalExtensionFileFound(
6154 kGoodId, &newer_version, kInvalidPathToCrx,
6155 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6156 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6159 TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
6160 Version kVersion123("1.2.3");
6161 Version kVersion124("1.2.4");
6162 Version kVersion125("1.2.5");
6163 const base::FilePath kInvalidPathToCrx = base::FilePath();
6164 const int kCreationFlags = 0;
6165 const bool kDontMarkAcknowledged = false;
6167 InitializeEmptyExtensionService();
6169 extensions::PendingExtensionManager* pending =
6170 service_->pending_extension_manager();
6171 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6173 // An external provider starts installing from a local crx.
6175 service_->OnExternalExtensionFileFound(
6176 kGoodId, &kVersion123, kInvalidPathToCrx,
6177 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6178 const extensions::PendingExtensionInfo* info;
6179 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6180 EXPECT_TRUE(info->version().IsValid());
6181 EXPECT_TRUE(info->version().Equals(kVersion123));
6183 // Adding a newer version overrides the currently pending version.
6185 service_->OnExternalExtensionFileFound(
6186 kGoodId, &kVersion124, kInvalidPathToCrx,
6187 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6188 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6189 EXPECT_TRUE(info->version().IsValid());
6190 EXPECT_TRUE(info->version().Equals(kVersion124));
6192 // Adding an older version fails.
6194 service_->OnExternalExtensionFileFound(
6195 kGoodId, &kVersion123, kInvalidPathToCrx,
6196 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6197 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6198 EXPECT_TRUE(info->version().IsValid());
6199 EXPECT_TRUE(info->version().Equals(kVersion124));
6201 // Adding an older version fails even when coming from a higher-priority
6204 service_->OnExternalExtensionFileFound(
6205 kGoodId, &kVersion123, kInvalidPathToCrx,
6206 Manifest::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
6207 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6208 EXPECT_TRUE(info->version().IsValid());
6209 EXPECT_TRUE(info->version().Equals(kVersion124));
6211 // Adding the latest version from the webstore overrides a specific version.
6212 GURL kUpdateUrl("http://example.com/update");
6214 service_->OnExternalExtensionUpdateUrlFound(
6215 kGoodId, kUpdateUrl, Manifest::EXTERNAL_POLICY_DOWNLOAD,
6216 Extension::NO_FLAGS, false));
6217 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6218 EXPECT_FALSE(info->version().IsValid());
6221 // This makes sure we can package and install CRX files that use whitelisted
6223 TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
6224 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
6225 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6226 switches::kWhitelistedExtensionID, test_id);
6228 InitializeEmptyExtensionService();
6229 base::FilePath path = data_dir_
6230 .AppendASCII("permissions");
6231 base::FilePath pem_path = path
6232 .AppendASCII("whitelist.pem");
6234 .AppendASCII("whitelist");
6236 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
6237 EXPECT_EQ(0u, GetErrors().size());
6238 ASSERT_EQ(1u, service_->extensions()->size());
6239 EXPECT_EQ(test_id, extension->id());
6242 // Test that when multiple sources try to install an extension,
6243 // we consistently choose the right one. To make tests easy to read,
6244 // methods that fake requests to install crx files in several ways
6246 class ExtensionSourcePriorityTest : public ExtensionServiceTest {
6248 virtual void SetUp() {
6249 ExtensionServiceTest::SetUp();
6251 // All tests use a single extension. Put the id and path in member vars
6252 // that all methods can read.
6254 crx_path_ = data_dir_.AppendASCII("good.crx");
6257 // Fake an external source adding a URL to fetch an extension from.
6258 bool AddPendingExternalPrefUrl() {
6259 return service_->pending_extension_manager()->AddFromExternalUpdateUrl(
6260 crx_id_, GURL(), Manifest::EXTERNAL_PREF_DOWNLOAD,
6261 Extension::NO_FLAGS, false);
6264 // Fake an external file from external_extensions.json.
6265 bool AddPendingExternalPrefFileInstall() {
6266 Version version("1.0.0.0");
6268 return service_->OnExternalExtensionFileFound(
6269 crx_id_, &version, crx_path_, Manifest::EXTERNAL_PREF,
6270 Extension::NO_FLAGS, false);
6273 // Fake a request from sync to install an extension.
6274 bool AddPendingSyncInstall() {
6275 return service_->pending_extension_manager()->AddFromSync(
6276 crx_id_, GURL(kGoodUpdateURL), &IsExtension, kGoodInstallSilently);
6279 // Fake a policy install.
6280 bool AddPendingPolicyInstall() {
6281 // Get path to the CRX with id |kGoodId|.
6282 return service_->OnExternalExtensionUpdateUrlFound(
6283 crx_id_, GURL(), Manifest::EXTERNAL_POLICY_DOWNLOAD,
6284 Extension::NO_FLAGS, false);
6287 // Get the install source of a pending extension.
6288 Manifest::Location GetPendingLocation() {
6289 const extensions::PendingExtensionInfo* info;
6290 EXPECT_TRUE((info = service_->pending_extension_manager()->
6292 return info->install_source();
6295 // Is an extension pending from a sync request?
6296 bool GetPendingIsFromSync() {
6297 const extensions::PendingExtensionInfo* info;
6298 EXPECT_TRUE((info = service_->pending_extension_manager()->
6300 return info->is_from_sync();
6303 // Is the CRX id these tests use pending?
6304 bool IsCrxPending() {
6305 return service_->pending_extension_manager()->IsIdPending(crx_id_);
6308 // Is an extension installed?
6309 bool IsCrxInstalled() {
6310 return (service_->GetExtensionById(crx_id_, true) != NULL);
6314 // All tests use a single extension. Making the id and path member
6315 // vars avoids pasing the same argument to every method.
6316 std::string crx_id_;
6317 base::FilePath crx_path_;
6320 // Test that a pending request for installation of an external CRX from
6321 // an update URL overrides a pending request to install the same extension
6323 TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
6324 InitializeEmptyExtensionService();
6326 ASSERT_FALSE(IsCrxInstalled());
6328 // Install pending extension from sync.
6329 EXPECT_TRUE(AddPendingSyncInstall());
6330 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
6331 EXPECT_TRUE(GetPendingIsFromSync());
6332 ASSERT_FALSE(IsCrxInstalled());
6334 // Install pending as external prefs json would.
6335 AddPendingExternalPrefFileInstall();
6336 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
6337 ASSERT_FALSE(IsCrxInstalled());
6339 // Another request from sync should be ignored.
6340 EXPECT_FALSE(AddPendingSyncInstall());
6341 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
6342 ASSERT_FALSE(IsCrxInstalled());
6344 WaitForCrxInstall(crx_path_, INSTALL_NEW);
6345 ASSERT_TRUE(IsCrxInstalled());
6348 // Test that an install of an external CRX from an update overrides
6349 // an install of the same extension from sync.
6350 TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
6351 InitializeEmptyExtensionService();
6352 ASSERT_FALSE(IsCrxInstalled());
6354 EXPECT_TRUE(AddPendingSyncInstall());
6355 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
6356 EXPECT_TRUE(GetPendingIsFromSync());
6357 ASSERT_FALSE(IsCrxInstalled());
6359 ASSERT_TRUE(AddPendingExternalPrefUrl());
6360 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
6361 EXPECT_FALSE(GetPendingIsFromSync());
6362 ASSERT_FALSE(IsCrxInstalled());
6364 EXPECT_FALSE(AddPendingSyncInstall());
6365 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
6366 EXPECT_FALSE(GetPendingIsFromSync());
6367 ASSERT_FALSE(IsCrxInstalled());
6370 // Test that an external install request stops sync from installing
6371 // the same extension.
6372 TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
6373 InitializeEmptyExtensionService();
6374 ASSERT_FALSE(IsCrxInstalled());
6376 // External prefs starts an install.
6377 AddPendingExternalPrefFileInstall();
6379 // Crx installer was made, but has not yet run.
6380 ASSERT_FALSE(IsCrxInstalled());
6382 // Before the CRX installer runs, Sync requests that the same extension
6383 // be installed. Should fail, because an external source is pending.
6384 ASSERT_FALSE(AddPendingSyncInstall());
6386 // Wait for the external source to install.
6387 WaitForCrxInstall(crx_path_, INSTALL_NEW);
6388 ASSERT_TRUE(IsCrxInstalled());
6390 // Now that the extension is installed, sync request should fail
6391 // because the extension is already installed.
6392 ASSERT_FALSE(AddPendingSyncInstall());
6395 // Test that installing an external extension displays a GlobalError.
6396 TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
6397 FeatureSwitch::ScopedOverride prompt(
6398 FeatureSwitch::prompt_for_external_extensions(), true);
6400 InitializeEmptyExtensionService();
6401 MockExtensionProvider* provider =
6402 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
6403 AddMockExternalProvider(provider);
6405 service_->UpdateExternalExtensionAlert();
6406 // Should return false, meaning there aren't any extensions that the user
6407 // needs to know about.
6408 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
6410 // This is a normal extension, installed normally.
6411 // This should NOT trigger an alert.
6412 set_extensions_enabled(true);
6413 base::FilePath path = data_dir_.AppendASCII("good.crx");
6414 InstallCRX(path, INSTALL_NEW);
6416 service_->CheckForExternalUpdates();
6417 base::RunLoop().RunUntilIdle();
6418 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
6420 // A hosted app, installed externally.
6421 // This should NOT trigger an alert.
6422 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0",
6423 data_dir_.AppendASCII("hosted_app.crx"));
6425 service_->CheckForExternalUpdates();
6426 content::WindowedNotificationObserver(
6427 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6428 content::NotificationService::AllSources()).Wait();
6429 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
6431 // Another normal extension, but installed externally.
6432 // This SHOULD trigger an alert.
6433 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
6434 data_dir_.AppendASCII("page_action.crx"));
6436 service_->CheckForExternalUpdates();
6437 content::WindowedNotificationObserver(
6438 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6439 content::NotificationService::AllSources()).Wait();
6440 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6443 // Test that external extensions are initially disabled, and that enabling
6444 // them clears the prompt.
6445 TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
6446 FeatureSwitch::ScopedOverride prompt(
6447 FeatureSwitch::prompt_for_external_extensions(), true);
6449 InitializeEmptyExtensionService();
6450 MockExtensionProvider* provider =
6451 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
6452 AddMockExternalProvider(provider);
6454 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
6455 data_dir_.AppendASCII("page_action.crx"));
6457 service_->CheckForExternalUpdates();
6458 content::WindowedNotificationObserver(
6459 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6460 content::NotificationService::AllSources()).Wait();
6461 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6462 EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
6464 const Extension* extension =
6465 service_->disabled_extensions()->GetByID(page_action);
6466 EXPECT_TRUE(extension);
6467 EXPECT_EQ(page_action, extension->id());
6469 service_->EnableExtension(page_action);
6470 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
6471 EXPECT_TRUE(service_->IsExtensionEnabled(page_action));
6474 // Test that installing multiple external extensions works.
6475 // Flaky on windows; http://crbug.com/295757 .
6477 #define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
6479 #define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
6481 TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
6482 FeatureSwitch::ScopedOverride prompt(
6483 FeatureSwitch::prompt_for_external_extensions(), true);
6485 InitializeEmptyExtensionService();
6486 MockExtensionProvider* provider =
6487 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
6488 AddMockExternalProvider(provider);
6490 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
6491 data_dir_.AppendASCII("page_action.crx"));
6492 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
6493 data_dir_.AppendASCII("good.crx"));
6494 provider->UpdateOrAddExtension(theme_crx, "2.0",
6495 data_dir_.AppendASCII("theme.crx"));
6497 service_->CheckForExternalUpdates();
6499 content::WindowedNotificationObserver(
6500 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6501 base::Bind(&WaitForCountNotificationsCallback, &count)).Wait();
6502 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6503 EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
6504 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
6505 EXPECT_FALSE(service_->IsExtensionEnabled(theme_crx));
6507 service_->EnableExtension(page_action);
6508 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6509 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
6510 service_->EnableExtension(theme_crx);
6511 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6512 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
6513 service_->EnableExtension(good_crx);
6514 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
6515 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
6518 // Test that there is a bubble for external extensions that update
6519 // from the webstore if the profile is not new.
6520 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
6521 FeatureSwitch::ScopedOverride prompt(
6522 FeatureSwitch::prompt_for_external_extensions(), true);
6524 // This sets up the ExtensionPrefs used by our ExtensionService to be
6526 ExtensionServiceInitParams params = CreateDefaultInitParams();
6527 params.is_first_run = false;
6528 InitializeExtensionService(params);
6530 base::FilePath crx_path = temp_dir_.path().AppendASCII("webstore.crx");
6531 PackCRX(data_dir_.AppendASCII("update_from_webstore"),
6532 data_dir_.AppendASCII("update_from_webstore.pem"),
6535 MockExtensionProvider* provider =
6536 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
6537 AddMockExternalProvider(provider);
6538 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
6540 service_->CheckForExternalUpdates();
6541 content::WindowedNotificationObserver(
6542 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6543 content::NotificationService::AllSources()).Wait();
6544 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6545 EXPECT_TRUE(extensions::HasExternalInstallBubble(service_));
6546 EXPECT_FALSE(service_->IsExtensionEnabled(updates_from_webstore));
6549 // Test that there is no bubble for external extensions if the profile is new.
6550 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
6551 FeatureSwitch::ScopedOverride prompt(
6552 FeatureSwitch::prompt_for_external_extensions(), true);
6554 InitializeEmptyExtensionService();
6556 base::FilePath crx_path = temp_dir_.path().AppendASCII("webstore.crx");
6557 PackCRX(data_dir_.AppendASCII("update_from_webstore"),
6558 data_dir_.AppendASCII("update_from_webstore.pem"),
6561 MockExtensionProvider* provider =
6562 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
6563 AddMockExternalProvider(provider);
6564 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
6566 service_->CheckForExternalUpdates();
6567 content::WindowedNotificationObserver(
6568 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6569 content::NotificationService::AllSources()).Wait();
6570 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6571 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
6572 EXPECT_FALSE(service_->IsExtensionEnabled(updates_from_webstore));
6575 TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) {
6576 InitializeEmptyExtensionService();
6578 scoped_refptr<Extension> extension = extensions::ExtensionBuilder()
6579 .SetManifest(extensions::DictionaryBuilder()
6580 .Set("name", "extension")
6581 .Set("version", "1.0")
6582 .Set("manifest_version", 2).Build())
6584 ASSERT_TRUE(extension.get());
6585 const std::string& id = extension->id();
6587 std::set<std::string> id_set;
6589 extensions::ExtensionNotificationObserver notifications(
6590 content::NotificationService::AllSources(), id_set);
6592 // Installation should be allowed but the extension should never have been
6593 // loaded and it should be blacklisted in prefs.
6594 service_->OnExtensionInstalled(
6596 syncer::StringOrdinal(),
6597 false /* has requirement errors */,
6598 extensions::Blacklist::BLACKLISTED_MALWARE,
6599 false /* wait for idle */);
6600 base::RunLoop().RunUntilIdle();
6602 // Extension was installed but not loaded.
6603 EXPECT_TRUE(notifications.CheckNotifications(
6604 chrome::NOTIFICATION_EXTENSION_INSTALLED));
6606 EXPECT_TRUE(service_->GetInstalledExtension(id));
6607 EXPECT_FALSE(service_->extensions()->Contains(id));
6608 EXPECT_TRUE(service_->blacklisted_extensions()->Contains(id));
6609 EXPECT_TRUE(service_->extension_prefs()->IsExtensionBlacklisted(id));
6611 service_->extension_prefs()->IsBlacklistedExtensionAcknowledged(id));
6614 TEST_F(ExtensionServiceTest, ReconcileKnownDisabledNoneDisabled) {
6615 // A profile with 3 extensions installed: good0, good1, and good2.
6616 InitializeGoodInstalledExtensionService();
6618 // Initializing shouldn't disable any extensions if none are known to be
6622 extensions::ExtensionIdSet expected_extensions;
6623 expected_extensions.insert(good0);
6624 expected_extensions.insert(good1);
6625 expected_extensions.insert(good2);
6627 extensions::ExtensionIdSet expected_disabled_extensions;
6629 EXPECT_EQ(expected_extensions, service_->extensions()->GetIDs());
6630 EXPECT_EQ(expected_disabled_extensions,
6631 service_->disabled_extensions()->GetIDs());
6634 TEST_F(ExtensionServiceTest, ReconcileKnownDisabledWithSideEnable) {
6635 // A profile with 3 extensions installed: good0, good1, and good2.
6636 InitializeGoodInstalledExtensionService();
6638 ExtensionPrefs* extension_prefs = service_->extension_prefs();
6641 extension_prefs->SetExtensionState(good1, Extension::DISABLED);
6643 // Mark both good1 and good2 as "known_disabled" (effectively making good2
6644 // look as if it had been side-enabled).
6645 extensions::ExtensionIdSet known_disabled;
6646 known_disabled.insert(good1);
6647 known_disabled.insert(good2);
6648 extension_prefs->SetKnownDisabled(known_disabled);
6650 // Initialize the service (which should disable good2 since it's known to be
6654 extensions::ExtensionIdSet expected_extensions;
6655 expected_extensions.insert(good0);
6657 extensions::ExtensionIdSet expected_disabled_extensions;
6658 expected_disabled_extensions.insert(good1);
6659 expected_disabled_extensions.insert(good2);
6661 EXPECT_EQ(expected_extensions, service_->extensions()->GetIDs());
6662 EXPECT_EQ(expected_disabled_extensions,
6663 service_->disabled_extensions()->GetIDs());
6665 // Make sure that re-enabling an extension sticks across calls to
6666 // ReconcileKnownDisabled().
6667 service_->EnableExtension(good2);
6668 service_->ReconcileKnownDisabled();
6669 expected_extensions.insert(good2);
6670 expected_disabled_extensions.erase(good2);
6672 EXPECT_EQ(expected_extensions, service_->extensions()->GetIDs());
6673 EXPECT_EQ(expected_disabled_extensions,
6674 service_->disabled_extensions()->GetIDs());