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