Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_service_unittest.cc
blob1577828d182b11689f68625b2c8bac3f85b2b4ee
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 <algorithm>
6 #include <set>
7 #include <vector>
9 #include "base/at_exit.h"
10 #include "base/basictypes.h"
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/files/file_enumerator.h"
14 #include "base/files/file_util.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/json/json_file_value_serializer.h"
17 #include "base/json/json_reader.h"
18 #include "base/json/json_string_value_serializer.h"
19 #include "base/location.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "base/memory/weak_ptr.h"
22 #include "base/prefs/scoped_user_pref_update.h"
23 #include "base/single_thread_task_runner.h"
24 #include "base/stl_util.h"
25 #include "base/strings/pattern.h"
26 #include "base/strings/string16.h"
27 #include "base/strings/string_number_conversions.h"
28 #include "base/strings/string_util.h"
29 #include "base/strings/utf_string_conversions.h"
30 #include "base/thread_task_runner_handle.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/blacklist.h"
35 #include "chrome/browser/extensions/chrome_app_sorting.h"
36 #include "chrome/browser/extensions/component_loader.h"
37 #include "chrome/browser/extensions/crx_installer.h"
38 #include "chrome/browser/extensions/default_apps.h"
39 #include "chrome/browser/extensions/extension_creator.h"
40 #include "chrome/browser/extensions/extension_error_reporter.h"
41 #include "chrome/browser/extensions/extension_error_ui.h"
42 #include "chrome/browser/extensions/extension_management_test_util.h"
43 #include "chrome/browser/extensions/extension_notification_observer.h"
44 #include "chrome/browser/extensions/extension_service.h"
45 #include "chrome/browser/extensions/extension_service_test_base.h"
46 #include "chrome/browser/extensions/extension_special_storage_policy.h"
47 #include "chrome/browser/extensions/extension_sync_data.h"
48 #include "chrome/browser/extensions/extension_sync_service.h"
49 #include "chrome/browser/extensions/extension_util.h"
50 #include "chrome/browser/extensions/external_install_error.h"
51 #include "chrome/browser/extensions/external_install_manager.h"
52 #include "chrome/browser/extensions/external_policy_loader.h"
53 #include "chrome/browser/extensions/external_pref_loader.h"
54 #include "chrome/browser/extensions/external_provider_impl.h"
55 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
56 #include "chrome/browser/extensions/installed_loader.h"
57 #include "chrome/browser/extensions/pack_extension_job.h"
58 #include "chrome/browser/extensions/pending_extension_info.h"
59 #include "chrome/browser/extensions/pending_extension_manager.h"
60 #include "chrome/browser/extensions/permissions_updater.h"
61 #include "chrome/browser/extensions/test_blacklist.h"
62 #include "chrome/browser/extensions/test_extension_system.h"
63 #include "chrome/browser/extensions/unpacked_installer.h"
64 #include "chrome/browser/extensions/updater/extension_updater.h"
65 #include "chrome/browser/policy/profile_policy_connector.h"
66 #include "chrome/browser/policy/profile_policy_connector_factory.h"
67 #include "chrome/browser/prefs/pref_service_syncable.h"
68 #include "chrome/browser/sync/profile_sync_service.h"
69 #include "chrome/browser/sync/profile_sync_service_factory.h"
70 #include "chrome/common/chrome_constants.h"
71 #include "chrome/common/chrome_switches.h"
72 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
73 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
74 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
75 #include "chrome/common/extensions/sync_helper.h"
76 #include "chrome/common/pref_names.h"
77 #include "chrome/common/url_constants.h"
78 #include "chrome/test/base/scoped_browser_locale.h"
79 #include "chrome/test/base/testing_pref_service_syncable.h"
80 #include "chrome/test/base/testing_profile.h"
81 #include "components/crx_file/id_util.h"
82 #include "components/pref_registry/pref_registry_syncable.h"
83 #include "content/public/browser/dom_storage_context.h"
84 #include "content/public/browser/gpu_data_manager.h"
85 #include "content/public/browser/indexed_db_context.h"
86 #include "content/public/browser/notification_registrar.h"
87 #include "content/public/browser/notification_service.h"
88 #include "content/public/browser/plugin_service.h"
89 #include "content/public/browser/render_process_host.h"
90 #include "content/public/browser/storage_partition.h"
91 #include "content/public/common/content_constants.h"
92 #include "content/public/test/test_browser_thread_bundle.h"
93 #include "content/public/test/test_utils.h"
94 #include "extensions/browser/extension_dialog_auto_confirm.h"
95 #include "extensions/browser/extension_prefs.h"
96 #include "extensions/browser/extension_registry.h"
97 #include "extensions/browser/extension_system.h"
98 #include "extensions/browser/external_provider_interface.h"
99 #include "extensions/browser/install_flag.h"
100 #include "extensions/browser/management_policy.h"
101 #include "extensions/browser/test_management_policy.h"
102 #include "extensions/browser/uninstall_reason.h"
103 #include "extensions/common/constants.h"
104 #include "extensions/common/extension.h"
105 #include "extensions/common/extension_builder.h"
106 #include "extensions/common/extension_l10n_util.h"
107 #include "extensions/common/extension_resource.h"
108 #include "extensions/common/feature_switch.h"
109 #include "extensions/common/manifest_constants.h"
110 #include "extensions/common/manifest_handlers/background_info.h"
111 #include "extensions/common/manifest_handlers/permissions_parser.h"
112 #include "extensions/common/manifest_url_handlers.h"
113 #include "extensions/common/permissions/permission_set.h"
114 #include "extensions/common/permissions/permissions_data.h"
115 #include "extensions/common/switches.h"
116 #include "extensions/common/url_pattern.h"
117 #include "extensions/common/value_builder.h"
118 #include "gpu/config/gpu_info.h"
119 #include "grit/browser_resources.h"
120 #include "grit/generated_resources.h"
121 #include "net/cookies/canonical_cookie.h"
122 #include "net/cookies/cookie_monster.h"
123 #include "net/cookies/cookie_options.h"
124 #include "net/url_request/url_request_context.h"
125 #include "net/url_request/url_request_context_getter.h"
126 #include "storage/browser/database/database_tracker.h"
127 #include "storage/browser/quota/quota_manager.h"
128 #include "storage/common/database/database_identifier.h"
129 #include "sync/api/fake_sync_change_processor.h"
130 #include "sync/api/string_ordinal.h"
131 #include "sync/api/sync_data.h"
132 #include "sync/api/sync_error_factory.h"
133 #include "sync/api/sync_error_factory_mock.h"
134 #include "sync/api/syncable_service.h"
135 #include "sync/protocol/app_specifics.pb.h"
136 #include "sync/protocol/extension_specifics.pb.h"
137 #include "sync/protocol/sync.pb.h"
138 #include "testing/gtest/include/gtest/gtest.h"
139 #include "testing/platform_test.h"
140 #include "ui/base/l10n/l10n_util.h"
141 #include "url/gurl.h"
143 #if defined(ENABLE_SUPERVISED_USERS)
144 #include "chrome/browser/supervised_user/permission_request_creator.h"
145 #include "chrome/browser/supervised_user/supervised_user_constants.h"
146 #include "chrome/browser/supervised_user/supervised_user_service.h"
147 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
148 #endif
150 #if defined(OS_CHROMEOS)
151 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
152 #include "chrome/browser/chromeos/settings/cros_settings.h"
153 #include "chrome/browser/chromeos/settings/device_settings_service.h"
154 #endif
156 // The blacklist tests rely on the safe-browsing database.
157 #if defined(SAFE_BROWSING_DB_LOCAL)
158 #define ENABLE_BLACKLIST_TESTS
159 #endif
161 using base::DictionaryValue;
162 using base::ListValue;
163 using base::Value;
164 using content::BrowserContext;
165 using content::BrowserThread;
166 using content::DOMStorageContext;
167 using content::IndexedDBContext;
168 using content::PluginService;
169 using extensions::APIPermission;
170 using extensions::APIPermissionSet;
171 using extensions::AppSorting;
172 using extensions::Blacklist;
173 using extensions::CrxInstaller;
174 using extensions::Extension;
175 using extensions::ExtensionCreator;
176 using extensions::ExtensionPrefs;
177 using extensions::ExtensionRegistry;
178 using extensions::ExtensionResource;
179 using extensions::ExtensionSyncData;
180 using extensions::ExtensionSystem;
181 using extensions::FakeSafeBrowsingDatabaseManager;
182 using extensions::FeatureSwitch;
183 using extensions::Manifest;
184 using extensions::PermissionSet;
185 using extensions::TestExtensionSystem;
186 using extensions::UnloadedExtensionInfo;
187 using extensions::URLPatternSet;
189 namespace keys = extensions::manifest_keys;
191 namespace {
193 // Extension ids used during testing.
194 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
195 const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
196 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
197 const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
198 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
199 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
200 const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
201 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
202 const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad";
203 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
204 const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
205 const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
206 const char permissions_blocklist[] = "noffkehfcaggllbcojjbopcmlhcnhcdn";
208 struct ExtensionsOrder {
209 bool operator()(const scoped_refptr<const Extension>& a,
210 const scoped_refptr<const Extension>& b) {
211 return a->name() < b->name();
215 static std::vector<base::string16> GetErrors() {
216 const std::vector<base::string16>* errors =
217 ExtensionErrorReporter::GetInstance()->GetErrors();
218 std::vector<base::string16> ret_val;
220 for (std::vector<base::string16>::const_iterator iter = errors->begin();
221 iter != errors->end(); ++iter) {
222 std::string utf8_error = base::UTF16ToUTF8(*iter);
223 if (utf8_error.find(".svn") == std::string::npos) {
224 ret_val.push_back(*iter);
228 // The tests rely on the errors being in a certain order, which can vary
229 // depending on how filesystem iteration works.
230 std::stable_sort(ret_val.begin(), ret_val.end());
232 return ret_val;
235 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
236 int schemes = URLPattern::SCHEME_ALL;
237 extent->AddPattern(URLPattern(schemes, pattern));
240 base::FilePath GetTemporaryFile() {
241 base::FilePath temp_file;
242 CHECK(base::CreateTemporaryFile(&temp_file));
243 return temp_file;
246 bool WaitForCountNotificationsCallback(int *count) {
247 return --(*count) == 0;
250 } // namespace
252 class MockExtensionProvider : public extensions::ExternalProviderInterface {
253 public:
254 MockExtensionProvider(
255 VisitorInterface* visitor,
256 Manifest::Location location)
257 : location_(location), visitor_(visitor), visit_count_(0) {
260 ~MockExtensionProvider() override {}
262 void UpdateOrAddExtension(const std::string& id,
263 const std::string& version,
264 const base::FilePath& path) {
265 extension_map_[id] = std::make_pair(version, path);
268 void RemoveExtension(const std::string& id) {
269 extension_map_.erase(id);
272 // ExternalProvider implementation:
273 void VisitRegisteredExtension() override {
274 visit_count_++;
275 for (DataMap::const_iterator i = extension_map_.begin();
276 i != extension_map_.end(); ++i) {
277 Version version(i->second.first);
279 visitor_->OnExternalExtensionFileFound(
280 i->first, &version, i->second.second, location_,
281 Extension::NO_FLAGS, false, false);
283 visitor_->OnExternalProviderReady(this);
286 bool HasExtension(const std::string& id) const override {
287 return extension_map_.find(id) != extension_map_.end();
290 bool GetExtensionDetails(const std::string& id,
291 Manifest::Location* location,
292 scoped_ptr<Version>* version) const override {
293 DataMap::const_iterator it = extension_map_.find(id);
294 if (it == extension_map_.end())
295 return false;
297 if (version)
298 version->reset(new Version(it->second.first));
300 if (location)
301 *location = location_;
303 return true;
306 bool IsReady() const override { return true; }
308 void ServiceShutdown() override {}
310 int visit_count() const { return visit_count_; }
311 void set_visit_count(int visit_count) {
312 visit_count_ = visit_count;
315 private:
316 typedef std::map< std::string, std::pair<std::string, base::FilePath> >
317 DataMap;
318 DataMap extension_map_;
319 Manifest::Location location_;
320 VisitorInterface* visitor_;
322 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
323 // Mutable because it must be incremented on each call to
324 // VisitRegisteredExtension(), which must be a const method to inherit
325 // from the class being mocked.
326 mutable int visit_count_;
328 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
331 class MockProviderVisitor
332 : public extensions::ExternalProviderInterface::VisitorInterface {
333 public:
334 // The provider will return |fake_base_path| from
335 // GetBaseCrxFilePath(). User can test the behavior with
336 // and without an empty path using this parameter.
337 explicit MockProviderVisitor(base::FilePath fake_base_path)
338 : ids_found_(0),
339 fake_base_path_(fake_base_path),
340 expected_creation_flags_(Extension::NO_FLAGS) {
341 profile_.reset(new TestingProfile);
344 MockProviderVisitor(base::FilePath fake_base_path,
345 int expected_creation_flags)
346 : ids_found_(0),
347 fake_base_path_(fake_base_path),
348 expected_creation_flags_(expected_creation_flags) {
349 profile_.reset(new TestingProfile);
352 int Visit(const std::string& json_data) {
353 // Give the test json file to the provider for parsing.
354 provider_.reset(new extensions::ExternalProviderImpl(
355 this,
356 new extensions::ExternalTestingLoader(json_data, fake_base_path_),
357 profile_.get(),
358 Manifest::EXTERNAL_PREF,
359 Manifest::EXTERNAL_PREF_DOWNLOAD,
360 Extension::NO_FLAGS));
362 // We also parse the file into a dictionary to compare what we get back
363 // from the provider.
364 JSONStringValueDeserializer deserializer(json_data);
365 base::Value* json_value = deserializer.Deserialize(NULL, NULL);
367 if (!json_value || !json_value->IsType(base::Value::TYPE_DICTIONARY)) {
368 NOTREACHED() << "Unable to deserialize json data";
369 return -1;
370 } else {
371 base::DictionaryValue* external_extensions =
372 static_cast<base::DictionaryValue*>(json_value);
373 prefs_.reset(external_extensions);
376 // Reset our counter.
377 ids_found_ = 0;
378 // Ask the provider to look up all extensions and return them.
379 provider_->VisitRegisteredExtension();
381 return ids_found_;
384 bool OnExternalExtensionFileFound(const std::string& id,
385 const Version* version,
386 const base::FilePath& path,
387 Manifest::Location unused,
388 int creation_flags,
389 bool mark_acknowledged,
390 bool install_immediately) override {
391 EXPECT_EQ(expected_creation_flags_, creation_flags);
393 ++ids_found_;
394 base::DictionaryValue* pref;
395 // This tests is to make sure that the provider only notifies us of the
396 // values we gave it. So if the id we doesn't exist in our internal
397 // dictionary then something is wrong.
398 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
399 << "Got back ID (" << id.c_str() << ") we weren't expecting";
401 EXPECT_TRUE(path.IsAbsolute());
402 if (!fake_base_path_.empty())
403 EXPECT_TRUE(fake_base_path_.IsParent(path));
405 if (pref) {
406 EXPECT_TRUE(provider_->HasExtension(id));
408 // Ask provider if the extension we got back is registered.
409 Manifest::Location location = Manifest::INVALID_LOCATION;
410 scoped_ptr<Version> v1;
411 base::FilePath crx_path;
413 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
414 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
416 scoped_ptr<Version> v2;
417 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
418 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
419 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
420 EXPECT_EQ(Manifest::EXTERNAL_PREF, location);
422 // Remove it so we won't count it ever again.
423 prefs_->Remove(id, NULL);
425 return true;
428 bool OnExternalExtensionUpdateUrlFound(const std::string& id,
429 const std::string& install_parameter,
430 const GURL& update_url,
431 Manifest::Location location,
432 int creation_flags,
433 bool mark_acknowledged) override {
434 ++ids_found_;
435 base::DictionaryValue* pref;
436 // This tests is to make sure that the provider only notifies us of the
437 // values we gave it. So if the id we doesn't exist in our internal
438 // dictionary then something is wrong.
439 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
440 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
441 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location);
443 if (pref) {
444 EXPECT_TRUE(provider_->HasExtension(id));
446 // External extensions with update URLs do not have versions.
447 scoped_ptr<Version> v1;
448 Manifest::Location location1 = Manifest::INVALID_LOCATION;
449 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
450 EXPECT_FALSE(v1.get());
451 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1);
453 std::string parsed_install_parameter;
454 pref->GetString("install_parameter", &parsed_install_parameter);
455 EXPECT_EQ(parsed_install_parameter, install_parameter);
457 // Remove it so we won't count it again.
458 prefs_->Remove(id, NULL);
460 return true;
463 void OnExternalProviderReady(
464 const extensions::ExternalProviderInterface* provider) override {
465 EXPECT_EQ(provider, provider_.get());
466 EXPECT_TRUE(provider->IsReady());
469 Profile* profile() { return profile_.get(); }
471 private:
472 int ids_found_;
473 base::FilePath fake_base_path_;
474 int expected_creation_flags_;
475 scoped_ptr<extensions::ExternalProviderImpl> provider_;
476 scoped_ptr<base::DictionaryValue> prefs_;
477 scoped_ptr<TestingProfile> profile_;
479 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
482 class ExtensionServiceTest : public extensions::ExtensionServiceTestBase,
483 public content::NotificationObserver {
484 public:
485 ExtensionServiceTest()
486 : unloaded_reason_(UnloadedExtensionInfo::REASON_UNDEFINED),
487 installed_(NULL),
488 was_update_(false),
489 override_external_install_prompt_(
490 FeatureSwitch::prompt_for_external_extensions(),
491 false),
492 expected_extensions_count_(0) {
493 registrar_.Add(this,
494 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
495 content::NotificationService::AllSources());
496 registrar_.Add(this,
497 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
498 content::NotificationService::AllSources());
499 registrar_.Add(
500 this,
501 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
502 content::NotificationService::AllSources());
505 void Observe(int type,
506 const content::NotificationSource& source,
507 const content::NotificationDetails& details) override {
508 switch (type) {
509 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
510 const Extension* extension =
511 content::Details<const Extension>(details).ptr();
512 loaded_.push_back(make_scoped_refptr(extension));
513 // The tests rely on the errors being in a certain order, which can vary
514 // depending on how filesystem iteration works.
515 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
516 break;
519 case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
520 UnloadedExtensionInfo* unloaded_info =
521 content::Details<UnloadedExtensionInfo>(details).ptr();
522 const Extension* e = unloaded_info->extension;
523 unloaded_id_ = e->id();
524 unloaded_reason_ = unloaded_info->reason;
525 extensions::ExtensionList::iterator i =
526 std::find(loaded_.begin(), loaded_.end(), e);
527 // TODO(erikkay) fix so this can be an assert. Right now the tests
528 // are manually calling clear() on loaded_, so this isn't doable.
529 if (i == loaded_.end())
530 return;
531 loaded_.erase(i);
532 break;
534 case extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED: {
535 const extensions::InstalledExtensionInfo* installed_info =
536 content::Details<const extensions::InstalledExtensionInfo>(details)
537 .ptr();
538 installed_ = installed_info->extension;
539 was_update_ = installed_info->is_update;
540 old_name_ = installed_info->old_name;
541 break;
544 default:
545 DCHECK(false);
549 void AddMockExternalProvider(
550 extensions::ExternalProviderInterface* provider) {
551 service()->AddProviderForTesting(provider);
554 void MockSyncStartFlare(bool* was_called,
555 syncer::ModelType* model_type_passed_in,
556 syncer::ModelType model_type) {
557 *was_called = true;
558 *model_type_passed_in = model_type;
561 protected:
562 // Paths to some of the fake extensions.
563 base::FilePath good0_path() {
564 return data_dir()
565 .AppendASCII("good")
566 .AppendASCII("Extensions")
567 .AppendASCII(good0)
568 .AppendASCII("1.0.0.0");
571 base::FilePath good1_path() {
572 return data_dir()
573 .AppendASCII("good")
574 .AppendASCII("Extensions")
575 .AppendASCII(good1)
576 .AppendASCII("2");
579 base::FilePath good2_path() {
580 return data_dir()
581 .AppendASCII("good")
582 .AppendASCII("Extensions")
583 .AppendASCII(good2)
584 .AppendASCII("1.0");
587 void TestExternalProvider(MockExtensionProvider* provider,
588 Manifest::Location location);
590 void PackCRX(const base::FilePath& dir_path,
591 const base::FilePath& pem_path,
592 const base::FilePath& crx_path) {
593 // Use the existing pem key, if provided.
594 base::FilePath pem_output_path;
595 if (pem_path.value().empty()) {
596 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
597 } else {
598 ASSERT_TRUE(base::PathExists(pem_path));
601 ASSERT_TRUE(base::DeleteFile(crx_path, false));
603 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
604 ASSERT_TRUE(creator->Run(dir_path,
605 crx_path,
606 pem_path,
607 pem_output_path,
608 ExtensionCreator::kOverwriteCRX));
610 ASSERT_TRUE(base::PathExists(crx_path));
613 enum InstallState {
614 INSTALL_FAILED,
615 INSTALL_UPDATED,
616 INSTALL_NEW,
617 INSTALL_WITHOUT_LOAD,
620 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
621 const base::FilePath& pem_path,
622 InstallState install_state,
623 int creation_flags) {
624 base::FilePath crx_path;
625 base::ScopedTempDir temp_dir;
626 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
627 crx_path = temp_dir.path().AppendASCII("temp.crx");
629 PackCRX(dir_path, pem_path, crx_path);
630 return InstallCRX(crx_path, install_state, creation_flags);
633 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
634 const base::FilePath& pem_path,
635 InstallState install_state) {
636 return PackAndInstallCRX(dir_path, pem_path, install_state,
637 Extension::NO_FLAGS);
640 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
641 InstallState install_state) {
642 return PackAndInstallCRX(dir_path, base::FilePath(), install_state,
643 Extension::NO_FLAGS);
646 // Attempts to install an extension. Use INSTALL_FAILED if the installation
647 // is expected to fail.
648 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
649 // non-empty, expects that the existing extension's title was
650 // |expected_old_name|.
651 const Extension* InstallCRX(const base::FilePath& path,
652 InstallState install_state,
653 int creation_flags,
654 const std::string& expected_old_name) {
655 InstallCRXInternal(path, creation_flags);
656 return VerifyCrxInstall(path, install_state, expected_old_name);
659 // Attempts to install an extension. Use INSTALL_FAILED if the installation
660 // is expected to fail.
661 const Extension* InstallCRX(const base::FilePath& path,
662 InstallState install_state,
663 int creation_flags) {
664 return InstallCRX(path, install_state, creation_flags, std::string());
667 // Attempts to install an extension. Use INSTALL_FAILED if the installation
668 // is expected to fail.
669 const Extension* InstallCRX(const base::FilePath& path,
670 InstallState install_state) {
671 return InstallCRX(path, install_state, Extension::NO_FLAGS);
674 const Extension* InstallCRXFromWebStore(const base::FilePath& path,
675 InstallState install_state) {
676 InstallCRXInternal(path, Extension::FROM_WEBSTORE);
677 return VerifyCrxInstall(path, install_state);
680 const Extension* InstallCRXWithLocation(const base::FilePath& crx_path,
681 Manifest::Location install_location,
682 InstallState install_state) {
683 EXPECT_TRUE(base::PathExists(crx_path))
684 << "Path does not exist: "<< crx_path.value().c_str();
685 // no client (silent install)
686 scoped_refptr<CrxInstaller> installer(
687 CrxInstaller::CreateSilent(service()));
688 installer->set_install_source(install_location);
690 content::WindowedNotificationObserver observer(
691 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
692 content::NotificationService::AllSources());
693 installer->InstallCrx(crx_path);
694 observer.Wait();
696 return VerifyCrxInstall(crx_path, install_state);
699 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
700 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
701 // Returns an Extension pointer if the install succeeded, NULL otherwise.
702 const Extension* VerifyCrxInstall(const base::FilePath& path,
703 InstallState install_state) {
704 return VerifyCrxInstall(path, install_state, std::string());
707 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
708 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
709 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
710 // non-empty, expects that the existing extension's title was
711 // |expected_old_name|.
712 // Returns an Extension pointer if the install succeeded, NULL otherwise.
713 const Extension* VerifyCrxInstall(const base::FilePath& path,
714 InstallState install_state,
715 const std::string& expected_old_name) {
716 std::vector<base::string16> errors = GetErrors();
717 const Extension* extension = NULL;
718 if (install_state != INSTALL_FAILED) {
719 if (install_state == INSTALL_NEW)
720 ++expected_extensions_count_;
722 EXPECT_TRUE(installed_) << path.value();
723 // If and only if INSTALL_UPDATED, it should have the is_update flag.
724 EXPECT_EQ(install_state == INSTALL_UPDATED, was_update_)
725 << path.value();
726 // If INSTALL_UPDATED, old_name_ should match the given string.
727 if (install_state == INSTALL_UPDATED && !expected_old_name.empty())
728 EXPECT_EQ(expected_old_name, old_name_);
729 EXPECT_EQ(0u, errors.size()) << path.value();
731 if (install_state == INSTALL_WITHOUT_LOAD) {
732 EXPECT_EQ(0u, loaded_.size()) << path.value();
733 } else {
734 EXPECT_EQ(1u, loaded_.size()) << path.value();
735 size_t actual_extension_count =
736 registry()->enabled_extensions().size() +
737 registry()->disabled_extensions().size();
738 EXPECT_EQ(expected_extensions_count_, actual_extension_count) <<
739 path.value();
740 extension = loaded_[0].get();
741 EXPECT_TRUE(service()->GetExtensionById(extension->id(), false))
742 << path.value();
745 for (std::vector<base::string16>::iterator err = errors.begin();
746 err != errors.end(); ++err) {
747 LOG(ERROR) << *err;
749 } else {
750 EXPECT_FALSE(installed_) << path.value();
751 EXPECT_EQ(0u, loaded_.size()) << path.value();
752 EXPECT_EQ(1u, errors.size()) << path.value();
755 installed_ = NULL;
756 was_update_ = false;
757 old_name_ = "";
758 loaded_.clear();
759 ExtensionErrorReporter::GetInstance()->ClearErrors();
760 return extension;
763 enum UpdateState {
764 FAILED_SILENTLY,
765 FAILED,
766 UPDATED,
767 INSTALLED,
768 DISABLED,
769 ENABLED
772 void BlackListWebGL() {
773 static const std::string json_blacklist =
774 "{\n"
775 " \"name\": \"gpu blacklist\",\n"
776 " \"version\": \"1.0\",\n"
777 " \"entries\": [\n"
778 " {\n"
779 " \"id\": 1,\n"
780 " \"features\": [\"webgl\"]\n"
781 " }\n"
782 " ]\n"
783 "}";
784 gpu::GPUInfo gpu_info;
785 content::GpuDataManager::GetInstance()->InitializeForTesting(
786 json_blacklist, gpu_info);
789 // Grants all optional permissions stated in manifest to active permission
790 // set for extension |id|.
791 void GrantAllOptionalPermissions(const std::string& id) {
792 const Extension* extension = service()->GetInstalledExtension(id);
793 scoped_refptr<const PermissionSet> all_optional_permissions =
794 extensions::PermissionsParser::GetOptionalPermissions(extension);
795 extensions::PermissionsUpdater perms_updater(profile());
796 perms_updater.AddPermissions(extension, all_optional_permissions.get());
799 // Helper method to set up a WindowedNotificationObserver to wait for a
800 // specific CrxInstaller to finish if we don't know the value of the
801 // |installer| yet.
802 static bool IsCrxInstallerDone(extensions::CrxInstaller** installer,
803 const content::NotificationSource& source,
804 const content::NotificationDetails& details) {
805 return content::Source<extensions::CrxInstaller>(source).ptr() ==
806 *installer;
809 void PackCRXAndUpdateExtension(const std::string& id,
810 const base::FilePath& dir_path,
811 const base::FilePath& pem_path,
812 UpdateState expected_state) {
813 base::ScopedTempDir temp_dir;
814 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
815 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
817 PackCRX(dir_path, pem_path, crx_path);
818 UpdateExtension(id, crx_path, expected_state);
821 void UpdateExtension(const std::string& id,
822 const base::FilePath& in_path,
823 UpdateState expected_state) {
824 ASSERT_TRUE(base::PathExists(in_path));
826 // We need to copy this to a temporary location because Update() will delete
827 // it.
828 base::FilePath path = temp_dir().path();
829 path = path.Append(in_path.BaseName());
830 ASSERT_TRUE(base::CopyFile(in_path, path));
832 int previous_enabled_extension_count =
833 registry()->enabled_extensions().size();
834 int previous_installed_extension_count =
835 previous_enabled_extension_count +
836 registry()->disabled_extensions().size();
838 extensions::CrxInstaller* installer = NULL;
839 content::WindowedNotificationObserver observer(
840 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
841 base::Bind(&IsCrxInstallerDone, &installer));
842 service()->UpdateExtension(extensions::CRXFileInfo(id, path), true,
843 &installer);
845 if (installer)
846 observer.Wait();
847 else
848 base::RunLoop().RunUntilIdle();
850 std::vector<base::string16> errors = GetErrors();
851 int error_count = errors.size();
852 int enabled_extension_count = registry()->enabled_extensions().size();
853 int installed_extension_count =
854 enabled_extension_count + registry()->disabled_extensions().size();
856 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
857 EXPECT_EQ(expected_error_count, error_count) << path.value();
859 if (expected_state <= FAILED) {
860 EXPECT_EQ(previous_enabled_extension_count,
861 enabled_extension_count);
862 EXPECT_EQ(previous_installed_extension_count,
863 installed_extension_count);
864 } else {
865 int expected_installed_extension_count =
866 (expected_state >= INSTALLED) ? 1 : 0;
867 int expected_enabled_extension_count =
868 (expected_state >= ENABLED) ? 1 : 0;
869 EXPECT_EQ(expected_installed_extension_count,
870 installed_extension_count);
871 EXPECT_EQ(expected_enabled_extension_count,
872 enabled_extension_count);
875 // Update() should the temporary input file.
876 EXPECT_FALSE(base::PathExists(path));
879 void TerminateExtension(const std::string& id) {
880 const Extension* extension = service()->GetInstalledExtension(id);
881 if (!extension) {
882 ADD_FAILURE();
883 return;
885 service()->TrackTerminatedExtensionForTest(extension);
888 testing::AssertionResult IsBlocked(const std::string& id) {
889 scoped_ptr<extensions::ExtensionSet> all_unblocked_extensions =
890 registry()->GenerateInstalledExtensionsSet(
891 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::BLOCKED);
892 if (all_unblocked_extensions.get()->Contains(id))
893 return testing::AssertionFailure() << id << " is still unblocked!";
894 if (!registry()->blocked_extensions().Contains(id))
895 return testing::AssertionFailure() << id << " is not blocked!";
896 return testing::AssertionSuccess();
899 // Helper method to test that an extension moves through being blocked and
900 // unblocked as appropriate for its type.
901 void AssertExtensionBlocksAndUnblocks(
902 bool should_block, const std::string extension_id) {
903 // Assume we start in an unblocked state.
904 EXPECT_FALSE(IsBlocked(extension_id));
906 // Block the extensions.
907 service()->BlockAllExtensions();
908 base::RunLoop().RunUntilIdle();
910 if (should_block)
911 ASSERT_TRUE(IsBlocked(extension_id));
912 else
913 ASSERT_FALSE(IsBlocked(extension_id));
915 service()->UnblockAllExtensions();
916 base::RunLoop().RunUntilIdle();
918 ASSERT_FALSE(IsBlocked(extension_id));
921 size_t GetPrefKeyCount() {
922 const base::DictionaryValue* dict =
923 profile()->GetPrefs()->GetDictionary("extensions.settings");
924 if (!dict) {
925 ADD_FAILURE();
926 return 0;
928 return dict->size();
931 void UninstallExtension(const std::string& id, bool use_helper) {
932 UninstallExtension(id, use_helper, Extension::ENABLED);
935 void UninstallExtension(const std::string& id, bool use_helper,
936 Extension::State expected_state) {
937 // Verify that the extension is installed.
938 base::FilePath extension_path = extensions_install_dir().AppendASCII(id);
939 EXPECT_TRUE(base::PathExists(extension_path));
940 size_t pref_key_count = GetPrefKeyCount();
941 EXPECT_GT(pref_key_count, 0u);
942 ValidateIntegerPref(id, "state", expected_state);
944 // Uninstall it.
945 if (use_helper) {
946 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(
947 service(), id, extensions::UNINSTALL_REASON_FOR_TESTING));
948 } else {
949 EXPECT_TRUE(service()->UninstallExtension(
951 extensions::UNINSTALL_REASON_FOR_TESTING,
952 base::Bind(&base::DoNothing),
953 NULL));
955 --expected_extensions_count_;
957 // We should get an unload notification.
958 EXPECT_FALSE(unloaded_id_.empty());
959 EXPECT_EQ(id, unloaded_id_);
961 // Verify uninstalled state.
962 size_t new_pref_key_count = GetPrefKeyCount();
963 if (new_pref_key_count == pref_key_count) {
964 ValidateIntegerPref(id, "state",
965 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
966 } else {
967 EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
970 // The extension should not be in the service anymore.
971 EXPECT_FALSE(service()->GetInstalledExtension(id));
972 base::RunLoop().RunUntilIdle();
974 // The directory should be gone.
975 EXPECT_FALSE(base::PathExists(extension_path));
978 void ValidatePrefKeyCount(size_t count) {
979 EXPECT_EQ(count, GetPrefKeyCount());
982 testing::AssertionResult ValidateBooleanPref(
983 const std::string& extension_id,
984 const std::string& pref_path,
985 bool expected_val) {
986 std::string msg = "while checking: ";
987 msg += extension_id;
988 msg += " ";
989 msg += pref_path;
990 msg += " == ";
991 msg += expected_val ? "true" : "false";
993 PrefService* prefs = profile()->GetPrefs();
994 const base::DictionaryValue* dict =
995 prefs->GetDictionary("extensions.settings");
996 if (!dict) {
997 return testing::AssertionFailure()
998 << "extension.settings does not exist " << msg;
1001 const base::DictionaryValue* pref = NULL;
1002 if (!dict->GetDictionary(extension_id, &pref)) {
1003 return testing::AssertionFailure()
1004 << "extension pref does not exist " << msg;
1007 bool val;
1008 if (!pref->GetBoolean(pref_path, &val)) {
1009 return testing::AssertionFailure()
1010 << pref_path << " pref not found " << msg;
1013 return expected_val == val
1014 ? testing::AssertionSuccess()
1015 : testing::AssertionFailure() << "base::Value is incorrect " << msg;
1018 bool IsPrefExist(const std::string& extension_id,
1019 const std::string& pref_path) {
1020 const base::DictionaryValue* dict =
1021 profile()->GetPrefs()->GetDictionary("extensions.settings");
1022 if (dict == NULL) return false;
1023 const base::DictionaryValue* pref = NULL;
1024 if (!dict->GetDictionary(extension_id, &pref)) {
1025 return false;
1027 if (pref == NULL) {
1028 return false;
1030 bool val;
1031 if (!pref->GetBoolean(pref_path, &val)) {
1032 return false;
1034 return true;
1037 void ValidateIntegerPref(const std::string& extension_id,
1038 const std::string& pref_path,
1039 int expected_val) {
1040 std::string msg = " while checking: ";
1041 msg += extension_id;
1042 msg += " ";
1043 msg += pref_path;
1044 msg += " == ";
1045 msg += base::IntToString(expected_val);
1047 PrefService* prefs = profile()->GetPrefs();
1048 const base::DictionaryValue* dict =
1049 prefs->GetDictionary("extensions.settings");
1050 ASSERT_TRUE(dict != NULL) << msg;
1051 const base::DictionaryValue* pref = NULL;
1052 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1053 EXPECT_TRUE(pref != NULL) << msg;
1054 int val;
1055 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
1056 EXPECT_EQ(expected_val, val) << msg;
1059 void ValidateStringPref(const std::string& extension_id,
1060 const std::string& pref_path,
1061 const std::string& expected_val) {
1062 std::string msg = " while checking: ";
1063 msg += extension_id;
1064 msg += ".manifest.";
1065 msg += pref_path;
1066 msg += " == ";
1067 msg += expected_val;
1069 const base::DictionaryValue* dict =
1070 profile()->GetPrefs()->GetDictionary("extensions.settings");
1071 ASSERT_TRUE(dict != NULL) << msg;
1072 const base::DictionaryValue* pref = NULL;
1073 std::string manifest_path = extension_id + ".manifest";
1074 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
1075 EXPECT_TRUE(pref != NULL) << msg;
1076 std::string val;
1077 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
1078 EXPECT_EQ(expected_val, val) << msg;
1081 void SetPref(const std::string& extension_id,
1082 const std::string& pref_path,
1083 base::Value* value,
1084 const std::string& msg) {
1085 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1086 base::DictionaryValue* dict = update.Get();
1087 ASSERT_TRUE(dict != NULL) << msg;
1088 base::DictionaryValue* pref = NULL;
1089 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1090 EXPECT_TRUE(pref != NULL) << msg;
1091 pref->Set(pref_path, value);
1094 void SetPrefInteg(const std::string& extension_id,
1095 const std::string& pref_path,
1096 int value) {
1097 std::string msg = " while setting: ";
1098 msg += extension_id;
1099 msg += " ";
1100 msg += pref_path;
1101 msg += " = ";
1102 msg += base::IntToString(value);
1104 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1107 void SetPrefBool(const std::string& extension_id,
1108 const std::string& pref_path,
1109 bool value) {
1110 std::string msg = " while setting: ";
1111 msg += extension_id + " " + pref_path;
1112 msg += " = ";
1113 msg += (value ? "true" : "false");
1115 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1118 void ClearPref(const std::string& extension_id,
1119 const std::string& pref_path) {
1120 std::string msg = " while clearing: ";
1121 msg += extension_id + " " + pref_path;
1123 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1124 base::DictionaryValue* dict = update.Get();
1125 ASSERT_TRUE(dict != NULL) << msg;
1126 base::DictionaryValue* pref = NULL;
1127 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1128 EXPECT_TRUE(pref != NULL) << msg;
1129 pref->Remove(pref_path, NULL);
1132 void SetPrefStringSet(const std::string& extension_id,
1133 const std::string& pref_path,
1134 const std::set<std::string>& value) {
1135 std::string msg = " while setting: ";
1136 msg += extension_id + " " + pref_path;
1138 base::ListValue* list_value = new base::ListValue();
1139 for (std::set<std::string>::const_iterator iter = value.begin();
1140 iter != value.end(); ++iter)
1141 list_value->Append(new base::StringValue(*iter));
1143 SetPref(extension_id, pref_path, list_value, msg);
1146 void InitPluginService() {
1147 #if defined(ENABLE_PLUGINS)
1148 PluginService::GetInstance()->Init();
1149 #endif
1152 void InitializeEmptyExtensionServiceWithTestingPrefs() {
1153 ExtensionServiceTestBase::ExtensionServiceInitParams params =
1154 CreateDefaultInitParams();
1155 params.pref_file = base::FilePath();
1156 InitializeExtensionService(params);
1159 extensions::ManagementPolicy* GetManagementPolicy() {
1160 return ExtensionSystem::Get(browser_context())->management_policy();
1163 ExtensionSyncService* extension_sync_service() {
1164 return ExtensionSyncService::Get(profile());
1167 protected:
1168 typedef extensions::ExtensionManagementPrefUpdater<TestingPrefServiceSyncable>
1169 ManagementPrefUpdater;
1170 extensions::ExtensionList loaded_;
1171 std::string unloaded_id_;
1172 UnloadedExtensionInfo::Reason unloaded_reason_;
1173 const Extension* installed_;
1174 bool was_update_;
1175 std::string old_name_;
1176 FeatureSwitch::ScopedOverride override_external_install_prompt_;
1178 private:
1179 // Create a CrxInstaller and install the CRX file.
1180 // Instead of calling this method yourself, use InstallCRX(), which does extra
1181 // error checking.
1182 void InstallCRXInternal(const base::FilePath& crx_path) {
1183 InstallCRXInternal(crx_path, Extension::NO_FLAGS);
1186 void InstallCRXInternal(const base::FilePath& crx_path, int creation_flags) {
1187 ASSERT_TRUE(base::PathExists(crx_path))
1188 << "Path does not exist: "<< crx_path.value().c_str();
1189 scoped_refptr<CrxInstaller> installer(
1190 CrxInstaller::CreateSilent(service()));
1191 installer->set_creation_flags(creation_flags);
1192 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT))
1193 installer->set_allow_silent_install(true);
1195 content::WindowedNotificationObserver observer(
1196 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1197 content::Source<extensions::CrxInstaller>(installer.get()));
1199 installer->InstallCrx(crx_path);
1201 observer.Wait();
1204 size_t expected_extensions_count_;
1205 content::NotificationRegistrar registrar_;
1208 // Receives notifications from a PackExtensionJob, indicating either that
1209 // packing succeeded or that there was some error.
1210 class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
1211 public:
1212 PackExtensionTestClient(const base::FilePath& expected_crx_path,
1213 const base::FilePath& expected_private_key_path);
1214 void OnPackSuccess(const base::FilePath& crx_path,
1215 const base::FilePath& private_key_path) override;
1216 void OnPackFailure(const std::string& error_message,
1217 ExtensionCreator::ErrorType type) override;
1219 private:
1220 const base::FilePath expected_crx_path_;
1221 const base::FilePath expected_private_key_path_;
1222 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
1225 PackExtensionTestClient::PackExtensionTestClient(
1226 const base::FilePath& expected_crx_path,
1227 const base::FilePath& expected_private_key_path)
1228 : expected_crx_path_(expected_crx_path),
1229 expected_private_key_path_(expected_private_key_path) {}
1231 // If packing succeeded, we make sure that the package names match our
1232 // expectations.
1233 void PackExtensionTestClient::OnPackSuccess(
1234 const base::FilePath& crx_path,
1235 const base::FilePath& private_key_path) {
1236 // We got the notification and processed it; we don't expect any further tasks
1237 // to be posted to the current thread, so we should stop blocking and continue
1238 // on with the rest of the test.
1239 // This call to |Quit()| matches the call to |Run()| in the
1240 // |PackPunctuatedExtension| test.
1241 base::MessageLoop::current()->Quit();
1242 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
1243 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
1244 ASSERT_TRUE(base::PathExists(private_key_path));
1247 // The tests are designed so that we never expect to see a packing error.
1248 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1249 ExtensionCreator::ErrorType type) {
1250 if (type == ExtensionCreator::kCRXExists)
1251 FAIL() << "Packing should not fail.";
1252 else
1253 FAIL() << "Existing CRX should have been overwritten.";
1256 // Test loading good extensions from the profile directory.
1257 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1258 InitPluginService();
1259 InitializeGoodInstalledExtensionService();
1260 service()->Init();
1262 uint32 expected_num_extensions = 3u;
1263 ASSERT_EQ(expected_num_extensions, loaded_.size());
1265 EXPECT_EQ(std::string(good0), loaded_[0]->id());
1266 EXPECT_EQ(std::string("My extension 1"),
1267 loaded_[0]->name());
1268 EXPECT_EQ(std::string("The first extension that I made."),
1269 loaded_[0]->description());
1270 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
1271 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false));
1272 EXPECT_EQ(expected_num_extensions, registry()->enabled_extensions().size());
1274 ValidatePrefKeyCount(3);
1275 ValidateIntegerPref(good0, "state", Extension::ENABLED);
1276 ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
1277 ValidateIntegerPref(good1, "state", Extension::ENABLED);
1278 ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
1279 ValidateIntegerPref(good2, "state", Extension::ENABLED);
1280 ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
1282 URLPatternSet expected_patterns;
1283 AddPattern(&expected_patterns, "file:///*");
1284 AddPattern(&expected_patterns, "http://*.google.com/*");
1285 AddPattern(&expected_patterns, "https://*.google.com/*");
1286 const Extension* extension = loaded_[0].get();
1287 const extensions::UserScriptList& scripts =
1288 extensions::ContentScriptsInfo::GetContentScripts(extension);
1289 ASSERT_EQ(2u, scripts.size());
1290 EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
1291 EXPECT_EQ(2u, scripts[0].js_scripts().size());
1292 ExtensionResource resource00(extension->id(),
1293 scripts[0].js_scripts()[0].extension_root(),
1294 scripts[0].js_scripts()[0].relative_path());
1295 base::FilePath expected_path =
1296 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
1297 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
1298 ExtensionResource resource01(extension->id(),
1299 scripts[0].js_scripts()[1].extension_root(),
1300 scripts[0].js_scripts()[1].relative_path());
1301 expected_path =
1302 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
1303 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
1304 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension));
1305 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
1306 EXPECT_EQ("http://*.news.com/*",
1307 scripts[1].url_patterns().begin()->GetAsString());
1308 ExtensionResource resource10(extension->id(),
1309 scripts[1].js_scripts()[0].extension_root(),
1310 scripts[1].js_scripts()[0].relative_path());
1311 expected_path =
1312 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
1313 expected_path = base::MakeAbsoluteFilePath(expected_path);
1314 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
1316 expected_patterns.ClearPatterns();
1317 AddPattern(&expected_patterns, "http://*.google.com/*");
1318 AddPattern(&expected_patterns, "https://*.google.com/*");
1319 EXPECT_EQ(
1320 expected_patterns,
1321 extension->permissions_data()->active_permissions()->explicit_hosts());
1323 EXPECT_EQ(std::string(good1), loaded_[1]->id());
1324 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
1325 EXPECT_EQ(std::string(), loaded_[1]->description());
1326 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
1327 extensions::BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
1328 EXPECT_EQ(0u,
1329 extensions::ContentScriptsInfo::GetContentScripts(loaded_[1].get())
1330 .size());
1332 // We don't parse the plugins section on Chrome OS.
1333 #if defined(OS_CHROMEOS)
1334 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1335 #else
1336 ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1337 const std::vector<extensions::PluginInfo>* plugins =
1338 extensions::PluginInfo::GetPlugins(loaded_[1].get());
1339 ASSERT_TRUE(plugins);
1340 ASSERT_EQ(2u, plugins->size());
1341 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
1342 plugins->at(0).path.value());
1343 EXPECT_TRUE(plugins->at(0).is_public);
1344 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1345 plugins->at(1).path.value());
1346 EXPECT_FALSE(plugins->at(1).is_public);
1347 #endif
1349 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
1351 int index = expected_num_extensions - 1;
1352 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1353 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1354 EXPECT_EQ(std::string(), loaded_[index]->description());
1355 EXPECT_EQ(0u,
1356 extensions::ContentScriptsInfo::GetContentScripts(
1357 loaded_[index].get()).size());
1358 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
1361 // Test loading bad extensions from the profile directory.
1362 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
1363 // Initialize the test dir with a bad Preferences/extensions.
1364 base::FilePath source_install_dir =
1365 data_dir().AppendASCII("bad").AppendASCII("Extensions");
1366 base::FilePath pref_path =
1367 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1369 InitializeInstalledExtensionService(pref_path, source_install_dir);
1371 service()->Init();
1373 ASSERT_EQ(4u, GetErrors().size());
1374 ASSERT_EQ(0u, loaded_.size());
1376 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[0]),
1377 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1378 extensions::manifest_errors::kManifestUnreadable)) <<
1379 base::UTF16ToUTF8(GetErrors()[0]);
1381 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[1]),
1382 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1383 extensions::manifest_errors::kManifestUnreadable)) <<
1384 base::UTF16ToUTF8(GetErrors()[1]);
1386 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[2]),
1387 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1388 extensions::manifest_errors::kMissingFile)) <<
1389 base::UTF16ToUTF8(GetErrors()[2]);
1391 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[3]),
1392 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1393 extensions::manifest_errors::kManifestUnreadable)) <<
1394 base::UTF16ToUTF8(GetErrors()[3]);
1397 // Test various cases for delayed install because of missing imports.
1398 TEST_F(ExtensionServiceTest, PendingImports) {
1399 InitPluginService();
1401 base::FilePath source_install_dir =
1402 data_dir().AppendASCII("pending_updates_with_imports").AppendASCII(
1403 "Extensions");
1404 base::FilePath pref_path =
1405 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1407 InitializeInstalledExtensionService(pref_path, source_install_dir);
1409 // Verify there are no pending extensions initially.
1410 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions());
1412 service()->Init();
1413 // Wait for GarbageCollectExtensions task to complete.
1414 base::RunLoop().RunUntilIdle();
1416 // These extensions are used by the extensions we test below, they must be
1417 // installed.
1418 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1419 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1420 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1421 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1423 // Each of these extensions should have been rejected because of dependencies
1424 // that cannot be satisfied.
1425 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1426 EXPECT_FALSE(
1427 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1428 EXPECT_FALSE(
1429 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1430 EXPECT_FALSE(
1431 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1432 EXPECT_FALSE(
1433 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1434 EXPECT_FALSE(
1435 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
1436 EXPECT_FALSE(
1437 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
1439 // Make sure the import started for the extension with a dependency.
1440 EXPECT_TRUE(
1441 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1442 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1443 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1445 EXPECT_FALSE(base::PathExists(extensions_install_dir().AppendASCII(
1446 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
1448 EXPECT_TRUE(service()->pending_extension_manager()->HasPendingExtensions());
1449 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
1450 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
1451 // Remove it because we are not testing the pending extension manager's
1452 // ability to download and install extensions.
1453 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id));
1456 // Test installing extensions. This test tries to install few extensions using
1457 // crx files. If you need to change those crx files, feel free to repackage
1458 // them, throw away the key used and change the id's above.
1459 TEST_F(ExtensionServiceTest, InstallExtension) {
1460 InitializeEmptyExtensionService();
1462 // Extensions not enabled.
1463 service()->set_extensions_enabled(false);
1464 base::FilePath path = data_dir().AppendASCII("good.crx");
1465 InstallCRX(path, INSTALL_FAILED);
1466 service()->set_extensions_enabled(true);
1468 ValidatePrefKeyCount(0);
1470 // A simple extension that should install without error.
1471 path = data_dir().AppendASCII("good.crx");
1472 InstallCRX(path, INSTALL_NEW);
1473 // TODO(erikkay): verify the contents of the installed extension.
1475 int pref_count = 0;
1476 ValidatePrefKeyCount(++pref_count);
1477 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1478 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
1480 // An extension with page actions.
1481 path = data_dir().AppendASCII("page_action.crx");
1482 InstallCRX(path, INSTALL_NEW);
1483 ValidatePrefKeyCount(++pref_count);
1484 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1485 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
1487 // Bad signature.
1488 path = data_dir().AppendASCII("bad_signature.crx");
1489 InstallCRX(path, INSTALL_FAILED);
1490 ValidatePrefKeyCount(pref_count);
1492 // 0-length extension file.
1493 path = data_dir().AppendASCII("not_an_extension.crx");
1494 InstallCRX(path, INSTALL_FAILED);
1495 ValidatePrefKeyCount(pref_count);
1497 // Bad magic number.
1498 path = data_dir().AppendASCII("bad_magic.crx");
1499 InstallCRX(path, INSTALL_FAILED);
1500 ValidatePrefKeyCount(pref_count);
1502 // Packed extensions may have folders or files that have underscores.
1503 // This will only cause a warning, rather than a fatal error.
1504 path = data_dir().AppendASCII("bad_underscore.crx");
1505 InstallCRX(path, INSTALL_NEW);
1506 ValidatePrefKeyCount(++pref_count);
1508 // A test for an extension with a 2048-bit public key.
1509 path = data_dir().AppendASCII("good2048.crx");
1510 InstallCRX(path, INSTALL_NEW);
1511 ValidatePrefKeyCount(++pref_count);
1512 ValidateIntegerPref(good2048, "state", Extension::ENABLED);
1513 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
1515 // TODO(erikkay): add more tests for many of the failure cases.
1516 // TODO(erikkay): add tests for upgrade cases.
1519 struct MockExtensionRegistryObserver
1520 : public extensions::ExtensionRegistryObserver {
1521 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
1522 const Extension* extension,
1523 bool is_update,
1524 bool from_ephemeral,
1525 const std::string& old_name) override {
1526 last_extension_installed = extension->id();
1529 void OnExtensionUninstalled(content::BrowserContext* browser_context,
1530 const Extension* extension,
1531 extensions::UninstallReason reason) override {
1532 last_extension_uninstalled = extension->id();
1535 std::string last_extension_installed;
1536 std::string last_extension_uninstalled;
1539 // Test that correct notifications are sent to ExtensionRegistryObserver on
1540 // extension install and uninstall.
1541 TEST_F(ExtensionServiceTest, InstallObserverNotified) {
1542 InitializeEmptyExtensionService();
1544 extensions::ExtensionRegistry* registry(
1545 extensions::ExtensionRegistry::Get(profile()));
1546 MockExtensionRegistryObserver observer;
1547 registry->AddObserver(&observer);
1549 // A simple extension that should install without error.
1550 ASSERT_TRUE(observer.last_extension_installed.empty());
1551 base::FilePath path = data_dir().AppendASCII("good.crx");
1552 InstallCRX(path, INSTALL_NEW);
1553 ASSERT_EQ(good_crx, observer.last_extension_installed);
1555 // Uninstall the extension.
1556 ASSERT_TRUE(observer.last_extension_uninstalled.empty());
1557 UninstallExtension(good_crx, false);
1558 ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
1560 registry->RemoveObserver(&observer);
1563 // Tests that flags passed to OnExternalExtensionFileFound() make it to the
1564 // extension object.
1565 TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
1566 const char kPrefFromBookmark[] = "from_bookmark";
1568 InitializeEmptyExtensionService();
1570 base::FilePath path = data_dir().AppendASCII("good.crx");
1571 service()->set_extensions_enabled(true);
1573 // Register and install an external extension.
1574 Version version("1.0.0.0");
1575 content::WindowedNotificationObserver observer(
1576 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1577 content::NotificationService::AllSources());
1578 if (service()->OnExternalExtensionFileFound(
1579 good_crx,
1580 &version,
1581 path,
1582 Manifest::EXTERNAL_PREF,
1583 Extension::FROM_BOOKMARK,
1584 false /* mark_acknowledged */,
1585 false /* install_immediately */)) {
1586 observer.Wait();
1589 const Extension* extension = service()->GetExtensionById(good_crx, false);
1590 ASSERT_TRUE(extension);
1591 ASSERT_TRUE(extension->from_bookmark());
1592 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1594 // Upgrade to version 2.0, the flag should be preserved.
1595 path = data_dir().AppendASCII("good2.crx");
1596 UpdateExtension(good_crx, path, ENABLED);
1597 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1598 extension = service()->GetExtensionById(good_crx, false);
1599 ASSERT_TRUE(extension);
1600 ASSERT_TRUE(extension->from_bookmark());
1603 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1604 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
1605 InitializeEmptyExtensionService();
1607 base::FilePath path = data_dir().AppendASCII("good.crx");
1608 service()->set_extensions_enabled(true);
1610 // Install an external extension.
1611 Version version("1.0.0.0");
1612 content::WindowedNotificationObserver observer(
1613 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1614 content::NotificationService::AllSources());
1615 if (service()->OnExternalExtensionFileFound(good_crx,
1616 &version,
1617 path,
1618 Manifest::EXTERNAL_PREF,
1619 Extension::NO_FLAGS,
1620 false,
1621 false)) {
1622 observer.Wait();
1625 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1627 // Uninstall it and check that its killbit gets set.
1628 UninstallExtension(good_crx, false);
1629 ValidateIntegerPref(good_crx, "state",
1630 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1632 // Try to re-install it externally. This should fail because of the killbit.
1633 service()->OnExternalExtensionFileFound(good_crx,
1634 &version,
1635 path,
1636 Manifest::EXTERNAL_PREF,
1637 Extension::NO_FLAGS,
1638 false,
1639 false);
1640 base::RunLoop().RunUntilIdle();
1641 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1642 ValidateIntegerPref(good_crx, "state",
1643 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1645 version = Version("1.0.0.1");
1646 // Repeat the same thing with a newer version of the extension.
1647 path = data_dir().AppendASCII("good2.crx");
1648 service()->OnExternalExtensionFileFound(good_crx,
1649 &version,
1650 path,
1651 Manifest::EXTERNAL_PREF,
1652 Extension::NO_FLAGS,
1653 false,
1654 false);
1655 base::RunLoop().RunUntilIdle();
1656 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1657 ValidateIntegerPref(good_crx, "state",
1658 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1660 // Try adding the same extension from an external update URL.
1661 ASSERT_FALSE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
1662 good_crx,
1663 std::string(),
1664 GURL("http:://fake.update/url"),
1665 Manifest::EXTERNAL_PREF_DOWNLOAD,
1666 Extension::NO_FLAGS,
1667 false));
1669 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
1672 // Test that uninstalling an external extension does not crash when
1673 // the extension could not be loaded.
1674 // This extension shown in preferences file requires an experimental permission.
1675 // It could not be loaded without such permission.
1676 TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
1677 base::FilePath source_install_dir =
1678 data_dir().AppendASCII("good").AppendASCII("Extensions");
1679 // The preference contains an external extension
1680 // that requires 'experimental' permission.
1681 base::FilePath pref_path = source_install_dir
1682 .DirName()
1683 .AppendASCII("PreferencesExperimental");
1685 // Aforementioned extension will not be loaded if
1686 // there is no '--enable-experimental-extension-apis' command line flag.
1687 InitializeInstalledExtensionService(pref_path, source_install_dir);
1689 service()->Init();
1691 // Check and try to uninstall it.
1692 // If we don't check whether the extension is loaded before we uninstall it
1693 // in CheckExternalUninstall, a crash will happen here because we will get or
1694 // dereference a NULL pointer (extension) inside UninstallExtension.
1695 MockExtensionProvider provider(NULL, Manifest::EXTERNAL_REGISTRY);
1696 service()->OnExternalProviderReady(&provider);
1699 // Test that external extensions with incorrect IDs are not installed.
1700 TEST_F(ExtensionServiceTest, FailOnWrongId) {
1701 InitializeEmptyExtensionService();
1702 base::FilePath path = data_dir().AppendASCII("good.crx");
1703 service()->set_extensions_enabled(true);
1705 Version version("1.0.0.0");
1707 const std::string wrong_id = all_zero;
1708 const std::string correct_id = good_crx;
1709 ASSERT_NE(correct_id, wrong_id);
1711 // Install an external extension with an ID from the external
1712 // source that is not equal to the ID in the extension manifest.
1713 content::WindowedNotificationObserver observer(
1714 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1715 content::NotificationService::AllSources());
1716 service()->OnExternalExtensionFileFound(wrong_id,
1717 &version,
1718 path,
1719 Manifest::EXTERNAL_PREF,
1720 Extension::NO_FLAGS,
1721 false,
1722 false);
1724 observer.Wait();
1725 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1727 // Try again with the right ID. Expect success.
1728 content::WindowedNotificationObserver observer2(
1729 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1730 content::NotificationService::AllSources());
1731 if (service()->OnExternalExtensionFileFound(correct_id,
1732 &version,
1733 path,
1734 Manifest::EXTERNAL_PREF,
1735 Extension::NO_FLAGS,
1736 false,
1737 false)) {
1738 observer2.Wait();
1740 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1743 // Test that external extensions with incorrect versions are not installed.
1744 TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1745 InitializeEmptyExtensionService();
1746 base::FilePath path = data_dir().AppendASCII("good.crx");
1747 service()->set_extensions_enabled(true);
1749 // Install an external extension with a version from the external
1750 // source that is not equal to the version in the extension manifest.
1751 Version wrong_version("1.2.3.4");
1752 content::WindowedNotificationObserver observer(
1753 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1754 content::NotificationService::AllSources());
1755 service()->OnExternalExtensionFileFound(good_crx,
1756 &wrong_version,
1757 path,
1758 Manifest::EXTERNAL_PREF,
1759 Extension::NO_FLAGS,
1760 false,
1761 false);
1763 observer.Wait();
1764 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1766 // Try again with the right version. Expect success.
1767 service()->pending_extension_manager()->Remove(good_crx);
1768 Version correct_version("1.0.0.0");
1769 content::WindowedNotificationObserver observer2(
1770 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1771 content::NotificationService::AllSources());
1772 if (service()->OnExternalExtensionFileFound(good_crx,
1773 &correct_version,
1774 path,
1775 Manifest::EXTERNAL_PREF,
1776 Extension::NO_FLAGS,
1777 false,
1778 false)) {
1779 observer2.Wait();
1781 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1784 // Install a user script (they get converted automatically to an extension)
1785 TEST_F(ExtensionServiceTest, InstallUserScript) {
1786 // The details of script conversion are tested elsewhere, this just tests
1787 // integration with ExtensionService.
1788 InitializeEmptyExtensionService();
1790 base::FilePath path = data_dir().AppendASCII("user_script_basic.user.js");
1792 ASSERT_TRUE(base::PathExists(path));
1793 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1794 installer->set_allow_silent_install(true);
1795 installer->InstallUserScript(
1796 path,
1797 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1799 base::RunLoop().RunUntilIdle();
1800 std::vector<base::string16> errors = GetErrors();
1801 EXPECT_TRUE(installed_) << "Nothing was installed.";
1802 EXPECT_FALSE(was_update_) << path.value();
1803 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1804 EXPECT_EQ(0u, errors.size())
1805 << "There were errors: "
1806 << base::JoinString(errors, base::ASCIIToUTF16(","));
1807 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false))
1808 << path.value();
1810 installed_ = NULL;
1811 was_update_ = false;
1812 loaded_.clear();
1813 ExtensionErrorReporter::GetInstance()->ClearErrors();
1816 // Extensions don't install during shutdown.
1817 TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
1818 InitializeEmptyExtensionService();
1820 // Simulate shutdown.
1821 service()->set_browser_terminating_for_test(true);
1823 base::FilePath path = data_dir().AppendASCII("good.crx");
1824 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1825 installer->set_allow_silent_install(true);
1826 installer->InstallCrx(path);
1827 base::RunLoop().RunUntilIdle();
1829 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
1830 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
1833 // This tests that the granted permissions preferences are correctly set when
1834 // installing an extension.
1835 TEST_F(ExtensionServiceTest, GrantedPermissions) {
1836 InitializeEmptyExtensionService();
1837 base::FilePath path = data_dir().AppendASCII("permissions");
1839 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1840 path = path.AppendASCII("unknown");
1842 ASSERT_TRUE(base::PathExists(pem_path));
1843 ASSERT_TRUE(base::PathExists(path));
1845 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1847 APIPermissionSet expected_api_perms;
1848 URLPatternSet expected_host_perms;
1850 // Make sure there aren't any granted permissions before the
1851 // extension is installed.
1852 scoped_refptr<PermissionSet> known_perms(
1853 prefs->GetGrantedPermissions(permissions_crx));
1854 EXPECT_FALSE(known_perms.get());
1856 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
1858 EXPECT_EQ(0u, GetErrors().size());
1859 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1860 EXPECT_EQ(permissions_crx, extension->id());
1862 // Verify that the valid API permissions have been recognized.
1863 expected_api_perms.insert(APIPermission::kTab);
1865 AddPattern(&expected_host_perms, "http://*.google.com/*");
1866 AddPattern(&expected_host_perms, "https://*.google.com/*");
1867 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
1868 AddPattern(&expected_host_perms, "http://www.example.com/*");
1870 known_perms = prefs->GetGrantedPermissions(extension->id());
1871 EXPECT_TRUE(known_perms.get());
1872 EXPECT_FALSE(known_perms->IsEmpty());
1873 EXPECT_EQ(expected_api_perms, known_perms->apis());
1874 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1875 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
1879 #if !defined(OS_CHROMEOS)
1880 // This tests that the granted permissions preferences are correctly set for
1881 // default apps.
1882 TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
1883 InitializeEmptyExtensionService();
1884 base::FilePath path = data_dir().AppendASCII("permissions");
1886 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1887 path = path.AppendASCII("unknown");
1889 ASSERT_TRUE(base::PathExists(pem_path));
1890 ASSERT_TRUE(base::PathExists(path));
1892 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1894 APIPermissionSet expected_api_perms;
1895 URLPatternSet expected_host_perms;
1897 // Make sure there aren't any granted permissions before the
1898 // extension is installed.
1899 scoped_refptr<PermissionSet> known_perms(
1900 prefs->GetGrantedPermissions(permissions_crx));
1901 EXPECT_FALSE(known_perms.get());
1903 const Extension* extension = PackAndInstallCRX(
1904 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
1906 EXPECT_EQ(0u, GetErrors().size());
1907 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1908 EXPECT_EQ(permissions_crx, extension->id());
1910 // Verify that the valid API permissions have been recognized.
1911 expected_api_perms.insert(APIPermission::kTab);
1913 known_perms = prefs->GetGrantedPermissions(extension->id());
1914 EXPECT_TRUE(known_perms.get());
1915 EXPECT_FALSE(known_perms->IsEmpty());
1916 EXPECT_EQ(expected_api_perms, known_perms->apis());
1917 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1919 #endif
1921 #if !defined(OS_POSIX) || defined(OS_MACOSX)
1922 // Tests that the granted permissions full_access bit gets set correctly when
1923 // an extension contains an NPAPI plugin.
1924 // Only run this on platforms that support NPAPI plugins.
1925 TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
1926 InitPluginService();
1928 InitializeEmptyExtensionService();
1930 ASSERT_TRUE(base::PathExists(good1_path()));
1931 const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW);
1932 EXPECT_EQ(0u, GetErrors().size());
1933 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1934 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1936 scoped_refptr<PermissionSet> permissions(
1937 prefs->GetGrantedPermissions(extension->id()));
1938 EXPECT_FALSE(permissions->IsEmpty());
1939 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
1940 EXPECT_FALSE(permissions->apis().empty());
1941 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
1943 // Full access implies full host access too...
1944 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
1946 #endif
1948 // Tests that the extension is disabled when permissions are missing from
1949 // the extension's granted permissions preferences. (This simulates updating
1950 // the browser to a version which recognizes more permissions).
1951 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
1952 InitializeEmptyExtensionService();
1954 base::FilePath path =
1955 data_dir().AppendASCII("permissions").AppendASCII("unknown");
1957 ASSERT_TRUE(base::PathExists(path));
1959 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
1961 EXPECT_EQ(0u, GetErrors().size());
1962 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1963 std::string extension_id = extension->id();
1965 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1967 APIPermissionSet expected_api_permissions;
1968 URLPatternSet expected_host_permissions;
1970 expected_api_permissions.insert(APIPermission::kTab);
1971 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1972 AddPattern(&expected_host_permissions, "https://*.google.com/*");
1973 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
1974 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1976 std::set<std::string> host_permissions;
1978 // Test that the extension is disabled when an API permission is missing from
1979 // the extension's granted api permissions preference. (This simulates
1980 // updating the browser to a version which recognizes a new API permission).
1981 SetPref(extension_id, "granted_permissions.api",
1982 new base::ListValue(), "granted_permissions.api");
1983 service()->ReloadExtensionsForTest();
1985 EXPECT_EQ(1u, registry()->disabled_extensions().size());
1986 extension = registry()->disabled_extensions().begin()->get();
1988 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
1989 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
1990 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1992 // Now grant and re-enable the extension, making sure the prefs are updated.
1993 service()->GrantPermissionsAndEnableExtension(extension);
1995 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
1996 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
1997 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1999 scoped_refptr<PermissionSet> current_perms(
2000 prefs->GetGrantedPermissions(extension_id));
2001 ASSERT_TRUE(current_perms.get());
2002 ASSERT_FALSE(current_perms->IsEmpty());
2003 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2004 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2005 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2007 // Tests that the extension is disabled when a host permission is missing from
2008 // the extension's granted host permissions preference. (This simulates
2009 // updating the browser to a version which recognizes additional host
2010 // permissions).
2011 host_permissions.clear();
2012 current_perms = NULL;
2014 host_permissions.insert("http://*.google.com/*");
2015 host_permissions.insert("https://*.google.com/*");
2016 host_permissions.insert("http://*.google.com.hk/*");
2018 base::ListValue* api_permissions = new base::ListValue();
2019 api_permissions->Append(
2020 new base::StringValue("tabs"));
2021 SetPref(extension_id, "granted_permissions.api",
2022 api_permissions, "granted_permissions.api");
2023 SetPrefStringSet(
2024 extension_id, "granted_permissions.scriptable_host", host_permissions);
2026 service()->ReloadExtensionsForTest();
2028 EXPECT_EQ(1u, registry()->disabled_extensions().size());
2029 extension = registry()->disabled_extensions().begin()->get();
2031 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2032 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
2033 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2035 // Now grant and re-enable the extension, making sure the prefs are updated.
2036 service()->GrantPermissionsAndEnableExtension(extension);
2038 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
2039 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2041 current_perms = prefs->GetGrantedPermissions(extension_id);
2042 ASSERT_TRUE(current_perms.get());
2043 ASSERT_FALSE(current_perms->IsEmpty());
2044 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2045 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2046 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2049 // Test Packaging and installing an extension.
2050 TEST_F(ExtensionServiceTest, PackExtension) {
2051 InitializeEmptyExtensionService();
2052 base::FilePath input_directory =
2053 data_dir()
2054 .AppendASCII("good")
2055 .AppendASCII("Extensions")
2056 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2057 .AppendASCII("1.0.0.0");
2059 base::ScopedTempDir temp_dir;
2060 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2061 base::FilePath output_directory = temp_dir.path();
2063 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2064 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2066 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2067 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2068 privkey_path, ExtensionCreator::kNoRunFlags));
2069 ASSERT_TRUE(base::PathExists(crx_path));
2070 ASSERT_TRUE(base::PathExists(privkey_path));
2072 // Repeat the run with the pem file gone, and no special flags
2073 // Should refuse to overwrite the existing crx.
2074 base::DeleteFile(privkey_path, false);
2075 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2076 privkey_path, ExtensionCreator::kNoRunFlags));
2078 // OK, now try it with a flag to overwrite existing crx. Should work.
2079 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2080 privkey_path, ExtensionCreator::kOverwriteCRX));
2082 // Repeat the run allowing existing crx, but the existing pem is still
2083 // an error. Should fail.
2084 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2085 privkey_path, ExtensionCreator::kOverwriteCRX));
2087 ASSERT_TRUE(base::PathExists(privkey_path));
2088 InstallCRX(crx_path, INSTALL_NEW);
2090 // Try packing with invalid paths.
2091 creator.reset(new ExtensionCreator());
2092 ASSERT_FALSE(
2093 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
2094 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2096 // Try packing an empty directory. Should fail because an empty directory is
2097 // not a valid extension.
2098 base::ScopedTempDir temp_dir2;
2099 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
2100 creator.reset(new ExtensionCreator());
2101 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2102 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2104 // Try packing with an invalid manifest.
2105 std::string invalid_manifest_content = "I am not a manifest.";
2106 ASSERT_TRUE(base::WriteFile(
2107 temp_dir2.path().Append(extensions::kManifestFilename),
2108 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
2109 creator.reset(new ExtensionCreator());
2110 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2111 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2113 // Try packing with a private key that is a valid key, but invalid for the
2114 // extension.
2115 base::FilePath bad_private_key_dir =
2116 data_dir().AppendASCII("bad_private_key");
2117 crx_path = output_directory.AppendASCII("bad_private_key.crx");
2118 privkey_path = data_dir().AppendASCII("bad_private_key.pem");
2119 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
2120 privkey_path, ExtensionCreator::kOverwriteCRX));
2123 // Test Packaging and installing an extension whose name contains punctuation.
2124 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
2125 InitializeEmptyExtensionService();
2126 base::FilePath input_directory = data_dir()
2127 .AppendASCII("good")
2128 .AppendASCII("Extensions")
2129 .AppendASCII(good0)
2130 .AppendASCII("1.0.0.0");
2132 base::ScopedTempDir temp_dir;
2133 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2135 // Extension names containing punctuation, and the expected names for the
2136 // packed extensions.
2137 const base::FilePath punctuated_names[] = {
2138 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2139 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2140 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
2141 NormalizePathSeparators(),
2143 const base::FilePath expected_crx_names[] = {
2144 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2145 base::FilePath(
2146 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2147 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
2149 const base::FilePath expected_private_key_names[] = {
2150 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2151 base::FilePath(
2152 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2153 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
2156 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
2157 SCOPED_TRACE(punctuated_names[i].value().c_str());
2158 base::FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
2160 // Copy the extension into the output directory, as PackExtensionJob doesn't
2161 // let us choose where to output the packed extension.
2162 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
2164 base::FilePath expected_crx_path =
2165 temp_dir.path().Append(expected_crx_names[i]);
2166 base::FilePath expected_private_key_path =
2167 temp_dir.path().Append(expected_private_key_names[i]);
2168 PackExtensionTestClient pack_client(expected_crx_path,
2169 expected_private_key_path);
2170 scoped_refptr<extensions::PackExtensionJob> packer(
2171 new extensions::PackExtensionJob(&pack_client, output_dir,
2172 base::FilePath(),
2173 ExtensionCreator::kOverwriteCRX));
2174 packer->Start();
2176 // The packer will post a notification task to the current thread's message
2177 // loop when it is finished. We manually run the loop here so that we
2178 // block and catch the notification; otherwise, the process would exit.
2179 // This call to |Run()| is matched by a call to |Quit()| in the
2180 // |PackExtensionTestClient|'s notification handling code.
2181 base::MessageLoop::current()->Run();
2183 if (HasFatalFailure())
2184 return;
2186 InstallCRX(expected_crx_path, INSTALL_NEW);
2190 TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
2191 InitializeEmptyExtensionService();
2193 base::ScopedTempDir extension_temp_dir;
2194 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
2195 base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
2196 ASSERT_TRUE(
2197 base::CopyDirectory(data_dir()
2198 .AppendASCII("good")
2199 .AppendASCII("Extensions")
2200 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2201 .AppendASCII("1.0.0.0"),
2202 input_directory,
2203 /*recursive=*/true));
2205 base::ScopedTempDir output_temp_dir;
2206 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
2207 base::FilePath output_directory = output_temp_dir.path();
2209 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2210 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2212 // Pack the extension once to get a private key.
2213 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2214 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2215 privkey_path, ExtensionCreator::kNoRunFlags))
2216 << creator->error_message();
2217 ASSERT_TRUE(base::PathExists(crx_path));
2218 ASSERT_TRUE(base::PathExists(privkey_path));
2220 base::DeleteFile(crx_path, false);
2221 // Move the pem file into the extension.
2222 base::Move(privkey_path,
2223 input_directory.AppendASCII("privkey.pem"));
2225 // This pack should fail because of the contained private key.
2226 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2227 privkey_path, ExtensionCreator::kNoRunFlags));
2228 EXPECT_THAT(creator->error_message(),
2229 testing::ContainsRegex(
2230 "extension includes the key file.*privkey.pem"));
2233 // Test Packaging and installing an extension using an openssl generated key.
2234 // The openssl is generated with the following:
2235 // > openssl genrsa -out privkey.pem 1024
2236 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
2237 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
2238 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
2239 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
2240 InitializeEmptyExtensionService();
2241 base::FilePath input_directory =
2242 data_dir()
2243 .AppendASCII("good")
2244 .AppendASCII("Extensions")
2245 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2246 .AppendASCII("1.0.0.0");
2247 base::FilePath privkey_path(
2248 data_dir().AppendASCII("openssl_privkey_asn1.pem"));
2249 ASSERT_TRUE(base::PathExists(privkey_path));
2251 base::ScopedTempDir temp_dir;
2252 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2253 base::FilePath output_directory = temp_dir.path();
2255 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2257 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2258 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
2259 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2261 InstallCRX(crx_path, INSTALL_NEW);
2264 #if defined(THREAD_SANITIZER)
2265 // Flaky under Tsan. http://crbug.com/377702
2266 #define MAYBE_InstallTheme DISABLED_InstallTheme
2267 #else
2268 #define MAYBE_InstallTheme InstallTheme
2269 #endif
2271 TEST_F(ExtensionServiceTest, MAYBE_InstallTheme) {
2272 InitializeEmptyExtensionService();
2273 service()->Init();
2275 // A theme.
2276 base::FilePath path = data_dir().AppendASCII("theme.crx");
2277 InstallCRX(path, INSTALL_NEW);
2278 int pref_count = 0;
2279 ValidatePrefKeyCount(++pref_count);
2280 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2281 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2283 // A theme when extensions are disabled. Themes can be installed, even when
2284 // extensions are disabled.
2285 service()->set_extensions_enabled(false);
2286 path = data_dir().AppendASCII("theme2.crx");
2287 InstallCRX(path, INSTALL_NEW);
2288 ValidatePrefKeyCount(++pref_count);
2289 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
2290 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
2292 // A theme with extension elements. Themes cannot have extension elements,
2293 // so any such elements (like content scripts) should be ignored.
2294 service()->set_extensions_enabled(true);
2296 path = data_dir().AppendASCII("theme_with_extension.crx");
2297 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2298 ValidatePrefKeyCount(++pref_count);
2299 ASSERT_TRUE(extension);
2300 EXPECT_TRUE(extension->is_theme());
2301 EXPECT_EQ(
2303 extensions::ContentScriptsInfo::GetContentScripts(extension).size());
2306 // A theme with image resources missing (misspelt path).
2307 path = data_dir().AppendASCII("theme_missing_image.crx");
2308 InstallCRX(path, INSTALL_FAILED);
2309 ValidatePrefKeyCount(pref_count);
2312 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
2313 // Load.
2314 InitializeEmptyExtensionService();
2315 service()->Init();
2317 base::FilePath extension_path = data_dir().AppendASCII("theme_i18n");
2319 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2320 base::RunLoop().RunUntilIdle();
2321 EXPECT_EQ(0u, GetErrors().size());
2322 ASSERT_EQ(1u, loaded_.size());
2323 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2324 const Extension* theme = registry()->enabled_extensions().begin()->get();
2325 EXPECT_EQ("name", theme->name());
2326 EXPECT_EQ("description", theme->description());
2328 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a
2329 // temporary directory, but it automatically installs to the extension's
2330 // directory, and we don't want to copy the whole extension for a unittest.
2331 base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
2332 ASSERT_TRUE(base::PathExists(theme_file));
2333 ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive.
2336 #if defined(OS_POSIX)
2337 TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
2338 base::FilePath source_data_dir =
2339 data_dir().AppendASCII("unpacked").AppendASCII("symlinks_allowed");
2341 // Paths to test data files.
2342 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2343 ASSERT_TRUE(base::PathExists(source_manifest));
2344 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2345 ASSERT_TRUE(base::PathExists(source_icon));
2347 // Set up the temporary extension directory.
2348 base::ScopedTempDir temp;
2349 ASSERT_TRUE(temp.CreateUniqueTempDir());
2350 base::FilePath extension_path = temp.path();
2351 base::FilePath manifest = extension_path.Append(
2352 extensions::kManifestFilename);
2353 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2354 base::CopyFile(source_manifest, manifest);
2355 base::CreateSymbolicLink(source_icon, icon_symlink);
2357 // Load extension.
2358 InitializeEmptyExtensionService();
2359 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2360 base::RunLoop().RunUntilIdle();
2362 EXPECT_TRUE(GetErrors().empty());
2363 ASSERT_EQ(1u, loaded_.size());
2364 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2366 #endif
2368 TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
2369 InitializeEmptyExtensionService();
2370 base::FilePath extension_path = data_dir().AppendASCII("underscore_name");
2371 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2372 base::RunLoop().RunUntilIdle();
2373 EXPECT_EQ(1u, GetErrors().size());
2374 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2377 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
2378 InitializeEmptyExtensionService();
2379 service()->Init();
2381 base::FilePath theme_path = data_dir().AppendASCII("theme_i18n");
2383 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
2385 EXPECT_EQ(0u, GetErrors().size());
2386 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2387 EXPECT_EQ("name", theme->name());
2388 EXPECT_EQ("description", theme->description());
2391 TEST_F(ExtensionServiceTest, InstallApps) {
2392 InitializeEmptyExtensionService();
2394 // An empty app.
2395 const Extension* app =
2396 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2397 int pref_count = 0;
2398 ValidatePrefKeyCount(++pref_count);
2399 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2400 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2401 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
2403 // Another app with non-overlapping extent. Should succeed.
2404 PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2405 ValidatePrefKeyCount(++pref_count);
2407 // A third app whose extent overlaps the first. Should fail.
2408 PackAndInstallCRX(data_dir().AppendASCII("app3"), INSTALL_FAILED);
2409 ValidatePrefKeyCount(pref_count);
2412 // Tests that file access is OFF by default.
2413 TEST_F(ExtensionServiceTest, DefaultFileAccess) {
2414 InitializeEmptyExtensionService();
2415 const Extension* extension = PackAndInstallCRX(
2416 data_dir().AppendASCII("permissions").AppendASCII("files"), INSTALL_NEW);
2417 EXPECT_EQ(0u, GetErrors().size());
2418 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2419 EXPECT_FALSE(
2420 ExtensionPrefs::Get(profile())->AllowFileAccess(extension->id()));
2423 TEST_F(ExtensionServiceTest, UpdateApps) {
2424 InitializeEmptyExtensionService();
2425 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2427 // First install v1 of a hosted app.
2428 const Extension* extension =
2429 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2430 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2431 std::string id = extension->id();
2432 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2434 // Now try updating to v2.
2435 UpdateExtension(id,
2436 extensions_path.AppendASCII("v2.crx"),
2437 ENABLED);
2438 ASSERT_EQ(std::string("2"),
2439 service()->GetExtensionById(id, false)->version()->GetString());
2442 // Verifies that the NTP page and launch ordinals are kept when updating apps.
2443 TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
2444 InitializeEmptyExtensionService();
2445 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2446 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2448 // First install v1 of a hosted app.
2449 const Extension* extension =
2450 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2451 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2452 std::string id = extension->id();
2453 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2455 // Modify the ordinals so we can distinguish them from the defaults.
2456 syncer::StringOrdinal new_page_ordinal =
2457 sorting->GetPageOrdinal(id).CreateAfter();
2458 syncer::StringOrdinal new_launch_ordinal =
2459 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2461 sorting->SetPageOrdinal(id, new_page_ordinal);
2462 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2464 // Now try updating to v2.
2465 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2466 ASSERT_EQ(std::string("2"),
2467 service()->GetExtensionById(id, false)->version()->GetString());
2469 // Verify that the ordinals match.
2470 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2471 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
2474 // Ensures that the CWS has properly initialized ordinals.
2475 TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
2476 InitializeEmptyExtensionService();
2477 service()->component_loader()->Add(
2478 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
2479 service()->Init();
2481 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2482 EXPECT_TRUE(
2483 sorting->GetPageOrdinal(extensions::kWebStoreAppId).IsValid());
2484 EXPECT_TRUE(
2485 sorting->GetAppLaunchOrdinal(extensions::kWebStoreAppId).IsValid());
2488 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
2489 InitializeEmptyExtensionService();
2490 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2492 int pref_count = 0;
2494 // Install app1 with unlimited storage.
2495 const Extension* extension =
2496 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2497 ValidatePrefKeyCount(++pref_count);
2498 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2499 const std::string id1 = extension->id();
2500 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2501 APIPermission::kUnlimitedStorage));
2502 EXPECT_TRUE(extension->web_extent().MatchesURL(
2503 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2504 const GURL origin1(
2505 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2506 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2507 origin1));
2509 // Install app2 from the same origin with unlimited storage.
2510 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2511 ValidatePrefKeyCount(++pref_count);
2512 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2513 const std::string id2 = extension->id();
2514 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2515 APIPermission::kUnlimitedStorage));
2516 EXPECT_TRUE(extension->web_extent().MatchesURL(
2517 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2518 const GURL origin2(
2519 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2520 EXPECT_EQ(origin1, origin2);
2521 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2522 origin2));
2524 // Uninstall one of them, unlimited storage should still be granted
2525 // to the origin.
2526 UninstallExtension(id1, false);
2527 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2528 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2529 origin1));
2531 // Uninstall the other, unlimited storage should be revoked.
2532 UninstallExtension(id2, false);
2533 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2534 EXPECT_FALSE(
2535 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2536 origin2));
2539 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
2540 InitializeEmptyExtensionService();
2541 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2543 int pref_count = 0;
2545 const Extension* extension =
2546 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2547 ValidatePrefKeyCount(++pref_count);
2548 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2549 EXPECT_TRUE(extension->is_app());
2550 const std::string id1 = extension->id();
2551 const GURL origin1(
2552 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2553 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2554 origin1));
2556 // App 4 has a different origin (maps.google.com).
2557 extension = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
2558 ValidatePrefKeyCount(++pref_count);
2559 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2560 const std::string id2 = extension->id();
2561 const GURL origin2(
2562 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2563 ASSERT_NE(origin1, origin2);
2564 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2565 origin2));
2567 UninstallExtension(id1, false);
2568 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2570 UninstallExtension(id2, false);
2572 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2573 EXPECT_FALSE(
2574 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2575 origin1));
2576 EXPECT_FALSE(
2577 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2578 origin2));
2581 // Test that when an extension version is reinstalled, nothing happens.
2582 TEST_F(ExtensionServiceTest, Reinstall) {
2583 InitializeEmptyExtensionService();
2585 // A simple extension that should install without error.
2586 base::FilePath path = data_dir().AppendASCII("good.crx");
2587 InstallCRX(path, INSTALL_NEW);
2589 ValidatePrefKeyCount(1);
2590 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2591 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2593 // Reinstall the same version, it should overwrite the previous one.
2594 InstallCRX(path, INSTALL_UPDATED);
2596 ValidatePrefKeyCount(1);
2597 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2598 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2601 // Test that we can determine if extensions came from the
2602 // Chrome web store.
2603 TEST_F(ExtensionServiceTest, FromWebStore) {
2604 InitializeEmptyExtensionService();
2606 // A simple extension that should install without error.
2607 base::FilePath path = data_dir().AppendASCII("good.crx");
2608 // Not from web store.
2609 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2610 std::string id = extension->id();
2612 ValidatePrefKeyCount(1);
2613 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
2614 ASSERT_FALSE(extension->from_webstore());
2616 // Test install from web store.
2617 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
2619 ValidatePrefKeyCount(1);
2620 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2622 // Reload so extension gets reinitialized with new value.
2623 service()->ReloadExtensionsForTest();
2624 extension = service()->GetExtensionById(id, false);
2625 ASSERT_TRUE(extension->from_webstore());
2627 // Upgrade to version 2.0
2628 path = data_dir().AppendASCII("good2.crx");
2629 UpdateExtension(good_crx, path, ENABLED);
2630 ValidatePrefKeyCount(1);
2631 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2634 // Test upgrading a signed extension.
2635 TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
2636 InitializeEmptyExtensionService();
2638 base::FilePath path = data_dir().AppendASCII("good.crx");
2639 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2640 std::string id = extension->id();
2642 ASSERT_EQ("1.0.0.0", extension->version()->GetString());
2643 ASSERT_EQ(0u, GetErrors().size());
2645 // Upgrade to version 1.0.0.1.
2646 // Also test that the extension's old and new title are correctly retrieved.
2647 path = data_dir().AppendASCII("good2.crx");
2648 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
2649 extension = service()->GetExtensionById(id, false);
2651 ASSERT_EQ("1.0.0.1", extension->version()->GetString());
2652 ASSERT_EQ("My updated extension 1", extension->name());
2653 ASSERT_EQ(0u, GetErrors().size());
2656 // Test upgrading a signed extension with a bad signature.
2657 TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
2658 InitializeEmptyExtensionService();
2660 base::FilePath path = data_dir().AppendASCII("good.crx");
2661 InstallCRX(path, INSTALL_NEW);
2663 // Try upgrading with a bad signature. This should fail during the unpack,
2664 // because the key will not match the signature.
2665 path = data_dir().AppendASCII("bad_signature.crx");
2666 InstallCRX(path, INSTALL_FAILED);
2669 // Test a normal update via the UpdateExtension API
2670 TEST_F(ExtensionServiceTest, UpdateExtension) {
2671 InitializeEmptyExtensionService();
2673 base::FilePath path = data_dir().AppendASCII("good.crx");
2675 const Extension* good = InstallCRX(path, INSTALL_NEW);
2676 ASSERT_EQ("1.0.0.0", good->VersionString());
2677 ASSERT_EQ(good_crx, good->id());
2679 path = data_dir().AppendASCII("good2.crx");
2680 UpdateExtension(good_crx, path, ENABLED);
2681 ASSERT_EQ(
2682 "1.0.0.1",
2683 service()->GetExtensionById(good_crx, false)->version()->GetString());
2686 // Extensions should not be updated during browser shutdown.
2687 TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
2688 InitializeEmptyExtensionService();
2690 // Install an extension.
2691 base::FilePath path = data_dir().AppendASCII("good.crx");
2692 const Extension* good = InstallCRX(path, INSTALL_NEW);
2693 ASSERT_EQ(good_crx, good->id());
2695 // Simulate shutdown.
2696 service()->set_browser_terminating_for_test(true);
2698 // Update should fail and extension should not be updated.
2699 path = data_dir().AppendASCII("good2.crx");
2700 bool updated = service()->UpdateExtension(
2701 extensions::CRXFileInfo(good_crx, path), true, NULL);
2702 ASSERT_FALSE(updated);
2703 ASSERT_EQ(
2704 "1.0.0.0",
2705 service()->GetExtensionById(good_crx, false)->version()->GetString());
2708 // Test updating a not-already-installed extension - this should fail
2709 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
2710 InitializeEmptyExtensionService();
2712 base::FilePath path = data_dir().AppendASCII("good.crx");
2713 UpdateExtension(good_crx, path, UPDATED);
2714 base::RunLoop().RunUntilIdle();
2716 ASSERT_EQ(0u, registry()->enabled_extensions().size());
2717 ASSERT_FALSE(installed_);
2718 ASSERT_EQ(0u, loaded_.size());
2721 // Makes sure you can't downgrade an extension via UpdateExtension
2722 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
2723 InitializeEmptyExtensionService();
2725 base::FilePath path = data_dir().AppendASCII("good2.crx");
2727 const Extension* good = InstallCRX(path, INSTALL_NEW);
2728 ASSERT_EQ("1.0.0.1", good->VersionString());
2729 ASSERT_EQ(good_crx, good->id());
2731 // Change path from good2.crx -> good.crx
2732 path = data_dir().AppendASCII("good.crx");
2733 UpdateExtension(good_crx, path, FAILED);
2734 ASSERT_EQ(
2735 "1.0.0.1",
2736 service()->GetExtensionById(good_crx, false)->version()->GetString());
2739 // Make sure calling update with an identical version does nothing
2740 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
2741 InitializeEmptyExtensionService();
2743 base::FilePath path = data_dir().AppendASCII("good.crx");
2745 const Extension* good = InstallCRX(path, INSTALL_NEW);
2746 ASSERT_EQ(good_crx, good->id());
2747 UpdateExtension(good_crx, path, FAILED_SILENTLY);
2750 // Tests that updating an extension does not clobber old state.
2751 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
2752 InitializeEmptyExtensionService();
2754 base::FilePath path = data_dir().AppendASCII("good.crx");
2756 const Extension* good = InstallCRX(path, INSTALL_NEW);
2757 ASSERT_EQ("1.0.0.0", good->VersionString());
2758 ASSERT_EQ(good_crx, good->id());
2760 // Disable it and allow it to run in incognito. These settings should carry
2761 // over to the updated version.
2762 service()->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
2763 extensions::util::SetIsIncognitoEnabled(good->id(), profile(), true);
2765 path = data_dir().AppendASCII("good2.crx");
2766 UpdateExtension(good_crx, path, INSTALLED);
2767 ASSERT_EQ(1u, registry()->disabled_extensions().size());
2768 const Extension* good2 = service()->GetExtensionById(good_crx, true);
2769 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2770 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good2->id(), profile()));
2771 EXPECT_EQ(Extension::DISABLE_USER_ACTION,
2772 ExtensionPrefs::Get(profile())->GetDisableReasons(good2->id()));
2775 // Tests that updating preserves extension location.
2776 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
2777 InitializeEmptyExtensionService();
2779 base::FilePath path = data_dir().AppendASCII("good.crx");
2781 const Extension* good =
2782 InstallCRXWithLocation(path, Manifest::EXTERNAL_PREF, INSTALL_NEW);
2784 ASSERT_EQ("1.0.0.0", good->VersionString());
2785 ASSERT_EQ(good_crx, good->id());
2787 path = data_dir().AppendASCII("good2.crx");
2788 UpdateExtension(good_crx, path, ENABLED);
2789 const Extension* good2 = service()->GetExtensionById(good_crx, false);
2790 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2791 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
2794 // Makes sure that LOAD extension types can downgrade.
2795 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
2796 InitializeEmptyExtensionService();
2798 base::ScopedTempDir temp;
2799 ASSERT_TRUE(temp.CreateUniqueTempDir());
2801 // We'll write the extension manifest dynamically to a temporary path
2802 // to make it easier to change the version number.
2803 base::FilePath extension_path = temp.path();
2804 base::FilePath manifest_path =
2805 extension_path.Append(extensions::kManifestFilename);
2806 ASSERT_FALSE(base::PathExists(manifest_path));
2808 // Start with version 2.0.
2809 base::DictionaryValue manifest;
2810 manifest.SetString("version", "2.0");
2811 manifest.SetString("name", "LOAD Downgrade Test");
2812 manifest.SetInteger("manifest_version", 2);
2814 JSONFileValueSerializer serializer(manifest_path);
2815 ASSERT_TRUE(serializer.Serialize(manifest));
2817 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2818 base::RunLoop().RunUntilIdle();
2820 EXPECT_EQ(0u, GetErrors().size());
2821 ASSERT_EQ(1u, loaded_.size());
2822 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2823 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2824 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2826 // Now set the version number to 1.0, reload the extensions and verify that
2827 // the downgrade was accepted.
2828 manifest.SetString("version", "1.0");
2829 ASSERT_TRUE(serializer.Serialize(manifest));
2831 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2832 base::RunLoop().RunUntilIdle();
2834 EXPECT_EQ(0u, GetErrors().size());
2835 ASSERT_EQ(1u, loaded_.size());
2836 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2837 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2838 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2841 #if !defined(OS_POSIX) || defined(OS_MACOSX)
2842 // LOAD extensions with plugins require approval.
2843 // Only run this on platforms that support NPAPI plugins.
2844 TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
2845 base::FilePath extension_with_plugin_path = good1_path();
2846 base::FilePath extension_no_plugin_path = good2_path();
2848 InitPluginService();
2849 InitializeEmptyExtensionService();
2850 service()->set_show_extensions_prompts(true);
2852 // Start by canceling any install prompts.
2853 scoped_ptr<extensions::ScopedTestDialogAutoConfirm> auto_confirm(
2854 new extensions::ScopedTestDialogAutoConfirm(
2855 extensions::ScopedTestDialogAutoConfirm::CANCEL));
2857 // The extension that has a plugin should not install.
2858 extensions::UnpackedInstaller::Create(service())
2859 ->Load(extension_with_plugin_path);
2860 base::RunLoop().RunUntilIdle();
2861 EXPECT_EQ(0u, GetErrors().size());
2862 EXPECT_EQ(0u, loaded_.size());
2863 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2864 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2866 // But the extension with no plugin should since there's no prompt.
2867 ExtensionErrorReporter::GetInstance()->ClearErrors();
2868 extensions::UnpackedInstaller::Create(service())
2869 ->Load(extension_no_plugin_path);
2870 base::RunLoop().RunUntilIdle();
2871 EXPECT_EQ(0u, GetErrors().size());
2872 EXPECT_EQ(1u, loaded_.size());
2873 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2874 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2875 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2877 // The plugin extension should install if we accept the dialog.
2878 auto_confirm.reset();
2879 auto_confirm.reset(new extensions::ScopedTestDialogAutoConfirm(
2880 extensions::ScopedTestDialogAutoConfirm::ACCEPT));
2882 ExtensionErrorReporter::GetInstance()->ClearErrors();
2883 extensions::UnpackedInstaller::Create(service())
2884 ->Load(extension_with_plugin_path);
2885 base::RunLoop().RunUntilIdle();
2886 EXPECT_EQ(0u, GetErrors().size());
2887 EXPECT_EQ(2u, loaded_.size());
2888 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2889 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2890 EXPECT_TRUE(registry()->enabled_extensions().Contains(good1));
2891 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2893 // Make sure the granted permissions have been setup.
2894 scoped_refptr<PermissionSet> permissions(
2895 ExtensionPrefs::Get(profile())->GetGrantedPermissions(good1));
2896 EXPECT_FALSE(permissions->IsEmpty());
2897 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
2898 EXPECT_FALSE(permissions->apis().empty());
2899 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
2901 // We should be able to reload the extension without getting another prompt.
2902 loaded_.clear();
2903 auto_confirm.reset();
2904 auto_confirm.reset(new extensions::ScopedTestDialogAutoConfirm(
2905 extensions::ScopedTestDialogAutoConfirm::CANCEL));
2907 service()->ReloadExtension(good1);
2908 base::RunLoop().RunUntilIdle();
2909 EXPECT_EQ(1u, loaded_.size());
2910 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2911 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2913 #endif // !defined(OS_POSIX) || defined(OS_MACOSX)
2915 namespace {
2917 bool IsExtension(const Extension* extension) {
2918 return extension->GetType() == Manifest::TYPE_EXTENSION;
2921 #if defined(ENABLE_BLACKLIST_TESTS)
2922 std::set<std::string> StringSet(const std::string& s) {
2923 std::set<std::string> set;
2924 set.insert(s);
2925 return set;
2927 std::set<std::string> StringSet(const std::string& s1, const std::string& s2) {
2928 std::set<std::string> set = StringSet(s1);
2929 set.insert(s2);
2930 return set;
2932 #endif // defined(ENABLE_BLACKLIST_TESTS)
2934 } // namespace
2936 // Test adding a pending extension.
2937 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
2938 InitializeEmptyExtensionService();
2940 const std::string kFakeId(all_zero);
2941 const GURL kFakeUpdateURL("http:://fake.update/url");
2942 const bool kFakeRemoteInstall(false);
2943 const bool kFakeInstalledByCustodian(false);
2945 EXPECT_TRUE(
2946 service()->pending_extension_manager()->AddFromSync(
2947 kFakeId,
2948 kFakeUpdateURL,
2949 &IsExtension,
2950 kFakeRemoteInstall,
2951 kFakeInstalledByCustodian));
2953 const extensions::PendingExtensionInfo* pending_extension_info;
2954 ASSERT_TRUE((pending_extension_info =
2955 service()->pending_extension_manager()->GetById(kFakeId)));
2956 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
2957 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
2958 // Use
2959 // EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install())
2960 // instead of
2961 // EXPECT_EQ(kFakeRemoteInstall, pending_extension_info->remote_install())
2962 // as gcc 4.7 issues the following warning on EXPECT_EQ(false, x), which is
2963 // turned into an error with -Werror=conversion-null:
2964 // converting 'false' to pointer type for argument 1 of
2965 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)'
2966 // https://code.google.com/p/googletest/issues/detail?id=458
2967 EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install());
2970 namespace {
2971 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2972 const char kGoodUpdateURL[] = "http://good.update/url";
2973 const bool kGoodIsFromSync = true;
2974 const bool kGoodRemoteInstall = false;
2975 const bool kGoodInstalledByCustodian = false;
2976 } // namespace
2978 // Test updating a pending extension.
2979 TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
2980 InitializeEmptyExtensionService();
2981 EXPECT_TRUE(
2982 service()->pending_extension_manager()->AddFromSync(
2983 kGoodId,
2984 GURL(kGoodUpdateURL),
2985 &IsExtension,
2986 kGoodRemoteInstall,
2987 kGoodInstalledByCustodian));
2988 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2990 base::FilePath path = data_dir().AppendASCII("good.crx");
2991 UpdateExtension(kGoodId, path, ENABLED);
2993 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2995 const Extension* extension = service()->GetExtensionById(kGoodId, true);
2996 ASSERT_TRUE(extension);
2999 namespace {
3001 bool IsTheme(const Extension* extension) {
3002 return extension->is_theme();
3005 } // namespace
3007 // Test updating a pending theme.
3008 // Disabled due to ASAN failure. http://crbug.com/108320
3009 TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
3010 InitializeEmptyExtensionService();
3011 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3012 theme_crx, GURL(), &IsTheme, false, false));
3013 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3015 base::FilePath path = data_dir().AppendASCII("theme.crx");
3016 UpdateExtension(theme_crx, path, ENABLED);
3018 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3020 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3021 ASSERT_TRUE(extension);
3023 EXPECT_FALSE(
3024 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3025 EXPECT_TRUE(service()->IsExtensionEnabled(theme_crx));
3028 #if defined(OS_CHROMEOS)
3029 // Always fails on ChromeOS: http://crbug.com/79737
3030 #define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
3031 #else
3032 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
3033 #endif
3034 // Test updating a pending CRX as if the source is an external extension
3035 // with an update URL. In this case we don't know if the CRX is a theme
3036 // or not.
3037 TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
3038 InitializeEmptyExtensionService();
3039 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3040 theme_crx,
3041 std::string(),
3042 GURL(),
3043 Manifest::EXTERNAL_PREF_DOWNLOAD,
3044 Extension::NO_FLAGS,
3045 false));
3047 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3049 base::FilePath path = data_dir().AppendASCII("theme.crx");
3050 UpdateExtension(theme_crx, path, ENABLED);
3052 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3054 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3055 ASSERT_TRUE(extension);
3057 EXPECT_FALSE(
3058 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3059 EXPECT_TRUE(service()->IsExtensionEnabled(extension->id()));
3060 EXPECT_FALSE(
3061 extensions::util::IsIncognitoEnabled(extension->id(), profile()));
3064 // Test updating a pending CRX as if the source is an external extension
3065 // with an update URL. The external update should overwrite a sync update,
3066 // but a sync update should not overwrite a non-sync update.
3067 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
3068 InitializeEmptyExtensionService();
3070 // Add a crx to be installed from the update mechanism.
3071 EXPECT_TRUE(
3072 service()->pending_extension_manager()->AddFromSync(
3073 kGoodId,
3074 GURL(kGoodUpdateURL),
3075 &IsExtension,
3076 kGoodRemoteInstall,
3077 kGoodInstalledByCustodian));
3079 // Check that there is a pending crx, with is_from_sync set to true.
3080 const extensions::PendingExtensionInfo* pending_extension_info;
3081 ASSERT_TRUE((pending_extension_info =
3082 service()->pending_extension_manager()->GetById(kGoodId)));
3083 EXPECT_TRUE(pending_extension_info->is_from_sync());
3085 // Add a crx to be updated, with the same ID, from a non-sync source.
3086 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3087 kGoodId,
3088 std::string(),
3089 GURL(kGoodUpdateURL),
3090 Manifest::EXTERNAL_PREF_DOWNLOAD,
3091 Extension::NO_FLAGS,
3092 false));
3094 // Check that there is a pending crx, with is_from_sync set to false.
3095 ASSERT_TRUE((pending_extension_info =
3096 service()->pending_extension_manager()->GetById(kGoodId)));
3097 EXPECT_FALSE(pending_extension_info->is_from_sync());
3098 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3099 pending_extension_info->install_source());
3101 // Add a crx to be installed from the update mechanism.
3102 EXPECT_FALSE(
3103 service()->pending_extension_manager()->AddFromSync(
3104 kGoodId,
3105 GURL(kGoodUpdateURL),
3106 &IsExtension,
3107 kGoodRemoteInstall,
3108 kGoodInstalledByCustodian));
3110 // Check that the external, non-sync update was not overridden.
3111 ASSERT_TRUE((pending_extension_info =
3112 service()->pending_extension_manager()->GetById(kGoodId)));
3113 EXPECT_FALSE(pending_extension_info->is_from_sync());
3114 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3115 pending_extension_info->install_source());
3118 // Updating a theme should fail if the updater is explicitly told that
3119 // the CRX is not a theme.
3120 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
3121 InitializeEmptyExtensionService();
3122 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3123 theme_crx, GURL(), &IsExtension, false, false));
3125 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3127 base::FilePath path = data_dir().AppendASCII("theme.crx");
3128 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
3130 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3132 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3133 ASSERT_FALSE(extension);
3136 // TODO(akalin): Test updating a pending extension non-silently once
3137 // we can mock out ExtensionInstallUI and inject our version into
3138 // UpdateExtension().
3140 // Test updating a pending extension which fails the should-install test.
3141 TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
3142 InitializeEmptyExtensionService();
3143 // Add pending extension with a flipped is_theme.
3144 EXPECT_TRUE(
3145 service()->pending_extension_manager()->AddFromSync(
3146 kGoodId,
3147 GURL(kGoodUpdateURL),
3148 &IsTheme,
3149 kGoodRemoteInstall,
3150 kGoodInstalledByCustodian));
3151 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3153 base::FilePath path = data_dir().AppendASCII("good.crx");
3154 UpdateExtension(kGoodId, path, UPDATED);
3156 // TODO(akalin): Figure out how to check that the extensions
3157 // directory is cleaned up properly in OnExtensionInstalled().
3159 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3162 // TODO(akalin): Figure out how to test that installs of pending
3163 // unsyncable extensions are blocked.
3165 // Test updating a pending extension for one that is not pending.
3166 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
3167 InitializeEmptyExtensionService();
3169 base::FilePath path = data_dir().AppendASCII("good.crx");
3170 UpdateExtension(kGoodId, path, UPDATED);
3172 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3175 // Test updating a pending extension for one that is already
3176 // installed.
3177 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
3178 InitializeEmptyExtensionService();
3180 base::FilePath path = data_dir().AppendASCII("good.crx");
3181 const Extension* good = InstallCRX(path, INSTALL_NEW);
3182 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3184 EXPECT_FALSE(good->is_theme());
3186 // Use AddExtensionImpl() as AddFrom*() would balk.
3187 service()->pending_extension_manager()->AddExtensionImpl(
3188 good->id(),
3189 std::string(),
3190 extensions::ManifestURL::GetUpdateURL(good),
3191 Version(),
3192 &IsExtension,
3193 kGoodIsFromSync,
3194 Manifest::INTERNAL,
3195 Extension::NO_FLAGS,
3196 false,
3197 kGoodRemoteInstall);
3198 UpdateExtension(good->id(), path, ENABLED);
3200 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3203 #if defined(ENABLE_BLACKLIST_TESTS)
3204 // Tests blacklisting then unblacklisting extensions after the service has been
3205 // initialized.
3206 TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
3207 extensions::TestBlacklist test_blacklist;
3208 // A profile with 3 extensions installed: good0, good1, and good2.
3209 InitializeGoodInstalledExtensionService();
3210 test_blacklist.Attach(service()->blacklist_);
3211 service()->Init();
3213 const extensions::ExtensionSet& enabled_extensions =
3214 registry()->enabled_extensions();
3215 const extensions::ExtensionSet& blacklisted_extensions =
3216 registry()->blacklisted_extensions();
3218 EXPECT_TRUE(enabled_extensions.Contains(good0) &&
3219 !blacklisted_extensions.Contains(good0));
3220 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3221 !blacklisted_extensions.Contains(good1));
3222 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3223 !blacklisted_extensions.Contains(good2));
3225 EXPECT_FALSE(IsPrefExist(good0, "blacklist"));
3226 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3227 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3228 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3230 // Blacklist good0 and good1 (and an invalid extension ID).
3231 test_blacklist.SetBlacklistState(
3232 good0, extensions::BLACKLISTED_MALWARE, true);
3233 test_blacklist.SetBlacklistState(
3234 good1, extensions::BLACKLISTED_MALWARE, true);
3235 test_blacklist.SetBlacklistState(
3236 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3237 base::RunLoop().RunUntilIdle();
3239 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3240 blacklisted_extensions.Contains(good0));
3241 EXPECT_TRUE(!enabled_extensions.Contains(good1) &&
3242 blacklisted_extensions.Contains(good1));
3243 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3244 !blacklisted_extensions.Contains(good2));
3246 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3247 EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true));
3248 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3249 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3251 // Un-blacklist good1 and blacklist good2.
3252 test_blacklist.Clear(false);
3253 test_blacklist.SetBlacklistState(
3254 good0, extensions::BLACKLISTED_MALWARE, true);
3255 test_blacklist.SetBlacklistState(
3256 good2, extensions::BLACKLISTED_MALWARE, true);
3257 test_blacklist.SetBlacklistState(
3258 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3259 base::RunLoop().RunUntilIdle();
3261 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3262 blacklisted_extensions.Contains(good0));
3263 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3264 !blacklisted_extensions.Contains(good1));
3265 EXPECT_TRUE(!enabled_extensions.Contains(good2) &&
3266 blacklisted_extensions.Contains(good2));
3268 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3269 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3270 EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true));
3271 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3273 #endif // defined(ENABLE_BLACKLIST_TESTS)
3275 #if defined(ENABLE_BLACKLIST_TESTS)
3276 // Tests trying to install a blacklisted extension.
3277 TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
3278 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3279 new FakeSafeBrowsingDatabaseManager(true));
3280 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3282 InitializeEmptyExtensionService();
3283 service()->Init();
3285 // After blacklisting good_crx, we cannot install it.
3286 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
3287 base::RunLoop().RunUntilIdle();
3289 base::FilePath path = data_dir().AppendASCII("good.crx");
3290 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3291 // decide to install this silently. Somebody should fix these tests, all
3292 // 6,000 lines of them. Hah!
3293 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
3294 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3296 #endif // defined(ENABLE_BLACKLIST_TESTS)
3298 #if defined(ENABLE_BLACKLIST_TESTS)
3299 // Unload blacklisted extension on policy change.
3300 TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
3301 extensions::TestBlacklist test_blacklist;
3303 // A profile with no extensions installed.
3304 InitializeEmptyExtensionServiceWithTestingPrefs();
3305 test_blacklist.Attach(service()->blacklist_);
3307 base::FilePath path = data_dir().AppendASCII("good.crx");
3309 const Extension* good = InstallCRX(path, INSTALL_NEW);
3310 EXPECT_EQ(good_crx, good->id());
3311 UpdateExtension(good_crx, path, FAILED_SILENTLY);
3312 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3315 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3316 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3319 test_blacklist.SetBlacklistState(
3320 good_crx, extensions::BLACKLISTED_MALWARE, true);
3321 base::RunLoop().RunUntilIdle();
3323 // The good_crx is blacklisted and the whitelist doesn't negate it.
3324 ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true));
3325 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3327 #endif // defined(ENABLE_BLACKLIST_TESTS)
3329 #if defined(ENABLE_BLACKLIST_TESTS)
3330 // Tests that a blacklisted extension is eventually unloaded on startup, if it
3331 // wasn't already.
3332 TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
3333 extensions::TestBlacklist test_blacklist;
3335 // A profile with 3 extensions installed: good0, good1, and good2.
3336 InitializeGoodInstalledExtensionService();
3337 test_blacklist.Attach(service()->blacklist_);
3339 // Blacklist good1 before the service initializes.
3340 test_blacklist.SetBlacklistState(
3341 good1, extensions::BLACKLISTED_MALWARE, false);
3343 // Load extensions.
3344 service()->Init();
3345 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet
3347 base::RunLoop().RunUntilIdle();
3349 ASSERT_EQ(1u, registry()->blacklisted_extensions().size());
3350 ASSERT_EQ(2u, registry()->enabled_extensions().size());
3352 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
3353 ASSERT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3354 ASSERT_TRUE(registry()->enabled_extensions().Contains(good2));
3356 #endif // defined(ENABLE_BLACKLIST_TESTS)
3358 #if defined(ENABLE_BLACKLIST_TESTS)
3359 // Tests extensions blacklisted in prefs on startup; one still blacklisted by
3360 // safe browsing, the other not. The not-blacklisted one should recover.
3361 TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) {
3362 extensions::TestBlacklist test_blacklist;
3364 InitializeGoodInstalledExtensionService();
3365 test_blacklist.Attach(service()->blacklist_);
3366 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good0, true);
3367 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good1, true);
3369 test_blacklist.SetBlacklistState(
3370 good1, extensions::BLACKLISTED_MALWARE, false);
3372 // Extension service hasn't loaded yet, but IsExtensionEnabled reads out of
3373 // prefs. Ensure it takes into account the blacklist state (crbug.com/373842).
3374 EXPECT_FALSE(service()->IsExtensionEnabled(good0));
3375 EXPECT_FALSE(service()->IsExtensionEnabled(good1));
3376 EXPECT_TRUE(service()->IsExtensionEnabled(good2));
3378 service()->Init();
3380 EXPECT_EQ(2u, registry()->blacklisted_extensions().size());
3381 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3383 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good0));
3384 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3385 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3387 // Give time for the blacklist to update.
3388 base::RunLoop().RunUntilIdle();
3390 EXPECT_EQ(1u, registry()->blacklisted_extensions().size());
3391 EXPECT_EQ(2u, registry()->enabled_extensions().size());
3393 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3394 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3395 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3397 #endif // defined(ENABLE_BLACKLIST_TESTS)
3399 #if defined(ENABLE_BLACKLIST_TESTS)
3400 // Extension is added to blacklist with BLACKLISTED_POTENTIALLY_UNWANTED state
3401 // after it is installed. It is then successfully re-enabled by the user.
3402 TEST_F(ExtensionServiceTest, GreylistedExtensionDisabled) {
3403 extensions::TestBlacklist test_blacklist;
3404 // A profile with 3 extensions installed: good0, good1, and good2.
3405 InitializeGoodInstalledExtensionService();
3406 test_blacklist.Attach(service()->blacklist_);
3407 service()->Init();
3409 const extensions::ExtensionSet& enabled_extensions =
3410 registry()->enabled_extensions();
3411 const extensions::ExtensionSet& disabled_extensions =
3412 registry()->disabled_extensions();
3414 EXPECT_TRUE(enabled_extensions.Contains(good0));
3415 EXPECT_TRUE(enabled_extensions.Contains(good1));
3416 EXPECT_TRUE(enabled_extensions.Contains(good2));
3418 // Blacklist good0 and good1 (and an invalid extension ID).
3419 test_blacklist.SetBlacklistState(
3420 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3421 test_blacklist.SetBlacklistState(
3422 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3423 test_blacklist.SetBlacklistState(
3424 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3425 base::RunLoop().RunUntilIdle();
3427 EXPECT_FALSE(enabled_extensions.Contains(good0));
3428 EXPECT_TRUE(disabled_extensions.Contains(good0));
3429 EXPECT_FALSE(enabled_extensions.Contains(good1));
3430 EXPECT_TRUE(disabled_extensions.Contains(good1));
3431 EXPECT_TRUE(enabled_extensions.Contains(good2));
3432 EXPECT_FALSE(disabled_extensions.Contains(good2));
3434 ValidateIntegerPref(
3435 good0, "blacklist_state", extensions::BLACKLISTED_CWS_POLICY_VIOLATION);
3436 ValidateIntegerPref(
3437 good1, "blacklist_state", extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
3439 // Now user enables good0.
3440 service()->EnableExtension(good0);
3442 EXPECT_TRUE(enabled_extensions.Contains(good0));
3443 EXPECT_FALSE(disabled_extensions.Contains(good0));
3444 EXPECT_FALSE(enabled_extensions.Contains(good1));
3445 EXPECT_TRUE(disabled_extensions.Contains(good1));
3447 // Remove extensions from blacklist.
3448 test_blacklist.SetBlacklistState(
3449 good0, extensions::NOT_BLACKLISTED, true);
3450 test_blacklist.SetBlacklistState(
3451 good1, extensions::NOT_BLACKLISTED, true);
3452 base::RunLoop().RunUntilIdle();
3454 // All extensions are enabled.
3455 EXPECT_TRUE(enabled_extensions.Contains(good0));
3456 EXPECT_FALSE(disabled_extensions.Contains(good0));
3457 EXPECT_TRUE(enabled_extensions.Contains(good1));
3458 EXPECT_FALSE(disabled_extensions.Contains(good1));
3459 EXPECT_TRUE(enabled_extensions.Contains(good2));
3460 EXPECT_FALSE(disabled_extensions.Contains(good2));
3462 #endif // defined(ENABLE_BLACKLIST_TESTS)
3464 #if defined(ENABLE_BLACKLIST_TESTS)
3465 // When extension is removed from greylist, do not re-enable it if it is
3466 // disabled by user.
3467 TEST_F(ExtensionServiceTest, GreylistDontEnableManuallyDisabled) {
3468 extensions::TestBlacklist test_blacklist;
3469 // A profile with 3 extensions installed: good0, good1, and good2.
3470 InitializeGoodInstalledExtensionService();
3471 test_blacklist.Attach(service()->blacklist_);
3472 service()->Init();
3474 const extensions::ExtensionSet& enabled_extensions =
3475 registry()->enabled_extensions();
3476 const extensions::ExtensionSet& disabled_extensions =
3477 registry()->disabled_extensions();
3479 // Manually disable.
3480 service()->DisableExtension(good0,
3481 extensions::Extension::DISABLE_USER_ACTION);
3483 test_blacklist.SetBlacklistState(
3484 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3485 test_blacklist.SetBlacklistState(
3486 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3487 test_blacklist.SetBlacklistState(
3488 good2, extensions::BLACKLISTED_SECURITY_VULNERABILITY, true);
3489 base::RunLoop().RunUntilIdle();
3491 // All extensions disabled.
3492 EXPECT_FALSE(enabled_extensions.Contains(good0));
3493 EXPECT_TRUE(disabled_extensions.Contains(good0));
3494 EXPECT_FALSE(enabled_extensions.Contains(good1));
3495 EXPECT_TRUE(disabled_extensions.Contains(good1));
3496 EXPECT_FALSE(enabled_extensions.Contains(good2));
3497 EXPECT_TRUE(disabled_extensions.Contains(good2));
3499 // Greylisted extension can be enabled.
3500 service()->EnableExtension(good1);
3501 EXPECT_TRUE(enabled_extensions.Contains(good1));
3502 EXPECT_FALSE(disabled_extensions.Contains(good1));
3504 // good1 is now manually disabled.
3505 service()->DisableExtension(good1,
3506 extensions::Extension::DISABLE_USER_ACTION);
3507 EXPECT_FALSE(enabled_extensions.Contains(good1));
3508 EXPECT_TRUE(disabled_extensions.Contains(good1));
3510 // Remove extensions from blacklist.
3511 test_blacklist.SetBlacklistState(
3512 good0, extensions::NOT_BLACKLISTED, true);
3513 test_blacklist.SetBlacklistState(
3514 good1, extensions::NOT_BLACKLISTED, true);
3515 test_blacklist.SetBlacklistState(
3516 good2, extensions::NOT_BLACKLISTED, true);
3517 base::RunLoop().RunUntilIdle();
3519 // good0 and good1 remain disabled.
3520 EXPECT_FALSE(enabled_extensions.Contains(good0));
3521 EXPECT_TRUE(disabled_extensions.Contains(good0));
3522 EXPECT_FALSE(enabled_extensions.Contains(good1));
3523 EXPECT_TRUE(disabled_extensions.Contains(good1));
3524 EXPECT_TRUE(enabled_extensions.Contains(good2));
3525 EXPECT_FALSE(disabled_extensions.Contains(good2));
3527 #endif // defined(ENABLE_BLACKLIST_TESTS)
3529 #if defined(ENABLE_BLACKLIST_TESTS)
3530 // Blacklisted extension with unknown state are not enabled/disabled.
3531 TEST_F(ExtensionServiceTest, GreylistUnknownDontChange) {
3532 extensions::TestBlacklist test_blacklist;
3533 // A profile with 3 extensions installed: good0, good1, and good2.
3534 InitializeGoodInstalledExtensionService();
3535 test_blacklist.Attach(service()->blacklist_);
3536 service()->Init();
3538 const extensions::ExtensionSet& enabled_extensions =
3539 registry()->enabled_extensions();
3540 const extensions::ExtensionSet& disabled_extensions =
3541 registry()->disabled_extensions();
3543 test_blacklist.SetBlacklistState(
3544 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3545 test_blacklist.SetBlacklistState(
3546 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3547 base::RunLoop().RunUntilIdle();
3549 EXPECT_FALSE(enabled_extensions.Contains(good0));
3550 EXPECT_TRUE(disabled_extensions.Contains(good0));
3551 EXPECT_FALSE(enabled_extensions.Contains(good1));
3552 EXPECT_TRUE(disabled_extensions.Contains(good1));
3553 EXPECT_TRUE(enabled_extensions.Contains(good2));
3554 EXPECT_FALSE(disabled_extensions.Contains(good2));
3556 test_blacklist.SetBlacklistState(
3557 good0, extensions::NOT_BLACKLISTED, true);
3558 test_blacklist.SetBlacklistState(
3559 good1, extensions::BLACKLISTED_UNKNOWN, true);
3560 test_blacklist.SetBlacklistState(
3561 good2, extensions::BLACKLISTED_UNKNOWN, true);
3562 base::RunLoop().RunUntilIdle();
3564 // good0 re-enabled, other remain as they were.
3565 EXPECT_TRUE(enabled_extensions.Contains(good0));
3566 EXPECT_FALSE(disabled_extensions.Contains(good0));
3567 EXPECT_FALSE(enabled_extensions.Contains(good1));
3568 EXPECT_TRUE(disabled_extensions.Contains(good1));
3569 EXPECT_TRUE(enabled_extensions.Contains(good2));
3570 EXPECT_FALSE(disabled_extensions.Contains(good2));
3573 // Tests that blacklisted extensions cannot be reloaded, both those loaded
3574 // before and after extension service startup.
3575 TEST_F(ExtensionServiceTest, ReloadBlacklistedExtension) {
3576 extensions::TestBlacklist test_blacklist;
3578 InitializeGoodInstalledExtensionService();
3579 test_blacklist.Attach(service()->blacklist_);
3581 test_blacklist.SetBlacklistState(
3582 good1, extensions::BLACKLISTED_MALWARE, false);
3583 service()->Init();
3584 test_blacklist.SetBlacklistState(
3585 good2, extensions::BLACKLISTED_MALWARE, false);
3586 base::RunLoop().RunUntilIdle();
3588 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3589 EXPECT_EQ(StringSet(good1, good2),
3590 registry()->blacklisted_extensions().GetIDs());
3592 service()->ReloadExtension(good1);
3593 service()->ReloadExtension(good2);
3594 base::RunLoop().RunUntilIdle();
3596 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3597 EXPECT_EQ(StringSet(good1, good2),
3598 registry()->blacklisted_extensions().GetIDs());
3600 #endif // defined(ENABLE_BLACKLIST_TESTS)
3602 // Tests blocking then unblocking enabled extensions after the service has been
3603 // initialized.
3604 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledExtension) {
3605 InitializeGoodInstalledExtensionService();
3606 service()->Init();
3608 AssertExtensionBlocksAndUnblocks(true, good0);
3611 // Tests blocking then unblocking disabled extensions after the service has been
3612 // initialized.
3613 TEST_F(ExtensionServiceTest, BlockAndUnblockDisabledExtension) {
3614 InitializeGoodInstalledExtensionService();
3615 service()->Init();
3617 service()->DisableExtension(good0, Extension::DISABLE_RELOAD);
3619 AssertExtensionBlocksAndUnblocks(true, good0);
3622 // Tests blocking then unblocking terminated extensions after the service has
3623 // been initialized.
3624 TEST_F(ExtensionServiceTest, BlockAndUnblockTerminatedExtension) {
3625 InitializeGoodInstalledExtensionService();
3626 service()->Init();
3628 TerminateExtension(good0);
3630 AssertExtensionBlocksAndUnblocks(true, good0);
3633 // Tests blocking then unblocking policy-forced extensions after the service has
3634 // been initialized.
3635 TEST_F(ExtensionServiceTest, BlockAndUnblockPolicyExtension) {
3636 InitializeEmptyExtensionServiceWithTestingPrefs();
3639 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3640 // // Blacklist everything.
3641 // pref.SetBlacklistedByDefault(true);
3642 // Mark good.crx for force-installation.
3643 pref.SetIndividualExtensionAutoInstalled(
3644 good_crx, "http://example.com/update_url", true);
3647 // Have policy force-install an extension.
3648 MockExtensionProvider* provider =
3649 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3650 AddMockExternalProvider(provider);
3651 provider->UpdateOrAddExtension(
3652 good_crx, "1.0.0.0", data_dir().AppendASCII("good_crx"));
3654 // Reloading extensions should find our externally registered extension
3655 // and install it.
3656 content::WindowedNotificationObserver observer(
3657 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3658 content::NotificationService::AllSources());
3659 service()->CheckForExternalUpdates();
3660 observer.Wait();
3662 AssertExtensionBlocksAndUnblocks(false, good_crx);
3666 #if defined(ENABLE_BLACKLIST_TESTS)
3667 // Tests blocking then unblocking extensions that are blacklisted both before
3668 // and after Init().
3669 TEST_F(ExtensionServiceTest, BlockAndUnblockBlacklistedExtension) {
3670 extensions::TestBlacklist test_blacklist;
3672 InitializeGoodInstalledExtensionService();
3673 test_blacklist.Attach(service()->blacklist_);
3675 test_blacklist.SetBlacklistState(
3676 good0, extensions::BLACKLISTED_MALWARE, true);
3677 base::RunLoop().RunUntilIdle();
3679 service()->Init();
3681 test_blacklist.SetBlacklistState(
3682 good1, extensions::BLACKLISTED_MALWARE, true);
3683 base::RunLoop().RunUntilIdle();
3685 // Blacklisted extensions stay blacklisted.
3686 AssertExtensionBlocksAndUnblocks(false, good0);
3687 AssertExtensionBlocksAndUnblocks(false, good1);
3689 service()->BlockAllExtensions();
3691 // Remove an extension from the blacklist while the service is blocked.
3692 test_blacklist.SetBlacklistState(
3693 good0, extensions::NOT_BLACKLISTED, true);
3694 // Add an extension to the blacklist while the service is blocked.
3695 test_blacklist.SetBlacklistState(
3696 good2, extensions::BLACKLISTED_MALWARE, true);
3697 base::RunLoop().RunUntilIdle();
3699 // Go directly to blocked, do not pass go, do not collect $200.
3700 ASSERT_TRUE(IsBlocked(good0));
3701 // Get on the blacklist - even if you were blocked!
3702 ASSERT_FALSE(IsBlocked(good2));
3704 #endif // defined(ENABLE_BLACKLIST_TESTS)
3706 // Tests blocking then unblocking enabled component extensions after the service
3707 // has been initialized.
3708 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledComponentExtension) {
3709 InitializeEmptyExtensionServiceWithTestingPrefs();
3711 // Install a component extension.
3712 base::FilePath path = data_dir()
3713 .AppendASCII("good")
3714 .AppendASCII("Extensions")
3715 .AppendASCII(good0)
3716 .AppendASCII("1.0.0.0");
3717 std::string manifest;
3718 ASSERT_TRUE(base::ReadFileToString(
3719 path.Append(extensions::kManifestFilename), &manifest));
3720 service()->component_loader()->Add(manifest, path);
3721 service()->Init();
3723 // Component extension should never block.
3724 AssertExtensionBlocksAndUnblocks(false, good0);
3727 // Tests blocking then unblocking a theme after the service has been
3728 // initialized.
3729 TEST_F(ExtensionServiceTest, BlockAndUnblockTheme) {
3730 InitializeEmptyExtensionService();
3731 service()->Init();
3733 base::FilePath path = data_dir().AppendASCII("theme.crx");
3734 InstallCRX(path, INSTALL_NEW);
3736 AssertExtensionBlocksAndUnblocks(true, theme_crx);
3739 // Tests that blocking extensions before Init() results in loading blocked
3740 // extensions.
3741 TEST_F(ExtensionServiceTest, WillNotLoadExtensionsWhenBlocked) {
3742 InitializeGoodInstalledExtensionService();
3744 service()->BlockAllExtensions();
3746 service()->Init();
3748 ASSERT_TRUE(IsBlocked(good0));
3749 ASSERT_TRUE(IsBlocked(good0));
3750 ASSERT_TRUE(IsBlocked(good0));
3753 // Tests that IsEnabledExtension won't crash on an uninstalled extension.
3754 TEST_F(ExtensionServiceTest, IsEnabledExtensionBlockedAndNotInstalled) {
3755 InitializeEmptyExtensionService();
3757 service()->BlockAllExtensions();
3759 service()->IsExtensionEnabled(theme_crx);
3762 // Will not install extension blacklisted by policy.
3763 TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
3764 InitializeEmptyExtensionServiceWithTestingPrefs();
3766 // Blacklist everything.
3768 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3769 pref.SetBlacklistedByDefault(true);
3772 // Blacklist prevents us from installing good_crx.
3773 base::FilePath path = data_dir().AppendASCII("good.crx");
3774 InstallCRX(path, INSTALL_FAILED);
3775 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3777 // Now whitelist this particular extension.
3779 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3780 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3783 // Ensure we can now install good_crx.
3784 InstallCRX(path, INSTALL_NEW);
3785 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3788 // Extension blacklisted by policy get unloaded after installing.
3789 TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
3790 InitializeEmptyExtensionServiceWithTestingPrefs();
3792 // Install good_crx.
3793 base::FilePath path = data_dir().AppendASCII("good.crx");
3794 InstallCRX(path, INSTALL_NEW);
3795 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3798 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3799 // Blacklist this extension.
3800 pref.SetIndividualExtensionInstallationAllowed(good_crx, false);
3803 // Extension should not be running now.
3804 base::RunLoop().RunUntilIdle();
3805 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3808 // Tests that component extensions are not blacklisted by policy.
3809 TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
3810 InitializeEmptyExtensionServiceWithTestingPrefs();
3812 // Blacklist everything.
3814 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3815 pref.SetBlacklistedByDefault(true);
3818 // Install a component extension.
3819 base::FilePath path = data_dir()
3820 .AppendASCII("good")
3821 .AppendASCII("Extensions")
3822 .AppendASCII(good0)
3823 .AppendASCII("1.0.0.0");
3824 std::string manifest;
3825 ASSERT_TRUE(base::ReadFileToString(
3826 path.Append(extensions::kManifestFilename), &manifest));
3827 service()->component_loader()->Add(manifest, path);
3828 service()->Init();
3830 // Extension should be installed despite blacklist.
3831 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3832 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3834 // Poke external providers and make sure the extension is still present.
3835 service()->CheckForExternalUpdates();
3836 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3837 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3839 // Extension should not be uninstalled on blacklist changes.
3841 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3842 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3844 base::RunLoop().RunUntilIdle();
3845 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3846 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3849 // Tests that policy-installed extensions are not blacklisted by policy.
3850 TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
3851 InitializeEmptyExtensionServiceWithTestingPrefs();
3854 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3855 // Blacklist everything.
3856 pref.SetBlacklistedByDefault(true);
3857 // Mark good.crx for force-installation.
3858 pref.SetIndividualExtensionAutoInstalled(
3859 good_crx, "http://example.com/update_url", true);
3862 // Have policy force-install an extension.
3863 MockExtensionProvider* provider =
3864 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3865 AddMockExternalProvider(provider);
3866 provider->UpdateOrAddExtension(
3867 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
3869 // Reloading extensions should find our externally registered extension
3870 // and install it.
3871 content::WindowedNotificationObserver observer(
3872 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3873 content::NotificationService::AllSources());
3874 service()->CheckForExternalUpdates();
3875 observer.Wait();
3877 // Extension should be installed despite blacklist.
3878 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3879 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3881 // Blacklist update should not uninstall the extension.
3883 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3884 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3886 base::RunLoop().RunUntilIdle();
3887 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3888 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3891 // Tests that extensions cannot be installed if the policy provider prohibits
3892 // it. This functionality is implemented in CrxInstaller::ConfirmInstall().
3893 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
3894 InitializeEmptyExtensionService();
3896 GetManagementPolicy()->UnregisterAllProviders();
3897 extensions::TestManagementPolicyProvider provider_(
3898 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3899 GetManagementPolicy()->RegisterProvider(&provider_);
3901 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_FAILED);
3902 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3905 // Tests that extensions cannot be loaded from prefs if the policy provider
3906 // prohibits it. This functionality is implemented in InstalledLoader::Load().
3907 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
3908 InitializeEmptyExtensionService();
3910 // Create a fake extension to be loaded as though it were read from prefs.
3911 base::FilePath path =
3912 data_dir().AppendASCII("management").AppendASCII("simple_extension");
3913 base::DictionaryValue manifest;
3914 manifest.SetString(keys::kName, "simple_extension");
3915 manifest.SetString(keys::kVersion, "1");
3916 // UNPACKED is for extensions loaded from a directory. We use it here, even
3917 // though we're testing loading from prefs, so that we don't need to provide
3918 // an extension key.
3919 extensions::ExtensionInfo extension_info(
3920 &manifest, std::string(), path, Manifest::UNPACKED);
3922 // Ensure we can load it with no management policy in place.
3923 GetManagementPolicy()->UnregisterAllProviders();
3924 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3925 extensions::InstalledLoader(service()).Load(extension_info, false);
3926 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3928 const Extension* extension =
3929 (registry()->enabled_extensions().begin())->get();
3930 EXPECT_TRUE(
3931 service()->UninstallExtension(extension->id(),
3932 extensions::UNINSTALL_REASON_FOR_TESTING,
3933 base::Bind(&base::DoNothing),
3934 NULL));
3935 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3937 // Ensure we cannot load it if management policy prohibits installation.
3938 extensions::TestManagementPolicyProvider provider_(
3939 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3940 GetManagementPolicy()->RegisterProvider(&provider_);
3942 extensions::InstalledLoader(service()).Load(extension_info, false);
3943 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3946 // Tests disabling an extension when prohibited by the ManagementPolicy.
3947 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
3948 InitializeEmptyExtensionService();
3950 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3951 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3952 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3954 GetManagementPolicy()->UnregisterAllProviders();
3955 extensions::TestManagementPolicyProvider provider(
3956 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3957 GetManagementPolicy()->RegisterProvider(&provider);
3959 // Attempt to disable it.
3960 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3962 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3963 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3964 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3967 // Tests uninstalling an extension when prohibited by the ManagementPolicy.
3968 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
3969 InitializeEmptyExtensionService();
3971 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3972 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3973 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3975 GetManagementPolicy()->UnregisterAllProviders();
3976 extensions::TestManagementPolicyProvider provider(
3977 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3978 GetManagementPolicy()->RegisterProvider(&provider);
3980 // Attempt to uninstall it.
3981 EXPECT_FALSE(
3982 service()->UninstallExtension(good_crx,
3983 extensions::UNINSTALL_REASON_FOR_TESTING,
3984 base::Bind(&base::DoNothing),
3985 NULL));
3987 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3988 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3991 // Tests that previously installed extensions that are now prohibited from
3992 // being installed are removed.
3993 TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
3994 InitializeEmptyExtensionService();
3996 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3997 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
3998 EXPECT_EQ(2u, registry()->enabled_extensions().size());
3999 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4001 GetManagementPolicy()->UnregisterAllProviders();
4002 extensions::TestManagementPolicyProvider provider(
4003 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
4004 GetManagementPolicy()->RegisterProvider(&provider);
4006 // Run the policy check.
4007 service()->CheckManagementPolicy();
4008 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4009 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4012 // Tests that previously disabled extensions that are now required to be
4013 // enabled are re-enabled on reinstall.
4014 TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
4015 InitializeEmptyExtensionService();
4017 // Install, then disable, an extension.
4018 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4019 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4020 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4021 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4023 // Register an ExtensionManagementPolicy that requires the extension to remain
4024 // enabled.
4025 GetManagementPolicy()->UnregisterAllProviders();
4026 extensions::TestManagementPolicyProvider provider(
4027 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
4028 GetManagementPolicy()->RegisterProvider(&provider);
4030 // Reinstall the extension.
4031 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_UPDATED);
4032 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4033 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4036 // Tests that extensions disabled by management policy can be installed but
4037 // will get disabled after installing.
4038 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsEnableOnInstalled) {
4039 InitializeEmptyExtensionService();
4041 // Register an ExtensionManagementPolicy that disables all extensions, with
4042 // a specified Extension::DisableReason.
4043 GetManagementPolicy()->UnregisterAllProviders();
4044 extensions::TestManagementPolicyProvider provider(
4045 extensions::TestManagementPolicyProvider::MUST_REMAIN_DISABLED);
4046 provider.SetDisableReason(Extension::DISABLE_NOT_VERIFIED);
4047 GetManagementPolicy()->RegisterProvider(&provider);
4049 // Attempts to install an extensions, it should be installed but disabled.
4050 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4051 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4052 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_WITHOUT_LOAD);
4053 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4054 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4056 // Verifies that the disable reason is set properly.
4057 EXPECT_EQ(Extension::DISABLE_NOT_VERIFIED,
4058 service()->extension_prefs_->GetDisableReasons(kGoodId));
4061 // Tests that extensions with conflicting required permissions by enterprise
4062 // policy cannot be installed.
4063 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionNewExtensionInstall) {
4064 InitializeEmptyExtensionServiceWithTestingPrefs();
4065 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4068 // Update policy to block one of the required permissions of target.
4069 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4070 pref.AddBlockedPermission("*", "tabs");
4073 // The extension should be failed to install.
4074 PackAndInstallCRX(path, INSTALL_FAILED);
4077 // Update policy to block one of the optional permissions instead.
4078 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4079 pref.ClearBlockedPermissions("*");
4080 pref.AddBlockedPermission("*", "history");
4083 // The extension should succeed to install this time.
4084 std::string id = PackAndInstallCRX(path, INSTALL_NEW)->id();
4086 // Uninstall the extension and update policy to block some arbitrary
4087 // unknown permission.
4088 UninstallExtension(id, false);
4090 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4091 pref.ClearBlockedPermissions("*");
4092 pref.AddBlockedPermission("*", "unknown.permission.for.testing");
4095 // The extension should succeed to install as well.
4096 PackAndInstallCRX(path, INSTALL_NEW);
4099 // Tests that extension supposed to be force installed but with conflicting
4100 // required permissions cannot be installed.
4101 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionConflictsWithForceInstall) {
4102 InitializeEmptyExtensionServiceWithTestingPrefs();
4104 // Pack the crx file.
4105 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4106 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4107 base::ScopedTempDir temp_dir;
4108 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4109 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
4111 PackCRX(path, pem_path, crx_path);
4114 // Block one of the required permissions.
4115 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4116 pref.AddBlockedPermission("*", "tabs");
4119 // Use MockExtensionProvider to simulate force installing extension.
4120 MockExtensionProvider* provider =
4121 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4122 AddMockExternalProvider(provider);
4123 provider->UpdateOrAddExtension(permissions_blocklist, "1.0", crx_path);
4126 // Attempts to force install this extension.
4127 content::WindowedNotificationObserver observer(
4128 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4129 content::NotificationService::AllSources());
4130 service()->CheckForExternalUpdates();
4131 observer.Wait();
4134 // The extension should not be installed.
4135 ASSERT_FALSE(service()->GetInstalledExtension(permissions_blocklist));
4137 // Remove this extension from pending extension manager as we would like to
4138 // give another attempt later.
4139 service()->pending_extension_manager()->Remove(permissions_blocklist);
4142 // Clears the permission block list.
4143 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4144 pref.ClearBlockedPermissions("*");
4148 // Attempts to force install this extension again.
4149 content::WindowedNotificationObserver observer(
4150 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4151 content::NotificationService::AllSources());
4152 service()->CheckForExternalUpdates();
4153 observer.Wait();
4156 const Extension* installed =
4157 service()->GetInstalledExtension(permissions_blocklist);
4158 ASSERT_TRUE(installed);
4159 EXPECT_EQ(installed->location(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4162 // Tests that newer versions of an extension with conflicting required
4163 // permissions by enterprise policy cannot be updated to.
4164 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionExtensionUpdate) {
4165 InitializeEmptyExtensionServiceWithTestingPrefs();
4167 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4168 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4169 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4171 // Install 'permissions_blocklist'.
4172 const Extension* installed = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
4173 EXPECT_EQ(installed->id(), permissions_blocklist);
4176 // Block one of the required permissions of 'permissions_blocklist2'.
4177 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4178 pref.AddBlockedPermission("*", "downloads");
4181 // Install 'permissions_blocklist' again, should be updated.
4182 const Extension* updated = PackAndInstallCRX(path, pem_path, INSTALL_UPDATED);
4183 EXPECT_EQ(updated->id(), permissions_blocklist);
4185 std::string old_version = updated->VersionString();
4187 // Attempts to update to 'permissions_blocklist2' should fail.
4188 PackAndInstallCRX(path2, pem_path, INSTALL_FAILED);
4190 // Verify that the old version is still enabled.
4191 updated = service()->GetExtensionById(permissions_blocklist, false);
4192 ASSERT_TRUE(updated);
4193 EXPECT_EQ(old_version, updated->VersionString());
4196 // Tests that policy update with additional permissions blocked revoke
4197 // conflicting granted optional permissions and unload extensions with
4198 // conflicting required permissions, including the force installed ones.
4199 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionPolicyUpdate) {
4200 InitializeEmptyExtensionServiceWithTestingPrefs();
4202 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4203 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4204 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4206 // Pack the crx file.
4207 base::ScopedTempDir temp_dir;
4208 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4209 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
4211 PackCRX(path2, pem_path, crx_path);
4213 // Install two arbitary extensions with specified manifest.
4214 std::string ext1 = PackAndInstallCRX(path, INSTALL_NEW)->id();
4215 std::string ext2 = PackAndInstallCRX(path2, INSTALL_NEW)->id();
4216 ASSERT_NE(ext1, permissions_blocklist);
4217 ASSERT_NE(ext2, permissions_blocklist);
4218 ASSERT_NE(ext1, ext2);
4220 // Force install another extension with known id and same manifest as 'ext2'.
4221 std::string ext2_forced = permissions_blocklist;
4222 MockExtensionProvider* provider =
4223 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4224 AddMockExternalProvider(provider);
4225 provider->UpdateOrAddExtension(ext2_forced, "2.0", crx_path);
4227 content::WindowedNotificationObserver observer(
4228 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4229 content::NotificationService::AllSources());
4230 service()->CheckForExternalUpdates();
4231 observer.Wait();
4233 extensions::ExtensionRegistry* registry =
4234 extensions::ExtensionRegistry::Get(profile());
4236 // Verify all three extensions are installed and enabled.
4237 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext1));
4238 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2));
4239 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2_forced));
4241 // Grant all optional permissions to each extension.
4242 GrantAllOptionalPermissions(ext1);
4243 GrantAllOptionalPermissions(ext2);
4244 GrantAllOptionalPermissions(ext2_forced);
4246 scoped_refptr<const PermissionSet> active_permissions(
4247 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1));
4248 EXPECT_TRUE(active_permissions->HasAPIPermission(
4249 extensions::APIPermission::kDownloads));
4251 // Set policy to block 'downloads' permission.
4253 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4254 pref.AddBlockedPermission("*", "downloads");
4257 base::RunLoop().RunUntilIdle();
4259 // 'ext1' should still be enabled, but with 'downloads' permission revoked.
4260 EXPECT_TRUE(registry->enabled_extensions().GetByID(ext1));
4261 active_permissions =
4262 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1);
4263 EXPECT_FALSE(active_permissions->HasAPIPermission(
4264 extensions::APIPermission::kDownloads));
4266 // 'ext2' should be disabled because one of its required permissions is
4267 // blocked.
4268 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2));
4270 // 'ext2_forced' should be handled the same as 'ext2'
4271 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2_forced));
4274 // Flaky on windows; http://crbug.com/309833
4275 #if defined(OS_WIN)
4276 #define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
4277 #else
4278 #define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
4279 #endif
4280 TEST_F(ExtensionServiceTest, MAYBE_ExternalExtensionAutoAcknowledgement) {
4281 InitializeEmptyExtensionService();
4282 service()->set_extensions_enabled(true);
4285 // Register and install an external extension.
4286 MockExtensionProvider* provider =
4287 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
4288 AddMockExternalProvider(provider);
4289 provider->UpdateOrAddExtension(
4290 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
4293 // Have policy force-install an extension.
4294 MockExtensionProvider* provider = new MockExtensionProvider(
4295 service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4296 AddMockExternalProvider(provider);
4297 provider->UpdateOrAddExtension(
4298 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
4301 // Providers are set up. Let them run.
4302 int count = 2;
4303 content::WindowedNotificationObserver observer(
4304 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4305 base::Bind(&WaitForCountNotificationsCallback, &count));
4306 service()->CheckForExternalUpdates();
4308 observer.Wait();
4310 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4311 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4312 EXPECT_TRUE(service()->GetExtensionById(page_action, false));
4313 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4314 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
4315 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
4318 #if !defined(OS_CHROMEOS)
4319 // This tests if default apps are installed correctly.
4320 TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
4321 InitializeEmptyExtensionService();
4322 service()->set_extensions_enabled(true);
4325 std::string json_data =
4327 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
4328 " \"external_crx\": \"good.crx\","
4329 " \"external_version\": \"1.0.0.0\","
4330 " \"is_bookmark_app\": false"
4331 " }"
4332 "}";
4333 default_apps::Provider* provider = new default_apps::Provider(
4334 profile(),
4335 service(),
4336 new extensions::ExternalTestingLoader(json_data, data_dir()),
4337 Manifest::INTERNAL,
4338 Manifest::INVALID_LOCATION,
4339 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4341 AddMockExternalProvider(provider);
4344 ASSERT_EQ(0u, registry()->enabled_extensions().size());
4345 content::WindowedNotificationObserver observer(
4346 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4347 content::NotificationService::AllSources());
4348 service()->CheckForExternalUpdates();
4349 observer.Wait();
4351 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4352 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4353 const Extension* extension = service()->GetExtensionById(good_crx, false);
4354 EXPECT_TRUE(extension->from_webstore());
4355 EXPECT_TRUE(extension->was_installed_by_default());
4357 #endif
4359 // Tests disabling extensions
4360 TEST_F(ExtensionServiceTest, DisableExtension) {
4361 InitializeEmptyExtensionService();
4363 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4364 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4365 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4367 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4368 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4369 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4370 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4372 // Disable it.
4373 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4375 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4376 EXPECT_FALSE(service()->GetExtensionById(good_crx, false));
4377 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4378 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4379 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4380 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4383 TEST_F(ExtensionServiceTest, TerminateExtension) {
4384 InitializeEmptyExtensionService();
4386 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4387 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4388 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4389 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4390 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4392 TerminateExtension(good_crx);
4394 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4395 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4396 EXPECT_EQ(1u, registry()->terminated_extensions().size());
4397 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4400 TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
4401 InitializeEmptyExtensionService();
4403 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4404 TerminateExtension(good_crx);
4405 EXPECT_TRUE(registry()->GetExtensionById(
4406 good_crx, extensions::ExtensionRegistry::TERMINATED));
4408 // Disable it.
4409 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4411 EXPECT_FALSE(registry()->GetExtensionById(
4412 good_crx, extensions::ExtensionRegistry::TERMINATED));
4413 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4415 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4416 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4417 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4418 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4421 // Tests disabling all extensions (simulating --disable-extensions flag).
4422 TEST_F(ExtensionServiceTest, DisableAllExtensions) {
4423 InitializeEmptyExtensionService();
4425 base::FilePath path = data_dir().AppendASCII("good.crx");
4426 InstallCRX(path, INSTALL_NEW);
4428 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4429 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4431 // Disable extensions.
4432 service()->set_extensions_enabled(false);
4433 service()->ReloadExtensionsForTest();
4435 // There shouldn't be extensions in either list.
4436 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4437 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4439 // This shouldn't do anything when all extensions are disabled.
4440 service()->EnableExtension(good_crx);
4441 service()->ReloadExtensionsForTest();
4443 // There still shouldn't be extensions in either list.
4444 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4445 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4447 // And then re-enable the extensions.
4448 service()->set_extensions_enabled(true);
4449 service()->ReloadExtensionsForTest();
4451 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4452 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4455 // Tests reloading extensions.
4456 TEST_F(ExtensionServiceTest, ReloadExtensions) {
4457 InitializeEmptyExtensionService();
4459 // Simple extension that should install without error.
4460 base::FilePath path = data_dir().AppendASCII("good.crx");
4461 InstallCRX(path, INSTALL_NEW,
4462 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4463 const char* const extension_id = good_crx;
4464 service()->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
4466 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4467 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4469 service()->ReloadExtensionsForTest();
4471 // The creation flags should not change when reloading the extension.
4472 const Extension* extension = service()->GetExtensionById(good_crx, true);
4473 EXPECT_TRUE(extension->from_webstore());
4474 EXPECT_TRUE(extension->was_installed_by_default());
4475 EXPECT_FALSE(extension->from_bookmark());
4477 // Extension counts shouldn't change.
4478 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4479 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4481 service()->EnableExtension(extension_id);
4483 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4484 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4486 // Need to clear |loaded_| manually before reloading as the
4487 // EnableExtension() call above inserted into it and
4488 // UnloadAllExtensions() doesn't send out notifications.
4489 loaded_.clear();
4490 service()->ReloadExtensionsForTest();
4492 // Extension counts shouldn't change.
4493 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4494 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4497 // Tests reloading an extension.
4498 TEST_F(ExtensionServiceTest, ReloadExtension) {
4499 InitializeEmptyExtensionService();
4501 // Simple extension that should install without error.
4502 const char extension_id[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
4503 base::FilePath ext = data_dir()
4504 .AppendASCII("good")
4505 .AppendASCII("Extensions")
4506 .AppendASCII(extension_id)
4507 .AppendASCII("1.0.0.0");
4508 extensions::UnpackedInstaller::Create(service())->Load(ext);
4509 base::RunLoop().RunUntilIdle();
4511 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4512 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4514 service()->ReloadExtension(extension_id);
4516 // Extension should be disabled now, waiting to be reloaded.
4517 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4518 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4519 EXPECT_EQ(Extension::DISABLE_RELOAD,
4520 ExtensionPrefs::Get(profile())->GetDisableReasons(extension_id));
4522 // Reloading again should not crash.
4523 service()->ReloadExtension(extension_id);
4525 // Finish reloading
4526 base::RunLoop().RunUntilIdle();
4528 // Extension should be enabled again.
4529 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4530 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4533 TEST_F(ExtensionServiceTest, UninstallExtension) {
4534 InitializeEmptyExtensionService();
4535 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4536 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4537 UninstallExtension(good_crx, false);
4538 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4539 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4542 TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
4543 InitializeEmptyExtensionService();
4544 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4545 TerminateExtension(good_crx);
4546 UninstallExtension(good_crx, false);
4547 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4550 // Tests the uninstaller helper.
4551 TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
4552 InitializeEmptyExtensionService();
4553 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4554 UninstallExtension(good_crx, true);
4555 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4558 TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
4559 InitializeEmptyExtensionService();
4560 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4561 TerminateExtension(good_crx);
4562 UninstallExtension(good_crx, true);
4563 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4566 // An extension disabled because of unsupported requirements should re-enabled
4567 // if updated to a version with supported requirements as long as there are no
4568 // other disable reasons.
4569 TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
4570 InitializeEmptyExtensionService();
4571 BlackListWebGL();
4573 base::FilePath path = data_dir().AppendASCII("requirements");
4574 base::FilePath pem_path =
4575 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4576 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4577 pem_path,
4578 INSTALL_NEW);
4579 std::string id = extension_v1->id();
4580 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4582 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4584 PackCRX(path.AppendASCII("v2_bad_requirements"),
4585 pem_path,
4586 v2_bad_requirements_crx);
4587 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4588 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4590 base::FilePath v3_good_crx = GetTemporaryFile();
4592 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4593 UpdateExtension(id, v3_good_crx, ENABLED);
4594 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4597 // Extensions disabled through user action should stay disabled.
4598 TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
4599 InitializeEmptyExtensionService();
4600 BlackListWebGL();
4602 base::FilePath path = data_dir().AppendASCII("requirements");
4603 base::FilePath pem_path =
4604 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4605 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4606 pem_path,
4607 INSTALL_NEW);
4608 std::string id = extension_v1->id();
4609 service()->DisableExtension(id, Extension::DISABLE_USER_ACTION);
4610 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4612 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4614 PackCRX(path.AppendASCII("v2_bad_requirements"),
4615 pem_path,
4616 v2_bad_requirements_crx);
4617 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4618 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4620 base::FilePath v3_good_crx = GetTemporaryFile();
4622 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4623 UpdateExtension(id, v3_good_crx, INSTALLED);
4624 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4627 // The extension should not re-enabled because it was disabled from a
4628 // permission increase.
4629 TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
4630 InitializeEmptyExtensionService();
4631 BlackListWebGL();
4633 base::FilePath path = data_dir().AppendASCII("requirements");
4634 base::FilePath pem_path =
4635 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4636 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4637 pem_path,
4638 INSTALL_NEW);
4639 std::string id = extension_v1->id();
4640 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4642 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
4644 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
4645 pem_path,
4646 v2_bad_requirements_and_permissions_crx);
4647 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
4648 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4650 base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
4652 PackCRX(path.AppendASCII("v3_bad_permissions"),
4653 pem_path,
4654 v3_bad_permissions_crx);
4655 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
4656 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4659 // Unpacked extensions are not allowed to be installed if they have unsupported
4660 // requirements.
4661 TEST_F(ExtensionServiceTest, UnpackedRequirements) {
4662 InitializeEmptyExtensionService();
4663 BlackListWebGL();
4665 base::FilePath path =
4666 data_dir().AppendASCII("requirements").AppendASCII("v2_bad_requirements");
4667 extensions::UnpackedInstaller::Create(service())->Load(path);
4668 base::RunLoop().RunUntilIdle();
4669 EXPECT_EQ(1u, GetErrors().size());
4670 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4673 class ExtensionCookieCallback {
4674 public:
4675 ExtensionCookieCallback()
4676 : result_(false),
4677 weak_factory_(base::MessageLoop::current()) {}
4679 void SetCookieCallback(bool result) {
4680 base::ThreadTaskRunnerHandle::Get()->PostTask(
4681 FROM_HERE,
4682 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4683 result_ = result;
4686 void GetAllCookiesCallback(const net::CookieList& list) {
4687 base::ThreadTaskRunnerHandle::Get()->PostTask(
4688 FROM_HERE,
4689 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4690 list_ = list;
4692 net::CookieList list_;
4693 bool result_;
4694 base::WeakPtrFactory<base::MessageLoop> weak_factory_;
4697 // Verifies extension state is removed upon uninstall.
4698 TEST_F(ExtensionServiceTest, ClearExtensionData) {
4699 InitializeEmptyExtensionService();
4700 ExtensionCookieCallback callback;
4702 // Load a test extension.
4703 base::FilePath path = data_dir();
4704 path = path.AppendASCII("good.crx");
4705 const Extension* extension = InstallCRX(path, INSTALL_NEW);
4706 ASSERT_TRUE(extension);
4707 GURL ext_url(extension->url());
4708 std::string origin_id = storage::GetIdentifierFromOrigin(ext_url);
4710 // Set a cookie for the extension.
4711 net::CookieMonster* cookie_monster = profile()
4712 ->GetRequestContextForExtensions()
4713 ->GetURLRequestContext()
4714 ->cookie_store()
4715 ->GetCookieMonster();
4716 ASSERT_TRUE(cookie_monster);
4717 net::CookieOptions options;
4718 cookie_monster->SetCookieWithOptionsAsync(
4719 ext_url, "dummy=value", options,
4720 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4721 base::Unretained(&callback)));
4722 base::RunLoop().RunUntilIdle();
4723 EXPECT_TRUE(callback.result_);
4725 cookie_monster->GetAllCookiesForURLAsync(
4726 ext_url,
4727 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4728 base::Unretained(&callback)));
4729 base::RunLoop().RunUntilIdle();
4730 EXPECT_EQ(1U, callback.list_.size());
4732 // Open a database.
4733 storage::DatabaseTracker* db_tracker =
4734 BrowserContext::GetDefaultStoragePartition(profile())
4735 ->GetDatabaseTracker();
4736 base::string16 db_name = base::UTF8ToUTF16("db");
4737 base::string16 description = base::UTF8ToUTF16("db_description");
4738 int64 size;
4739 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4740 db_tracker->DatabaseClosed(origin_id, db_name);
4741 std::vector<storage::OriginInfo> origins;
4742 db_tracker->GetAllOriginsInfo(&origins);
4743 EXPECT_EQ(1U, origins.size());
4744 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4746 // Create local storage. We only simulate this by creating the backing files.
4747 // Note: This test depends on details of how the dom_storage library
4748 // stores data in the host file system.
4749 base::FilePath lso_dir_path =
4750 profile()->GetPath().AppendASCII("Local Storage");
4751 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4752 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4753 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4754 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4755 EXPECT_TRUE(base::PathExists(lso_file_path));
4757 // Create indexed db. Similarly, it is enough to only simulate this by
4758 // creating the directory on the disk.
4759 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4760 profile())->GetIndexedDBContext();
4761 idb_context->SetTaskRunnerForTesting(
4762 base::MessageLoop::current()->task_runner().get());
4763 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4764 EXPECT_TRUE(base::CreateDirectory(idb_path));
4765 EXPECT_TRUE(base::DirectoryExists(idb_path));
4767 // Uninstall the extension.
4768 base::RunLoop run_loop;
4769 ASSERT_TRUE(
4770 service()->UninstallExtension(good_crx,
4771 extensions::UNINSTALL_REASON_FOR_TESTING,
4772 run_loop.QuitClosure(),
4773 NULL));
4774 // The data deletion happens on the IO thread.
4775 run_loop.Run();
4777 // Check that the cookie is gone.
4778 cookie_monster->GetAllCookiesForURLAsync(
4779 ext_url,
4780 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4781 base::Unretained(&callback)));
4782 base::RunLoop().RunUntilIdle();
4783 EXPECT_EQ(0U, callback.list_.size());
4785 // The database should have vanished as well.
4786 origins.clear();
4787 db_tracker->GetAllOriginsInfo(&origins);
4788 EXPECT_EQ(0U, origins.size());
4790 // Check that the LSO file has been removed.
4791 EXPECT_FALSE(base::PathExists(lso_file_path));
4793 // Check if the indexed db has disappeared too.
4794 EXPECT_FALSE(base::DirectoryExists(idb_path));
4797 // Verifies app state is removed upon uninstall.
4798 TEST_F(ExtensionServiceTest, ClearAppData) {
4799 InitializeEmptyExtensionService();
4800 ExtensionCookieCallback callback;
4802 int pref_count = 0;
4804 // Install app1 with unlimited storage.
4805 const Extension* extension =
4806 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
4807 ValidatePrefKeyCount(++pref_count);
4808 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4809 const std::string id1 = extension->id();
4810 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4811 APIPermission::kUnlimitedStorage));
4812 const GURL origin1(
4813 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4814 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4815 origin1));
4816 std::string origin_id = storage::GetIdentifierFromOrigin(origin1);
4818 // Install app2 from the same origin with unlimited storage.
4819 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
4820 ValidatePrefKeyCount(++pref_count);
4821 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4822 const std::string id2 = extension->id();
4823 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4824 APIPermission::kUnlimitedStorage));
4825 EXPECT_TRUE(extension->web_extent().MatchesURL(
4826 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
4827 const GURL origin2(
4828 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4829 EXPECT_EQ(origin1, origin2);
4830 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4831 origin2));
4833 // Set a cookie for the extension.
4834 net::CookieMonster* cookie_monster = profile()
4835 ->GetRequestContext()
4836 ->GetURLRequestContext()
4837 ->cookie_store()
4838 ->GetCookieMonster();
4839 ASSERT_TRUE(cookie_monster);
4840 net::CookieOptions options;
4841 cookie_monster->SetCookieWithOptionsAsync(
4842 origin1, "dummy=value", options,
4843 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4844 base::Unretained(&callback)));
4845 base::RunLoop().RunUntilIdle();
4846 EXPECT_TRUE(callback.result_);
4848 cookie_monster->GetAllCookiesForURLAsync(
4849 origin1,
4850 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4851 base::Unretained(&callback)));
4852 base::RunLoop().RunUntilIdle();
4853 EXPECT_EQ(1U, callback.list_.size());
4855 // Open a database.
4856 storage::DatabaseTracker* db_tracker =
4857 BrowserContext::GetDefaultStoragePartition(profile())
4858 ->GetDatabaseTracker();
4859 base::string16 db_name = base::UTF8ToUTF16("db");
4860 base::string16 description = base::UTF8ToUTF16("db_description");
4861 int64 size;
4862 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4863 db_tracker->DatabaseClosed(origin_id, db_name);
4864 std::vector<storage::OriginInfo> origins;
4865 db_tracker->GetAllOriginsInfo(&origins);
4866 EXPECT_EQ(1U, origins.size());
4867 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4869 // Create local storage. We only simulate this by creating the backing files.
4870 // Note: This test depends on details of how the dom_storage library
4871 // stores data in the host file system.
4872 base::FilePath lso_dir_path =
4873 profile()->GetPath().AppendASCII("Local Storage");
4874 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4875 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4876 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4877 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4878 EXPECT_TRUE(base::PathExists(lso_file_path));
4880 // Create indexed db. Similarly, it is enough to only simulate this by
4881 // creating the directory on the disk.
4882 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4883 profile())->GetIndexedDBContext();
4884 idb_context->SetTaskRunnerForTesting(
4885 base::MessageLoop::current()->task_runner().get());
4886 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4887 EXPECT_TRUE(base::CreateDirectory(idb_path));
4888 EXPECT_TRUE(base::DirectoryExists(idb_path));
4890 // Uninstall one of them, unlimited storage should still be granted
4891 // to the origin.
4892 UninstallExtension(id1, false);
4893 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4894 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4895 origin1));
4897 // Check that the cookie is still there.
4898 cookie_monster->GetAllCookiesForURLAsync(
4899 origin1,
4900 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4901 base::Unretained(&callback)));
4902 base::RunLoop().RunUntilIdle();
4903 EXPECT_EQ(1U, callback.list_.size());
4905 // Now uninstall the other. Storage should be cleared for the apps.
4906 UninstallExtension(id2, false);
4907 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4908 EXPECT_FALSE(
4909 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4910 origin1));
4912 // Check that the cookie is gone.
4913 cookie_monster->GetAllCookiesForURLAsync(
4914 origin1,
4915 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4916 base::Unretained(&callback)));
4917 base::RunLoop().RunUntilIdle();
4918 EXPECT_EQ(0U, callback.list_.size());
4920 // The database should have vanished as well.
4921 origins.clear();
4922 db_tracker->GetAllOriginsInfo(&origins);
4923 EXPECT_EQ(0U, origins.size());
4925 // Check that the LSO file has been removed.
4926 EXPECT_FALSE(base::PathExists(lso_file_path));
4928 // Check if the indexed db has disappeared too.
4929 EXPECT_FALSE(base::DirectoryExists(idb_path));
4932 // Tests loading single extensions (like --load-extension)
4933 // Flaky crashes. http://crbug.com/231806
4934 TEST_F(ExtensionServiceTest, DISABLED_LoadExtension) {
4935 InitializeEmptyExtensionService();
4937 base::FilePath ext1 = data_dir()
4938 .AppendASCII("good")
4939 .AppendASCII("Extensions")
4940 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4941 .AppendASCII("1.0.0.0");
4942 extensions::UnpackedInstaller::Create(service())->Load(ext1);
4943 base::RunLoop().RunUntilIdle();
4944 EXPECT_EQ(0u, GetErrors().size());
4945 ASSERT_EQ(1u, loaded_.size());
4946 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
4947 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4949 ValidatePrefKeyCount(1);
4951 base::FilePath no_manifest =
4952 data_dir()
4953 .AppendASCII("bad")
4954 // .AppendASCII("Extensions")
4955 .AppendASCII("cccccccccccccccccccccccccccccccc")
4956 .AppendASCII("1");
4957 extensions::UnpackedInstaller::Create(service())->Load(no_manifest);
4958 base::RunLoop().RunUntilIdle();
4959 EXPECT_EQ(1u, GetErrors().size());
4960 ASSERT_EQ(1u, loaded_.size());
4961 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4963 // Test uninstall.
4964 std::string id = loaded_[0]->id();
4965 EXPECT_FALSE(unloaded_id_.length());
4966 service()->UninstallExtension(id,
4967 extensions::UNINSTALL_REASON_FOR_TESTING,
4968 base::Bind(&base::DoNothing),
4969 NULL);
4970 base::RunLoop().RunUntilIdle();
4971 EXPECT_EQ(id, unloaded_id_);
4972 ASSERT_EQ(0u, loaded_.size());
4973 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4976 // Tests that we generate IDs when they are not specified in the manifest for
4977 // --load-extension.
4978 TEST_F(ExtensionServiceTest, GenerateID) {
4979 InitializeEmptyExtensionService();
4981 base::FilePath no_id_ext = data_dir().AppendASCII("no_id");
4982 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
4983 base::RunLoop().RunUntilIdle();
4984 EXPECT_EQ(0u, GetErrors().size());
4985 ASSERT_EQ(1u, loaded_.size());
4986 ASSERT_TRUE(crx_file::id_util::IdIsValid(loaded_[0]->id()));
4987 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
4989 ValidatePrefKeyCount(1);
4991 std::string previous_id = loaded_[0]->id();
4993 // If we reload the same path, we should get the same extension ID.
4994 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
4995 base::RunLoop().RunUntilIdle();
4996 ASSERT_EQ(1u, loaded_.size());
4997 ASSERT_EQ(previous_id, loaded_[0]->id());
5000 TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
5001 InitializeEmptyExtensionService();
5003 base::FilePath bad_locale =
5004 data_dir().AppendASCII("unpacked").AppendASCII("bad_messages_file");
5005 extensions::UnpackedInstaller::Create(service())->Load(bad_locale);
5006 base::RunLoop().RunUntilIdle();
5007 EXPECT_EQ(1u, GetErrors().size());
5008 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
5009 .AppendASCII("ms")
5010 .AppendASCII("messages.json");
5011 EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
5012 testing::HasSubstr(
5013 base::UTF16ToUTF8(ms_messages_file.LossyDisplayName())),
5014 testing::HasSubstr("Dictionary keys must be quoted.")));
5015 ASSERT_EQ(0u, loaded_.size());
5018 void ExtensionServiceTest::TestExternalProvider(
5019 MockExtensionProvider* provider, Manifest::Location location) {
5020 // Verify that starting with no providers loads no extensions.
5021 service()->Init();
5022 ASSERT_EQ(0u, loaded_.size());
5024 provider->set_visit_count(0);
5026 // Register a test extension externally using the mock registry provider.
5027 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5029 // Add the extension.
5030 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5032 // Reloading extensions should find our externally registered extension
5033 // and install it.
5034 content::WindowedNotificationObserver observer(
5035 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5036 content::NotificationService::AllSources());
5037 service()->CheckForExternalUpdates();
5038 observer.Wait();
5040 ASSERT_EQ(0u, GetErrors().size());
5041 ASSERT_EQ(1u, loaded_.size());
5042 ASSERT_EQ(location, loaded_[0]->location());
5043 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
5044 ValidatePrefKeyCount(1);
5045 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5046 ValidateIntegerPref(good_crx, "location", location);
5048 // Reload extensions without changing anything. The extension should be
5049 // loaded again.
5050 loaded_.clear();
5051 service()->ReloadExtensionsForTest();
5052 base::RunLoop().RunUntilIdle();
5053 ASSERT_EQ(0u, GetErrors().size());
5054 ASSERT_EQ(1u, loaded_.size());
5055 ValidatePrefKeyCount(1);
5056 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5057 ValidateIntegerPref(good_crx, "location", location);
5059 // Now update the extension with a new version. We should get upgraded.
5060 source_path = source_path.DirName().AppendASCII("good2.crx");
5061 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5063 loaded_.clear();
5064 content::WindowedNotificationObserver observer_2(
5065 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5066 content::NotificationService::AllSources());
5067 service()->CheckForExternalUpdates();
5068 observer_2.Wait();
5069 ASSERT_EQ(0u, GetErrors().size());
5070 ASSERT_EQ(1u, loaded_.size());
5071 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
5072 ValidatePrefKeyCount(1);
5073 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5074 ValidateIntegerPref(good_crx, "location", location);
5076 // Uninstall the extension and reload. Nothing should happen because the
5077 // preference should prevent us from reinstalling.
5078 std::string id = loaded_[0]->id();
5079 bool no_uninstall =
5080 GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL);
5081 service()->UninstallExtension(id,
5082 extensions::UNINSTALL_REASON_FOR_TESTING,
5083 base::Bind(&base::DoNothing),
5084 NULL);
5085 base::RunLoop().RunUntilIdle();
5087 base::FilePath install_path = extensions_install_dir().AppendASCII(id);
5088 if (no_uninstall) {
5089 // Policy controlled extensions should not have been touched by uninstall.
5090 ASSERT_TRUE(base::PathExists(install_path));
5091 } else {
5092 // The extension should also be gone from the install directory.
5093 ASSERT_FALSE(base::PathExists(install_path));
5094 loaded_.clear();
5095 service()->CheckForExternalUpdates();
5096 base::RunLoop().RunUntilIdle();
5097 ASSERT_EQ(0u, loaded_.size());
5098 ValidatePrefKeyCount(1);
5099 ValidateIntegerPref(good_crx, "state",
5100 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
5101 ValidateIntegerPref(good_crx, "location", location);
5103 // Now clear the preference and reinstall.
5104 SetPrefInteg(good_crx, "state", Extension::ENABLED);
5106 loaded_.clear();
5107 content::WindowedNotificationObserver observer(
5108 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5109 content::NotificationService::AllSources());
5110 service()->CheckForExternalUpdates();
5111 observer.Wait();
5112 ASSERT_EQ(1u, loaded_.size());
5114 ValidatePrefKeyCount(1);
5115 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5116 ValidateIntegerPref(good_crx, "location", location);
5118 if (GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL)) {
5119 EXPECT_EQ(2, provider->visit_count());
5120 } else {
5121 // Now test an externally triggered uninstall (deleting the registry key or
5122 // the pref entry).
5123 provider->RemoveExtension(good_crx);
5125 loaded_.clear();
5126 service()->OnExternalProviderReady(provider);
5127 base::RunLoop().RunUntilIdle();
5128 ASSERT_EQ(0u, loaded_.size());
5129 ValidatePrefKeyCount(0);
5131 // The extension should also be gone from the install directory.
5132 ASSERT_FALSE(base::PathExists(install_path));
5134 // Now test the case where user uninstalls and then the extension is removed
5135 // from the external provider.
5136 content::WindowedNotificationObserver observer(
5137 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5138 content::NotificationService::AllSources());
5139 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5140 service()->CheckForExternalUpdates();
5141 observer.Wait();
5143 ASSERT_EQ(1u, loaded_.size());
5144 ASSERT_EQ(0u, GetErrors().size());
5146 // User uninstalls.
5147 loaded_.clear();
5148 service()->UninstallExtension(id,
5149 extensions::UNINSTALL_REASON_FOR_TESTING,
5150 base::Bind(&base::DoNothing),
5151 NULL);
5152 base::RunLoop().RunUntilIdle();
5153 ASSERT_EQ(0u, loaded_.size());
5155 // Then remove the extension from the extension provider.
5156 provider->RemoveExtension(good_crx);
5158 // Should still be at 0.
5159 loaded_.clear();
5160 extensions::InstalledLoader(service()).LoadAllExtensions();
5161 base::RunLoop().RunUntilIdle();
5162 ASSERT_EQ(0u, loaded_.size());
5163 ValidatePrefKeyCount(1);
5165 EXPECT_EQ(5, provider->visit_count());
5169 // Tests the external installation feature
5170 #if defined(OS_WIN)
5171 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
5172 // This should all work, even when normal extension installation is disabled.
5173 InitializeEmptyExtensionService();
5174 service()->set_extensions_enabled(false);
5176 // Now add providers. Extension system takes ownership of the objects.
5177 MockExtensionProvider* reg_provider =
5178 new MockExtensionProvider(service(), Manifest::EXTERNAL_REGISTRY);
5179 AddMockExternalProvider(reg_provider);
5180 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
5182 #endif
5184 TEST_F(ExtensionServiceTest, ExternalInstallPref) {
5185 InitializeEmptyExtensionService();
5187 // Now add providers. Extension system takes ownership of the objects.
5188 MockExtensionProvider* pref_provider =
5189 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
5191 AddMockExternalProvider(pref_provider);
5192 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
5195 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
5196 // This should all work, even when normal extension installation is disabled.
5197 InitializeEmptyExtensionService();
5198 service()->set_extensions_enabled(false);
5200 // TODO(skerner): The mock provider is not a good model of a provider
5201 // that works with update URLs, because it adds file and version info.
5202 // Extend the mock to work with update URLs. This test checks the
5203 // behavior that is common to all external extension visitors. The
5204 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5205 // what the visitor does results in an extension being downloaded and
5206 // installed.
5207 MockExtensionProvider* pref_provider =
5208 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF_DOWNLOAD);
5209 AddMockExternalProvider(pref_provider);
5210 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
5213 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
5214 // This should all work, even when normal extension installation is disabled.
5215 InitializeEmptyExtensionService();
5216 service()->set_extensions_enabled(false);
5218 // TODO(skerner): The mock provider is not a good model of a provider
5219 // that works with update URLs, because it adds file and version info.
5220 // Extend the mock to work with update URLs. This test checks the
5221 // behavior that is common to all external extension visitors. The
5222 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5223 // what the visitor does results in an extension being downloaded and
5224 // installed.
5225 MockExtensionProvider* pref_provider =
5226 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
5227 AddMockExternalProvider(pref_provider);
5228 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
5231 // Tests that external extensions get uninstalled when the external extension
5232 // providers can't account for them.
5233 TEST_F(ExtensionServiceTest, ExternalUninstall) {
5234 // Start the extensions service with one external extension already installed.
5235 base::FilePath source_install_dir =
5236 data_dir().AppendASCII("good").AppendASCII("Extensions");
5237 base::FilePath pref_path = source_install_dir
5238 .DirName()
5239 .AppendASCII("PreferencesExternal");
5241 // This initializes the extensions service with no ExternalProviders.
5242 InitializeInstalledExtensionService(pref_path, source_install_dir);
5243 service()->set_extensions_enabled(false);
5245 service()->Init();
5247 ASSERT_EQ(0u, GetErrors().size());
5248 ASSERT_EQ(0u, loaded_.size());
5250 // Verify that it's not the disabled extensions flag causing it not to load.
5251 service()->set_extensions_enabled(true);
5252 service()->ReloadExtensionsForTest();
5253 base::RunLoop().RunUntilIdle();
5255 ASSERT_EQ(0u, GetErrors().size());
5256 ASSERT_EQ(0u, loaded_.size());
5259 // Test that running multiple update checks simultaneously does not
5260 // keep the update from succeeding.
5261 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
5262 InitializeEmptyExtensionService();
5264 MockExtensionProvider* provider =
5265 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
5266 AddMockExternalProvider(provider);
5268 // Verify that starting with no providers loads no extensions.
5269 service()->Init();
5270 ASSERT_EQ(0u, loaded_.size());
5272 // Start two checks for updates.
5273 provider->set_visit_count(0);
5274 service()->CheckForExternalUpdates();
5275 service()->CheckForExternalUpdates();
5276 base::RunLoop().RunUntilIdle();
5278 // Two calls should cause two checks for external extensions.
5279 EXPECT_EQ(2, provider->visit_count());
5280 EXPECT_EQ(0u, GetErrors().size());
5281 EXPECT_EQ(0u, loaded_.size());
5283 // Register a test extension externally using the mock registry provider.
5284 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5285 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5287 // Two checks for external updates should find the extension, and install it
5288 // once.
5289 content::WindowedNotificationObserver observer(
5290 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5291 content::NotificationService::AllSources());
5292 provider->set_visit_count(0);
5293 service()->CheckForExternalUpdates();
5294 service()->CheckForExternalUpdates();
5295 observer.Wait();
5296 EXPECT_EQ(2, provider->visit_count());
5297 ASSERT_EQ(0u, GetErrors().size());
5298 ASSERT_EQ(1u, loaded_.size());
5299 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
5300 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
5301 ValidatePrefKeyCount(1);
5302 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5303 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
5305 provider->RemoveExtension(good_crx);
5306 provider->set_visit_count(0);
5307 service()->CheckForExternalUpdates();
5308 service()->CheckForExternalUpdates();
5309 base::RunLoop().RunUntilIdle();
5311 // Two calls should cause two checks for external extensions.
5312 // Because the external source no longer includes good_crx,
5313 // good_crx will be uninstalled. So, expect that no extensions
5314 // are loaded.
5315 EXPECT_EQ(2, provider->visit_count());
5316 EXPECT_EQ(0u, GetErrors().size());
5317 EXPECT_EQ(0u, loaded_.size());
5320 TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
5321 InitializeEmptyExtensionService();
5323 // Test some valid extension records.
5324 // Set a base path to avoid erroring out on relative paths.
5325 // Paths starting with // are absolute on every platform we support.
5326 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5327 ASSERT_TRUE(base_path.IsAbsolute());
5328 MockProviderVisitor visitor(base_path);
5329 std::string json_data =
5331 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5332 " \"external_crx\": \"RandomExtension.crx\","
5333 " \"external_version\": \"1.0\""
5334 " },"
5335 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5336 " \"external_crx\": \"RandomExtension2.crx\","
5337 " \"external_version\": \"2.0\""
5338 " },"
5339 " \"cccccccccccccccccccccccccccccccc\": {"
5340 " \"external_update_url\": \"http:\\\\foo.com/update\","
5341 " \"install_parameter\": \"id\""
5342 " }"
5343 "}";
5344 EXPECT_EQ(3, visitor.Visit(json_data));
5346 // Simulate an external_extensions.json file that contains seven invalid
5347 // records:
5348 // - One that is missing the 'external_crx' key.
5349 // - One that is missing the 'external_version' key.
5350 // - One that is specifying .. in the path.
5351 // - One that specifies both a file and update URL.
5352 // - One that specifies no file or update URL.
5353 // - One that has an update URL that is not well formed.
5354 // - One that contains a malformed version.
5355 // - One that has an invalid id.
5356 // - One that has a non-dictionary value.
5357 // - One that has an integer 'external_version' instead of a string.
5358 // The final extension is valid, and we check that it is read to make sure
5359 // failures don't stop valid records from being read.
5360 json_data =
5362 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5363 " \"external_version\": \"1.0\""
5364 " },"
5365 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5366 " \"external_crx\": \"RandomExtension.crx\""
5367 " },"
5368 " \"cccccccccccccccccccccccccccccccc\": {"
5369 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
5370 " \"external_version\": \"2.0\""
5371 " },"
5372 " \"dddddddddddddddddddddddddddddddd\": {"
5373 " \"external_crx\": \"RandomExtension2.crx\","
5374 " \"external_version\": \"2.0\","
5375 " \"external_update_url\": \"http:\\\\foo.com/update\""
5376 " },"
5377 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
5378 " },"
5379 " \"ffffffffffffffffffffffffffffffff\": {"
5380 " \"external_update_url\": \"This string is not a valid URL\""
5381 " },"
5382 " \"gggggggggggggggggggggggggggggggg\": {"
5383 " \"external_crx\": \"RandomExtension3.crx\","
5384 " \"external_version\": \"This is not a valid version!\""
5385 " },"
5386 " \"This is not a valid id!\": {},"
5387 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
5388 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
5389 " \"external_crx\": \"RandomExtension4.crx\","
5390 " \"external_version\": 1.0"
5391 " },"
5392 " \"pppppppppppppppppppppppppppppppp\": {"
5393 " \"external_crx\": \"RandomValidExtension.crx\","
5394 " \"external_version\": \"1.0\""
5395 " }"
5396 "}";
5397 EXPECT_EQ(1, visitor.Visit(json_data));
5399 // Check that if a base path is not provided, use of a relative
5400 // path fails.
5401 base::FilePath empty;
5402 MockProviderVisitor visitor_no_relative_paths(empty);
5404 // Use absolute paths. Expect success.
5405 json_data =
5407 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5408 " \"external_crx\": \"//RandomExtension1.crx\","
5409 " \"external_version\": \"3.0\""
5410 " },"
5411 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5412 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
5413 " \"external_version\": \"3.0\""
5414 " }"
5415 "}";
5416 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
5418 // Use a relative path. Expect that it will error out.
5419 json_data =
5421 " \"cccccccccccccccccccccccccccccccc\": {"
5422 " \"external_crx\": \"RandomExtension2.crx\","
5423 " \"external_version\": \"3.0\""
5424 " }"
5425 "}";
5426 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
5428 // Test supported_locales.
5429 json_data =
5431 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5432 " \"external_crx\": \"RandomExtension.crx\","
5433 " \"external_version\": \"1.0\","
5434 " \"supported_locales\": [ \"en\" ]"
5435 " },"
5436 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5437 " \"external_crx\": \"RandomExtension2.crx\","
5438 " \"external_version\": \"2.0\","
5439 " \"supported_locales\": [ \"en-GB\" ]"
5440 " },"
5441 " \"cccccccccccccccccccccccccccccccc\": {"
5442 " \"external_crx\": \"RandomExtension2.crx\","
5443 " \"external_version\": \"3.0\","
5444 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
5445 " }"
5446 "}";
5448 ScopedBrowserLocale guard("en-US");
5449 EXPECT_EQ(2, visitor.Visit(json_data));
5452 // Test keep_if_present.
5453 json_data =
5455 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5456 " \"external_crx\": \"RandomExtension.crx\","
5457 " \"external_version\": \"1.0\","
5458 " \"keep_if_present\": true"
5459 " }"
5460 "}";
5462 EXPECT_EQ(0, visitor.Visit(json_data));
5465 // Test is_bookmark_app.
5466 MockProviderVisitor from_bookmark_visitor(
5467 base_path, Extension::FROM_BOOKMARK);
5468 json_data =
5470 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5471 " \"external_crx\": \"RandomExtension.crx\","
5472 " \"external_version\": \"1.0\","
5473 " \"is_bookmark_app\": true"
5474 " }"
5475 "}";
5476 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
5478 // Test is_from_webstore.
5479 MockProviderVisitor from_webstore_visitor(
5480 base_path, Extension::FROM_WEBSTORE);
5481 json_data =
5483 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5484 " \"external_crx\": \"RandomExtension.crx\","
5485 " \"external_version\": \"1.0\","
5486 " \"is_from_webstore\": true"
5487 " }"
5488 "}";
5489 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
5491 // Test was_installed_by_eom.
5492 MockProviderVisitor was_installed_by_eom_visitor(
5493 base_path, Extension::WAS_INSTALLED_BY_OEM);
5494 json_data =
5496 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5497 " \"external_crx\": \"RandomExtension.crx\","
5498 " \"external_version\": \"1.0\","
5499 " \"was_installed_by_oem\": true"
5500 " }"
5501 "}";
5502 EXPECT_EQ(1, was_installed_by_eom_visitor.Visit(json_data));
5504 // Test min_profile_created_by_version.
5505 MockProviderVisitor min_profile_created_by_version_visitor(base_path);
5506 json_data =
5508 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5509 " \"external_crx\": \"RandomExtension.crx\","
5510 " \"external_version\": \"1.0\","
5511 " \"min_profile_created_by_version\": \"42.0.0.1\""
5512 " },"
5513 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5514 " \"external_crx\": \"RandomExtension2.crx\","
5515 " \"external_version\": \"1.0\","
5516 " \"min_profile_created_by_version\": \"43.0.0.1\""
5517 " },"
5518 " \"cccccccccccccccccccccccccccccccc\": {"
5519 " \"external_crx\": \"RandomExtension3.crx\","
5520 " \"external_version\": \"3.0\","
5521 " \"min_profile_created_by_version\": \"44.0.0.1\""
5522 " }"
5523 "}";
5524 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5525 prefs::kProfileCreatedByVersion, "40.0.0.1");
5526 EXPECT_EQ(0, min_profile_created_by_version_visitor.Visit(json_data));
5527 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5528 prefs::kProfileCreatedByVersion, "43.0.0.1");
5529 EXPECT_EQ(2, min_profile_created_by_version_visitor.Visit(json_data));
5530 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5531 prefs::kProfileCreatedByVersion, "45.0.0.1");
5532 EXPECT_EQ(3, min_profile_created_by_version_visitor.Visit(json_data));
5535 TEST_F(ExtensionServiceTest, DoNotInstallForEnterprise) {
5536 InitializeEmptyExtensionService();
5538 const base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5539 ASSERT_TRUE(base_path.IsAbsolute());
5540 MockProviderVisitor visitor(base_path);
5541 policy::ProfilePolicyConnector* const connector =
5542 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(
5543 visitor.profile());
5544 connector->OverrideIsManagedForTesting(true);
5545 EXPECT_TRUE(connector->IsManaged());
5547 std::string json_data =
5549 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5550 " \"external_crx\": \"RandomExtension.crx\","
5551 " \"external_version\": \"1.0\","
5552 " \"do_not_install_for_enterprise\": true"
5553 " },"
5554 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5555 " \"external_crx\": \"RandomExtension2.crx\","
5556 " \"external_version\": \"1.0\""
5557 " }"
5558 "}";
5559 EXPECT_EQ(1, visitor.Visit(json_data));
5562 // Test loading good extensions from the profile directory.
5563 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
5564 // Ensure we're testing in "en" and leave global state untouched.
5565 extension_l10n_util::ScopedLocaleForTest testLocale("en");
5567 // Initialize the test dir with a good Preferences/extensions.
5568 base::FilePath source_install_dir = data_dir().AppendASCII("l10n");
5569 base::FilePath pref_path =
5570 source_install_dir.Append(chrome::kPreferencesFilename);
5571 InitializeInstalledExtensionService(pref_path, source_install_dir);
5573 service()->Init();
5575 ASSERT_EQ(3u, loaded_.size());
5577 // This was equal to "sr" on load.
5578 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
5580 // These are untouched by re-localization.
5581 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
5582 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
5584 // This one starts with Serbian name, and gets re-localized into English.
5585 EXPECT_EQ("My name is simple.", loaded_[0]->name());
5587 // These are untouched by re-localization.
5588 EXPECT_EQ("My name is simple.", loaded_[1]->name());
5589 EXPECT_EQ("no l10n", loaded_[2]->name());
5592 class ExtensionsReadyRecorder : public content::NotificationObserver {
5593 public:
5594 ExtensionsReadyRecorder() : ready_(false) {
5595 registrar_.Add(this,
5596 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
5597 content::NotificationService::AllSources());
5600 void set_ready(bool value) { ready_ = value; }
5601 bool ready() { return ready_; }
5603 private:
5604 void Observe(int type,
5605 const content::NotificationSource& source,
5606 const content::NotificationDetails& details) override {
5607 switch (type) {
5608 case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED:
5609 ready_ = true;
5610 break;
5611 default:
5612 NOTREACHED();
5616 content::NotificationRegistrar registrar_;
5617 bool ready_;
5620 // Test that we get enabled/disabled correctly for all the pref/command-line
5621 // combinations. We don't want to derive from the ExtensionServiceTest class
5622 // for this test, so we use ExtensionServiceTestSimple.
5624 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
5625 // enabled or not.
5626 class ExtensionServiceTestSimple : public testing::Test {
5627 content::TestBrowserThreadBundle thread_bundle_;
5630 TEST_F(ExtensionServiceTestSimple, Enabledness) {
5631 // Make sure the PluginService singleton is destroyed at the end of the test.
5632 base::ShadowingAtExitManager at_exit_manager;
5633 #if defined(ENABLE_PLUGINS)
5634 content::PluginService::GetInstance()->Init();
5635 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
5636 #endif
5638 ExtensionErrorReporter::Init(false); // no noisy errors
5639 ExtensionsReadyRecorder recorder;
5640 scoped_ptr<TestingProfile> profile(new TestingProfile());
5641 #if defined OS_CHROMEOS
5642 chromeos::ScopedTestDeviceSettingsService device_settings_service;
5643 chromeos::ScopedTestCrosSettings cros_settings;
5644 scoped_ptr<chromeos::ScopedTestUserManager> user_manager(
5645 new chromeos::ScopedTestUserManager);
5646 #endif
5647 scoped_ptr<base::CommandLine> command_line;
5648 base::FilePath install_dir = profile->GetPath()
5649 .AppendASCII(extensions::kInstallDirectoryName);
5651 // By default, we are enabled.
5652 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5653 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
5654 ExtensionSystem::Get(profile.get()))->
5655 CreateExtensionService(
5656 command_line.get(),
5657 install_dir,
5658 false);
5659 EXPECT_TRUE(service->extensions_enabled());
5660 service->Init();
5661 base::RunLoop().RunUntilIdle();
5662 EXPECT_TRUE(recorder.ready());
5663 #if defined OS_CHROMEOS
5664 user_manager.reset();
5665 #endif
5667 // If either the command line or pref is set, we are disabled.
5668 recorder.set_ready(false);
5669 profile.reset(new TestingProfile());
5670 command_line->AppendSwitch(switches::kDisableExtensions);
5671 service = static_cast<extensions::TestExtensionSystem*>(
5672 ExtensionSystem::Get(profile.get()))->
5673 CreateExtensionService(
5674 command_line.get(),
5675 install_dir,
5676 false);
5677 EXPECT_FALSE(service->extensions_enabled());
5678 service->Init();
5679 base::RunLoop().RunUntilIdle();
5680 EXPECT_TRUE(recorder.ready());
5682 recorder.set_ready(false);
5683 profile.reset(new TestingProfile());
5684 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5685 service = static_cast<extensions::TestExtensionSystem*>(
5686 ExtensionSystem::Get(profile.get()))->
5687 CreateExtensionService(
5688 command_line.get(),
5689 install_dir,
5690 false);
5691 EXPECT_FALSE(service->extensions_enabled());
5692 service->Init();
5693 base::RunLoop().RunUntilIdle();
5694 EXPECT_TRUE(recorder.ready());
5696 recorder.set_ready(false);
5697 profile.reset(new TestingProfile());
5698 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5699 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5700 service = static_cast<extensions::TestExtensionSystem*>(
5701 ExtensionSystem::Get(profile.get()))->
5702 CreateExtensionService(
5703 command_line.get(),
5704 install_dir,
5705 false);
5706 EXPECT_FALSE(service->extensions_enabled());
5707 service->Init();
5708 base::RunLoop().RunUntilIdle();
5709 EXPECT_TRUE(recorder.ready());
5711 // Explicitly delete all the resources used in this test.
5712 profile.reset();
5713 service = NULL;
5714 // Execute any pending deletion tasks.
5715 base::RunLoop().RunUntilIdle();
5718 // Test loading extensions that require limited and unlimited storage quotas.
5719 TEST_F(ExtensionServiceTest, StorageQuota) {
5720 InitializeEmptyExtensionService();
5722 base::FilePath extensions_path = data_dir().AppendASCII("storage_quota");
5724 base::FilePath limited_quota_ext =
5725 extensions_path.AppendASCII("limited_quota")
5726 .AppendASCII("1.0");
5728 // The old permission name for unlimited quota was "unlimited_storage", but
5729 // we changed it to "unlimitedStorage". This tests both versions.
5730 base::FilePath unlimited_quota_ext =
5731 extensions_path.AppendASCII("unlimited_quota")
5732 .AppendASCII("1.0");
5733 base::FilePath unlimited_quota_ext2 =
5734 extensions_path.AppendASCII("unlimited_quota")
5735 .AppendASCII("2.0");
5736 extensions::UnpackedInstaller::Create(service())->Load(limited_quota_ext);
5737 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext);
5738 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext2);
5739 base::RunLoop().RunUntilIdle();
5741 ASSERT_EQ(3u, loaded_.size());
5742 EXPECT_TRUE(profile());
5743 EXPECT_FALSE(profile()->IsOffTheRecord());
5744 EXPECT_FALSE(
5745 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5746 loaded_[0]->url()));
5747 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5748 loaded_[1]->url()));
5749 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5750 loaded_[2]->url()));
5753 // Tests ComponentLoader::Add().
5754 TEST_F(ExtensionServiceTest, ComponentExtensions) {
5755 InitializeEmptyExtensionService();
5757 // Component extensions should work even when extensions are disabled.
5758 service()->set_extensions_enabled(false);
5760 base::FilePath path = data_dir()
5761 .AppendASCII("good")
5762 .AppendASCII("Extensions")
5763 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
5764 .AppendASCII("1.0.0.0");
5766 std::string manifest;
5767 ASSERT_TRUE(base::ReadFileToString(
5768 path.Append(extensions::kManifestFilename), &manifest));
5770 service()->component_loader()->Add(manifest, path);
5771 service()->Init();
5773 // Note that we do not pump messages -- the extension should be loaded
5774 // immediately.
5776 EXPECT_EQ(0u, GetErrors().size());
5777 ASSERT_EQ(1u, loaded_.size());
5778 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
5779 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5781 // Component extensions get a prefs entry on first install.
5782 ValidatePrefKeyCount(1);
5784 // Reload all extensions, and make sure it comes back.
5785 std::string extension_id = (*registry()->enabled_extensions().begin())->id();
5786 loaded_.clear();
5787 service()->ReloadExtensionsForTest();
5788 ASSERT_EQ(1u, registry()->enabled_extensions().size());
5789 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id());
5792 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
5793 InitializeEmptyExtensionService();
5795 bool flare_was_called = false;
5796 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5797 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5798 extension_sync_service()->SetSyncStartFlare(
5799 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5800 factory.GetWeakPtr(),
5801 &flare_was_called, // Safe due to WeakPtrFactory scope.
5802 &triggered_type)); // Safe due to WeakPtrFactory scope.
5804 // Install a component extension.
5805 std::string manifest;
5806 ASSERT_TRUE(base::ReadFileToString(
5807 good0_path().Append(extensions::kManifestFilename), &manifest));
5808 service()->component_loader()->Add(manifest, good0_path());
5809 ASSERT_FALSE(service()->is_ready());
5810 service()->Init();
5811 ASSERT_TRUE(service()->is_ready());
5813 // Extensions added before service is_ready() don't trigger sync startup.
5814 EXPECT_FALSE(flare_was_called);
5815 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5818 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
5819 InitializeGoodInstalledExtensionService();
5821 bool flare_was_called = false;
5822 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5823 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5824 extension_sync_service()->SetSyncStartFlare(
5825 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5826 factory.GetWeakPtr(),
5827 &flare_was_called, // Safe due to WeakPtrFactory scope.
5828 &triggered_type)); // Safe due to WeakPtrFactory scope.
5830 ASSERT_FALSE(service()->is_ready());
5831 service()->Init();
5832 ASSERT_EQ(3u, loaded_.size());
5833 ASSERT_TRUE(service()->is_ready());
5835 // Extensions added before service is_ready() don't trigger sync startup.
5836 EXPECT_FALSE(flare_was_called);
5837 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5840 TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
5841 InitializeEmptyExtensionService();
5842 service()->Init();
5843 ASSERT_TRUE(service()->is_ready());
5845 bool flare_was_called = false;
5846 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5847 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5848 extension_sync_service()->SetSyncStartFlare(
5849 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5850 factory.GetWeakPtr(),
5851 &flare_was_called, // Safe due to WeakPtrFactory scope.
5852 &triggered_type)); // Safe due to WeakPtrFactory scope.
5854 base::FilePath path = data_dir().AppendASCII("good.crx");
5855 InstallCRX(path, INSTALL_NEW);
5857 EXPECT_TRUE(flare_was_called);
5858 EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
5860 // Reset.
5861 flare_was_called = false;
5862 triggered_type = syncer::UNSPECIFIED;
5864 // Once sync starts, flare should no longer be invoked.
5865 extension_sync_service()->MergeDataAndStartSyncing(
5866 syncer::EXTENSIONS,
5867 syncer::SyncDataList(),
5868 scoped_ptr<syncer::SyncChangeProcessor>(
5869 new syncer::FakeSyncChangeProcessor),
5870 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5871 path = data_dir().AppendASCII("page_action.crx");
5872 InstallCRX(path, INSTALL_NEW);
5873 EXPECT_FALSE(flare_was_called);
5874 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5877 TEST_F(ExtensionServiceTest, DisableExtensionFromSync) {
5878 // Start the extensions service with one external extension already installed.
5879 base::FilePath source_install_dir =
5880 data_dir().AppendASCII("good").AppendASCII("Extensions");
5881 base::FilePath pref_path =
5882 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5884 InitializeInstalledExtensionService(pref_path, source_install_dir);
5886 // The user has enabled sync.
5887 ProfileSyncService* sync_service =
5888 ProfileSyncServiceFactory::GetForProfile(profile());
5889 sync_service->SetSyncSetupCompleted();
5891 service()->Init();
5892 ASSERT_TRUE(service()->is_ready());
5894 ASSERT_EQ(3u, loaded_.size());
5896 // We start enabled.
5897 const Extension* extension = service()->GetExtensionById(good0, true);
5898 ASSERT_TRUE(extension);
5899 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5901 // Sync starts up.
5902 extension_sync_service()->MergeDataAndStartSyncing(
5903 syncer::EXTENSIONS,
5904 syncer::SyncDataList(),
5905 make_scoped_ptr(new syncer::FakeSyncChangeProcessor),
5906 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5908 // Then sync data arrives telling us to disable |good0|.
5909 ExtensionSyncData disable_good_crx(*extension, false,
5910 Extension::DISABLE_USER_ACTION, false,
5911 false, ExtensionSyncData::BOOLEAN_UNSET);
5912 syncer::SyncChange sync_change(FROM_HERE,
5913 syncer::SyncChange::ACTION_UPDATE,
5914 disable_good_crx.GetSyncData());
5915 syncer::SyncChangeList list(1, sync_change);
5916 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5918 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5921 TEST_F(ExtensionServiceTest, IgnoreSyncChangesWhenLocalStateIsMoreRecent) {
5922 // Start the extension service with three extensions already installed.
5923 base::FilePath source_install_dir =
5924 data_dir().AppendASCII("good").AppendASCII("Extensions");
5925 base::FilePath pref_path =
5926 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5928 InitializeInstalledExtensionService(pref_path, source_install_dir);
5930 // The user has enabled sync.
5931 ProfileSyncService* sync_service =
5932 ProfileSyncServiceFactory::GetForProfile(profile());
5933 sync_service->SetSyncSetupCompleted();
5935 service()->Init();
5936 ASSERT_TRUE(service()->is_ready());
5937 ASSERT_EQ(3u, loaded_.size());
5939 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5940 ASSERT_TRUE(service()->IsExtensionEnabled(good2));
5942 // Disable and re-enable good0 before first sync data arrives.
5943 service()->DisableExtension(good0, Extension::DISABLE_USER_ACTION);
5944 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5945 service()->EnableExtension(good0);
5946 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5947 // Disable good2 before first sync data arrives (good1 is considered
5948 // non-syncable because it has plugin permission).
5949 service()->DisableExtension(good2, Extension::DISABLE_USER_ACTION);
5950 ASSERT_FALSE(service()->IsExtensionEnabled(good2));
5952 const Extension* extension0 = service()->GetExtensionById(good0, true);
5953 const Extension* extension2 = service()->GetExtensionById(good2, true);
5954 ASSERT_TRUE(extensions::sync_helper::IsSyncable(extension0));
5955 ASSERT_TRUE(extensions::sync_helper::IsSyncable(extension2));
5957 // Now sync data comes in that says to disable good0 and enable good2.
5958 ExtensionSyncData disable_good0(*extension0, false,
5959 Extension::DISABLE_USER_ACTION, false, false,
5960 ExtensionSyncData::BOOLEAN_UNSET);
5961 ExtensionSyncData enable_good2(*extension2, true, Extension::DISABLE_NONE,
5962 false, false,
5963 ExtensionSyncData::BOOLEAN_UNSET);
5964 syncer::SyncDataList sync_data;
5965 sync_data.push_back(disable_good0.GetSyncData());
5966 sync_data.push_back(enable_good2.GetSyncData());
5967 extension_sync_service()->MergeDataAndStartSyncing(
5968 syncer::EXTENSIONS,
5969 sync_data,
5970 make_scoped_ptr(new syncer::FakeSyncChangeProcessor),
5971 make_scoped_ptr(new syncer::SyncErrorFactoryMock));
5973 // Both sync changes should be ignored, since the local state was changed
5974 // before sync started, and so the local state is considered more recent.
5975 EXPECT_TRUE(service()->IsExtensionEnabled(good0));
5976 EXPECT_FALSE(service()->IsExtensionEnabled(good2));
5979 TEST_F(ExtensionServiceTest, GetSyncData) {
5980 InitializeEmptyExtensionService();
5981 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5982 const Extension* extension = service()->GetInstalledExtension(good_crx);
5983 ASSERT_TRUE(extension);
5985 extension_sync_service()->MergeDataAndStartSyncing(
5986 syncer::EXTENSIONS,
5987 syncer::SyncDataList(),
5988 scoped_ptr<syncer::SyncChangeProcessor>(
5989 new syncer::FakeSyncChangeProcessor),
5990 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5992 syncer::SyncDataList list =
5993 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5994 ASSERT_EQ(list.size(), 1U);
5995 scoped_ptr<ExtensionSyncData> data =
5996 ExtensionSyncData::CreateFromSyncData(list[0]);
5997 ASSERT_TRUE(data.get());
5998 EXPECT_EQ(extension->id(), data->id());
5999 EXPECT_FALSE(data->uninstalled());
6000 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
6001 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
6002 data->incognito_enabled());
6003 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6004 EXPECT_TRUE(data->version().Equals(*extension->version()));
6005 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
6006 data->update_url());
6007 EXPECT_EQ(extension->name(), data->name());
6010 TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
6011 InitializeEmptyExtensionService();
6012 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6013 TerminateExtension(good_crx);
6014 const Extension* extension = service()->GetInstalledExtension(good_crx);
6015 ASSERT_TRUE(extension);
6017 syncer::FakeSyncChangeProcessor processor;
6018 extension_sync_service()->MergeDataAndStartSyncing(
6019 syncer::EXTENSIONS,
6020 syncer::SyncDataList(),
6021 scoped_ptr<syncer::SyncChangeProcessor>(
6022 new syncer::FakeSyncChangeProcessor),
6023 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6025 syncer::SyncDataList list =
6026 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6027 ASSERT_EQ(list.size(), 1U);
6028 scoped_ptr<ExtensionSyncData> data =
6029 ExtensionSyncData::CreateFromSyncData(list[0]);
6030 ASSERT_TRUE(data.get());
6031 EXPECT_EQ(extension->id(), data->id());
6032 EXPECT_FALSE(data->uninstalled());
6033 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
6034 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
6035 data->incognito_enabled());
6036 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6037 EXPECT_TRUE(data->version().Equals(*extension->version()));
6038 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
6039 data->update_url());
6040 EXPECT_EQ(extension->name(), data->name());
6043 TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
6044 InitializeEmptyExtensionService();
6045 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6046 const Extension* extension = service()->GetInstalledExtension(good_crx);
6047 ASSERT_TRUE(extension);
6049 syncer::FakeSyncChangeProcessor processor;
6050 extension_sync_service()->MergeDataAndStartSyncing(
6051 syncer::APPS,
6052 syncer::SyncDataList(),
6053 scoped_ptr<syncer::SyncChangeProcessor>(
6054 new syncer::FakeSyncChangeProcessor),
6055 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6057 syncer::SyncDataList list =
6058 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6059 ASSERT_EQ(list.size(), 0U);
6062 TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
6063 InitializeEmptyExtensionService();
6064 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6065 const Extension* extension = service()->GetInstalledExtension(good_crx);
6066 ASSERT_TRUE(extension);
6068 syncer::FakeSyncChangeProcessor processor;
6069 extension_sync_service()->MergeDataAndStartSyncing(
6070 syncer::EXTENSIONS,
6071 syncer::SyncDataList(),
6072 scoped_ptr<syncer::SyncChangeProcessor>(
6073 new syncer::FakeSyncChangeProcessor),
6074 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6077 syncer::SyncDataList list =
6078 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6079 ASSERT_EQ(list.size(), 1U);
6080 scoped_ptr<ExtensionSyncData> data =
6081 ExtensionSyncData::CreateFromSyncData(list[0]);
6082 ASSERT_TRUE(data.get());
6083 EXPECT_TRUE(data->enabled());
6084 EXPECT_FALSE(data->incognito_enabled());
6085 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6088 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
6090 syncer::SyncDataList list =
6091 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6092 ASSERT_EQ(list.size(), 1U);
6093 scoped_ptr<ExtensionSyncData> data =
6094 ExtensionSyncData::CreateFromSyncData(list[0]);
6095 ASSERT_TRUE(data.get());
6096 EXPECT_FALSE(data->enabled());
6097 EXPECT_FALSE(data->incognito_enabled());
6098 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6101 extensions::util::SetIsIncognitoEnabled(good_crx, profile(), true);
6102 extensions::util::SetAllowedScriptingOnAllUrls(
6103 good_crx, profile(), false);
6105 syncer::SyncDataList list =
6106 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6107 ASSERT_EQ(list.size(), 1U);
6108 scoped_ptr<ExtensionSyncData> data =
6109 ExtensionSyncData::CreateFromSyncData(list[0]);
6110 ASSERT_TRUE(data.get());
6111 EXPECT_FALSE(data->enabled());
6112 EXPECT_TRUE(data->incognito_enabled());
6113 EXPECT_EQ(ExtensionSyncData::BOOLEAN_FALSE, data->all_urls_enabled());
6116 service()->EnableExtension(good_crx);
6117 extensions::util::SetAllowedScriptingOnAllUrls(
6118 good_crx, profile(), true);
6120 syncer::SyncDataList list =
6121 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6122 ASSERT_EQ(list.size(), 1U);
6123 scoped_ptr<ExtensionSyncData> data =
6124 ExtensionSyncData::CreateFromSyncData(list[0]);
6125 ASSERT_TRUE(data.get());
6126 EXPECT_TRUE(data->enabled());
6127 EXPECT_TRUE(data->incognito_enabled());
6128 EXPECT_EQ(ExtensionSyncData::BOOLEAN_TRUE, data->all_urls_enabled());
6132 TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
6133 InitializeEmptyExtensionService();
6134 InstallCRXWithLocation(
6135 data_dir().AppendASCII("good.crx"), Manifest::EXTERNAL_PREF, INSTALL_NEW);
6136 const Extension* extension = service()->GetInstalledExtension(good_crx);
6137 ASSERT_TRUE(extension);
6139 syncer::FakeSyncChangeProcessor processor;
6140 extension_sync_service()->MergeDataAndStartSyncing(
6141 syncer::EXTENSIONS,
6142 syncer::SyncDataList(),
6143 scoped_ptr<syncer::SyncChangeProcessor>(
6144 new syncer::FakeSyncChangeProcessor),
6145 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6147 UninstallExtension(good_crx, false);
6148 EXPECT_TRUE(
6149 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
6151 sync_pb::EntitySpecifics specifics;
6152 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6153 sync_pb::ExtensionSpecifics* extension_specifics =
6154 app_specifics->mutable_extension();
6155 extension_specifics->set_id(good_crx);
6156 extension_specifics->set_version("1.0");
6157 extension_specifics->set_enabled(true);
6159 syncer::SyncData sync_data =
6160 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6161 syncer::SyncChange sync_change(FROM_HERE,
6162 syncer::SyncChange::ACTION_UPDATE,
6163 sync_data);
6164 syncer::SyncChangeList list(1);
6165 list[0] = sync_change;
6167 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6168 EXPECT_TRUE(
6169 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
6172 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
6173 InitializeEmptyExtensionService();
6174 const Extension* app =
6175 PackAndInstallCRX(data_dir().AppendASCII("app"), INSTALL_NEW);
6176 ASSERT_TRUE(app);
6177 ASSERT_TRUE(app->is_app());
6179 syncer::FakeSyncChangeProcessor processor;
6180 extension_sync_service()->MergeDataAndStartSyncing(
6181 syncer::APPS,
6182 syncer::SyncDataList(),
6183 scoped_ptr<syncer::SyncChangeProcessor>(
6184 new syncer::FakeSyncChangeProcessor),
6185 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6187 syncer::StringOrdinal initial_ordinal =
6188 syncer::StringOrdinal::CreateInitialOrdinal();
6190 syncer::SyncDataList list =
6191 extension_sync_service()->GetAllSyncData(syncer::APPS);
6192 ASSERT_EQ(list.size(), 1U);
6194 scoped_ptr<ExtensionSyncData> app_sync_data =
6195 ExtensionSyncData::CreateFromSyncData(list[0]);
6196 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->app_launch_ordinal()));
6197 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6200 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
6201 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
6203 syncer::SyncDataList list =
6204 extension_sync_service()->GetAllSyncData(syncer::APPS);
6205 ASSERT_EQ(list.size(), 1U);
6207 scoped_ptr<ExtensionSyncData> app_sync_data =
6208 ExtensionSyncData::CreateFromSyncData(list[0]);
6209 ASSERT_TRUE(app_sync_data.get());
6210 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6211 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6214 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
6216 syncer::SyncDataList list =
6217 extension_sync_service()->GetAllSyncData(syncer::APPS);
6218 ASSERT_EQ(list.size(), 1U);
6220 scoped_ptr<ExtensionSyncData> app_sync_data =
6221 ExtensionSyncData::CreateFromSyncData(list[0]);
6222 ASSERT_TRUE(app_sync_data.get());
6223 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6224 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->page_ordinal()));
6228 // TODO (rdevlin.cronin): The OnExtensionMoved() method has been removed from
6229 // ExtensionService, so this test probably needs a new home. Unfortunately, it
6230 // relies pretty heavily on things like InitializeExtension[Sync]Service() and
6231 // PackAndInstallCRX(). When we clean up a bit more, this should move out.
6232 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
6233 InitializeEmptyExtensionService();
6234 const size_t kAppCount = 3;
6235 const Extension* apps[kAppCount];
6236 apps[0] = PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
6237 apps[1] = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
6238 apps[2] = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
6239 for (size_t i = 0; i < kAppCount; ++i) {
6240 ASSERT_TRUE(apps[i]);
6241 ASSERT_TRUE(apps[i]->is_app());
6244 syncer::FakeSyncChangeProcessor processor;
6245 extension_sync_service()->MergeDataAndStartSyncing(
6246 syncer::APPS,
6247 syncer::SyncDataList(),
6248 scoped_ptr<syncer::SyncChangeProcessor>(
6249 new syncer::FakeSyncChangeProcessor),
6250 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6252 ExtensionPrefs::Get(service()->GetBrowserContext())
6253 ->app_sorting()
6254 ->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
6256 syncer::SyncDataList list =
6257 extension_sync_service()->GetAllSyncData(syncer::APPS);
6258 ASSERT_EQ(list.size(), 3U);
6260 scoped_ptr<ExtensionSyncData> data[kAppCount];
6261 for (size_t i = 0; i < kAppCount; ++i) {
6262 data[i] = ExtensionSyncData::CreateFromSyncData(list[i]);
6263 ASSERT_TRUE(data[i].get());
6266 // The sync data is not always in the same order our apps were installed in,
6267 // so we do that sorting here so we can make sure the values are changed as
6268 // expected.
6269 syncer::StringOrdinal app_launch_ordinals[kAppCount];
6270 for (size_t i = 0; i < kAppCount; ++i) {
6271 for (size_t j = 0; j < kAppCount; ++j) {
6272 if (apps[i]->id() == data[j]->id())
6273 app_launch_ordinals[i] = data[j]->app_launch_ordinal();
6277 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
6278 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
6282 TEST_F(ExtensionServiceTest, GetSyncDataList) {
6283 InitializeEmptyExtensionService();
6284 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6285 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
6286 InstallCRX(data_dir().AppendASCII("theme.crx"), INSTALL_NEW);
6287 InstallCRX(data_dir().AppendASCII("theme2.crx"), INSTALL_NEW);
6289 syncer::FakeSyncChangeProcessor processor;
6290 extension_sync_service()->MergeDataAndStartSyncing(
6291 syncer::APPS,
6292 syncer::SyncDataList(),
6293 scoped_ptr<syncer::SyncChangeProcessor>(
6294 new syncer::FakeSyncChangeProcessor),
6295 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6296 extension_sync_service()->MergeDataAndStartSyncing(
6297 syncer::EXTENSIONS,
6298 syncer::SyncDataList(),
6299 scoped_ptr<syncer::SyncChangeProcessor>(
6300 new syncer::FakeSyncChangeProcessor),
6301 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6303 service()->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
6304 TerminateExtension(theme2_crx);
6306 EXPECT_EQ(0u, extension_sync_service()->GetAllSyncData(syncer::APPS).size());
6307 EXPECT_EQ(
6308 2u, extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS).size());
6311 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
6312 InitializeEmptyExtensionService();
6313 syncer::FakeSyncChangeProcessor processor;
6314 extension_sync_service()->MergeDataAndStartSyncing(
6315 syncer::EXTENSIONS,
6316 syncer::SyncDataList(),
6317 scoped_ptr<syncer::SyncChangeProcessor>(
6318 new syncer::FakeSyncChangeProcessor),
6319 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6321 sync_pb::EntitySpecifics specifics;
6322 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6323 ext_specifics->set_id(good_crx);
6324 ext_specifics->set_version("1.0");
6325 syncer::SyncData sync_data =
6326 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6327 syncer::SyncChange sync_change(FROM_HERE,
6328 syncer::SyncChange::ACTION_DELETE,
6329 sync_data);
6330 syncer::SyncChangeList list(1);
6331 list[0] = sync_change;
6333 // Should do nothing.
6334 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6335 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6337 // Install the extension.
6338 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6339 InstallCRX(extension_path, INSTALL_NEW);
6340 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6342 // Should uninstall the extension.
6343 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6344 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6346 // Should again do nothing.
6347 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6348 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6351 TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
6352 InitializeEmptyExtensionService();
6354 // Install the extension.
6355 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6356 InstallCRX(extension_path, INSTALL_NEW);
6357 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6359 sync_pb::EntitySpecifics specifics;
6360 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6361 sync_pb::ExtensionSpecifics* extension_specifics =
6362 app_specifics->mutable_extension();
6363 extension_specifics->set_id(good_crx);
6364 extension_specifics->set_version(
6365 service()->GetInstalledExtension(good_crx)->version()->GetString());
6368 extension_specifics->set_enabled(true);
6369 syncer::SyncData sync_data =
6370 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6371 syncer::SyncChange sync_change(FROM_HERE,
6372 syncer::SyncChange::ACTION_DELETE,
6373 sync_data);
6374 syncer::SyncChangeList list(1);
6375 list[0] = sync_change;
6377 // Should do nothing
6378 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6379 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6383 extension_specifics->set_enabled(false);
6384 syncer::SyncData sync_data =
6385 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6386 syncer::SyncChange sync_change(FROM_HERE,
6387 syncer::SyncChange::ACTION_UPDATE,
6388 sync_data);
6389 syncer::SyncChangeList list(1);
6390 list[0] = sync_change;
6392 // Should again do nothing.
6393 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6394 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
6398 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
6399 InitializeEmptyExtensionService();
6400 syncer::FakeSyncChangeProcessor processor;
6401 extension_sync_service()->MergeDataAndStartSyncing(
6402 syncer::EXTENSIONS,
6403 syncer::SyncDataList(),
6404 scoped_ptr<syncer::SyncChangeProcessor>(
6405 new syncer::FakeSyncChangeProcessor),
6406 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6408 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6409 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6410 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6411 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6412 good_crx, profile()));
6413 const bool kDefaultAllowedScripting =
6414 extensions::util::DefaultAllowedScriptingOnAllUrls();
6415 EXPECT_EQ(kDefaultAllowedScripting,
6416 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6418 sync_pb::EntitySpecifics specifics;
6419 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6420 ext_specifics->set_id(good_crx);
6421 ext_specifics->set_version(
6422 service()->GetInstalledExtension(good_crx)->version()->GetString());
6423 ext_specifics->set_enabled(false);
6426 syncer::SyncData sync_data =
6427 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6428 syncer::SyncChange sync_change(FROM_HERE,
6429 syncer::SyncChange::ACTION_UPDATE,
6430 sync_data);
6431 syncer::SyncChangeList list(1);
6432 list[0] = sync_change;
6433 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6434 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6435 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6436 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6437 good_crx, profile()));
6438 EXPECT_EQ(kDefaultAllowedScripting,
6439 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6443 ext_specifics->set_enabled(true);
6444 ext_specifics->set_incognito_enabled(true);
6445 syncer::SyncData sync_data =
6446 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6447 syncer::SyncChange sync_change(FROM_HERE,
6448 syncer::SyncChange::ACTION_UPDATE,
6449 sync_data);
6450 syncer::SyncChangeList list(1);
6451 list[0] = sync_change;
6452 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6453 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6454 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6458 ext_specifics->set_enabled(false);
6459 ext_specifics->set_incognito_enabled(true);
6460 syncer::SyncData sync_data =
6461 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6462 syncer::SyncChange sync_change(FROM_HERE,
6463 syncer::SyncChange::ACTION_UPDATE,
6464 sync_data);
6465 syncer::SyncChangeList list(1);
6466 list[0] = sync_change;
6467 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6468 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6469 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6473 ext_specifics->set_enabled(true);
6474 ext_specifics->set_all_urls_enabled(!kDefaultAllowedScripting);
6475 syncer::SyncData sync_data =
6476 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6477 syncer::SyncChange sync_change(FROM_HERE,
6478 syncer::SyncChange::ACTION_UPDATE,
6479 sync_data);
6480 syncer::SyncChangeList list(1);
6481 list[0] = sync_change;
6482 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6483 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6484 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6485 good_crx, profile()));
6486 EXPECT_EQ(!kDefaultAllowedScripting,
6487 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6491 ext_specifics->set_all_urls_enabled(kDefaultAllowedScripting);
6492 syncer::SyncData sync_data =
6493 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6494 syncer::SyncChange sync_change(FROM_HERE,
6495 syncer::SyncChange::ACTION_UPDATE,
6496 sync_data);
6497 syncer::SyncChangeList list(1);
6498 list[0] = sync_change;
6499 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6500 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6501 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6502 good_crx, profile()));
6503 EXPECT_EQ(kDefaultAllowedScripting,
6504 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6507 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6510 TEST_F(ExtensionServiceTest, ProcessSyncDataNewExtension) {
6511 InitializeEmptyExtensionService();
6512 syncer::FakeSyncChangeProcessor processor;
6513 extension_sync_service()->MergeDataAndStartSyncing(
6514 syncer::EXTENSIONS,
6515 syncer::SyncDataList(),
6516 scoped_ptr<syncer::SyncChangeProcessor>(
6517 new syncer::FakeSyncChangeProcessor),
6518 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6520 const base::FilePath path = data_dir().AppendASCII("good.crx");
6521 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6523 struct TestCase {
6524 const char* name; // For failure output only.
6525 bool sync_enabled; // The "enabled" flag coming in from Sync.
6526 // The disable reason(s) coming in from Sync, or -1 for "not set".
6527 int sync_disable_reasons;
6528 // The disable reason(s) that should be set on the installed extension.
6529 // This will usually be the same as |sync_disable_reasons|, but see the
6530 // "Legacy" case.
6531 int expect_disable_reasons;
6532 // Whether the extension's permissions should be auto-granted during
6533 // installation.
6534 bool expect_permissions_granted;
6535 } test_cases[] = {
6536 // Standard case: Extension comes in enabled; permissions should be granted
6537 // during installation.
6538 { "Standard", true, 0, 0, true },
6539 // If the extension comes in disabled, its permissions should still be
6540 // granted (the user already approved them on another machine).
6541 { "Disabled", false, Extension::DISABLE_USER_ACTION,
6542 Extension::DISABLE_USER_ACTION, true },
6543 // Legacy case (<M45): No disable reasons come in from Sync (see
6544 // crbug.com/484214). After installation, the reason should be set to
6545 // DISABLE_UNKNOWN_FROM_SYNC.
6546 { "Legacy", false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC, true },
6547 // If the extension came in disabled due to a permissions increase, then the
6548 // user has *not* approved the permissions, and they shouldn't be granted.
6549 // crbug.com/484214
6550 { "PermissionsIncrease", false, Extension::DISABLE_PERMISSIONS_INCREASE,
6551 Extension::DISABLE_PERMISSIONS_INCREASE, false },
6554 for (const TestCase& test_case : test_cases) {
6555 SCOPED_TRACE(test_case.name);
6557 sync_pb::EntitySpecifics specifics;
6558 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6559 ext_specifics->set_id(good_crx);
6560 ext_specifics->set_version(base::Version("1").GetString());
6561 ext_specifics->set_enabled(test_case.sync_enabled);
6562 if (test_case.sync_disable_reasons != -1)
6563 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6565 syncer::SyncData sync_data =
6566 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6567 syncer::SyncChange sync_change(FROM_HERE,
6568 syncer::SyncChange::ACTION_UPDATE,
6569 sync_data);
6570 syncer::SyncChangeList list(1, sync_change);
6571 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6573 ASSERT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
6574 UpdateExtension(good_crx, path, test_case.sync_enabled ? ENABLED
6575 : DISABLED);
6576 EXPECT_EQ(test_case.expect_disable_reasons,
6577 prefs->GetDisableReasons(good_crx));
6578 scoped_refptr<PermissionSet> permissions(
6579 prefs->GetGrantedPermissions(good_crx));
6580 EXPECT_EQ(test_case.expect_permissions_granted, !permissions->IsEmpty());
6581 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6583 // Remove the extension again, so we can install it again for the next case.
6584 UninstallExtension(good_crx, false,
6585 test_case.sync_enabled ? Extension::ENABLED
6586 : Extension::DISABLED);
6590 TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
6591 InitializeExtensionServiceWithUpdater();
6592 syncer::FakeSyncChangeProcessor processor;
6593 extension_sync_service()->MergeDataAndStartSyncing(
6594 syncer::EXTENSIONS,
6595 syncer::SyncDataList(),
6596 scoped_ptr<syncer::SyncChangeProcessor>(
6597 new syncer::FakeSyncChangeProcessor),
6598 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6600 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6601 TerminateExtension(good_crx);
6602 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6603 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6605 sync_pb::EntitySpecifics specifics;
6606 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6607 ext_specifics->set_id(good_crx);
6608 ext_specifics->set_version(
6609 service()->GetInstalledExtension(good_crx)->version()->GetString());
6610 ext_specifics->set_enabled(false);
6611 ext_specifics->set_incognito_enabled(true);
6612 syncer::SyncData sync_data =
6613 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6614 syncer::SyncChange sync_change(FROM_HERE,
6615 syncer::SyncChange::ACTION_UPDATE,
6616 sync_data);
6617 syncer::SyncChangeList list(1);
6618 list[0] = sync_change;
6620 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6621 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6622 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6624 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6627 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
6628 InitializeExtensionServiceWithUpdater();
6629 syncer::FakeSyncChangeProcessor processor;
6630 extension_sync_service()->MergeDataAndStartSyncing(
6631 syncer::EXTENSIONS,
6632 syncer::SyncDataList(),
6633 scoped_ptr<syncer::SyncChangeProcessor>(
6634 new syncer::FakeSyncChangeProcessor),
6635 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6637 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6638 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6639 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6641 sync_pb::EntitySpecifics specifics;
6642 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6643 ext_specifics->set_id(good_crx);
6644 ext_specifics->set_enabled(true);
6647 ext_specifics->set_version(
6648 service()->GetInstalledExtension(good_crx)->version()->GetString());
6649 syncer::SyncData sync_data =
6650 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6651 syncer::SyncChange sync_change(FROM_HERE,
6652 syncer::SyncChange::ACTION_UPDATE,
6653 sync_data);
6654 syncer::SyncChangeList list(1);
6655 list[0] = sync_change;
6657 // Should do nothing if extension version == sync version.
6658 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6659 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6662 // Should do nothing if extension version > sync version (but see
6663 // the TODO in ProcessExtensionSyncData).
6665 ext_specifics->set_version("0.0.0.0");
6666 syncer::SyncData sync_data =
6667 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6668 syncer::SyncChange sync_change(FROM_HERE,
6669 syncer::SyncChange::ACTION_UPDATE,
6670 sync_data);
6671 syncer::SyncChangeList list(1);
6672 list[0] = sync_change;
6674 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6675 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6678 // Should kick off an update if extension version < sync version.
6680 ext_specifics->set_version("9.9.9.9");
6681 syncer::SyncData sync_data =
6682 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6683 syncer::SyncChange sync_change(FROM_HERE,
6684 syncer::SyncChange::ACTION_UPDATE,
6685 sync_data);
6686 syncer::SyncChangeList list(1);
6687 list[0] = sync_change;
6689 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6690 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6693 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6696 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
6697 InitializeExtensionServiceWithUpdater();
6698 syncer::FakeSyncChangeProcessor processor;
6699 extension_sync_service()->MergeDataAndStartSyncing(
6700 syncer::EXTENSIONS,
6701 syncer::SyncDataList(),
6702 scoped_ptr<syncer::SyncChangeProcessor>(
6703 new syncer::FakeSyncChangeProcessor),
6704 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6706 sync_pb::EntitySpecifics specifics;
6707 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6708 ext_specifics->set_id(good_crx);
6709 ext_specifics->set_enabled(false);
6710 ext_specifics->set_incognito_enabled(true);
6711 ext_specifics->set_update_url("http://www.google.com/");
6712 ext_specifics->set_version("1.2.3.4");
6713 syncer::SyncData sync_data =
6714 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6715 syncer::SyncChange sync_change(FROM_HERE,
6716 syncer::SyncChange::ACTION_UPDATE,
6717 sync_data);
6718 syncer::SyncChangeList list(1);
6719 list[0] = sync_change;
6721 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6722 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6723 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6724 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6725 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6726 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6728 const extensions::PendingExtensionInfo* info;
6729 EXPECT_TRUE(
6730 (info = service()->pending_extension_manager()->GetById(good_crx)));
6731 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
6732 EXPECT_TRUE(info->is_from_sync());
6733 EXPECT_EQ(Manifest::INTERNAL, info->install_source());
6734 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
6737 TEST_F(ExtensionServiceTest, ProcessSyncDataEnableDisable) {
6738 InitializeEmptyExtensionService();
6739 extension_sync_service()->MergeDataAndStartSyncing(
6740 syncer::EXTENSIONS,
6741 syncer::SyncDataList(),
6742 scoped_ptr<syncer::SyncChangeProcessor>(
6743 new syncer::FakeSyncChangeProcessor),
6744 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6746 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6748 struct TestCase {
6749 const char* name; // For failure output only.
6750 // Set of disable reasons before any Sync data comes in. If this is != 0,
6751 // the extension is disabled.
6752 int previous_disable_reasons;
6753 bool sync_enable; // The enabled flag coming in from Sync.
6754 // The disable reason(s) coming in from Sync, or -1 for "not set".
6755 int sync_disable_reasons;
6756 // The expected set of disable reasons after processing the Sync update. The
6757 // extension should be disabled iff this is != 0.
6758 int expect_disable_reasons;
6759 } test_cases[] = {
6760 { "NopEnable", 0, true, 0, 0 },
6761 { "NopDisable", Extension::DISABLE_USER_ACTION, false,
6762 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6763 { "Disable", 0, false, Extension::DISABLE_USER_ACTION,
6764 Extension::DISABLE_USER_ACTION },
6765 { "DisableLegacy", 0, false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC },
6766 { "AddDisableReason", Extension::DISABLE_REMOTE_INSTALL, false,
6767 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION,
6768 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION },
6769 { "AddDisableReasonLegacy", Extension::DISABLE_USER_ACTION, false, -1,
6770 Extension::DISABLE_USER_ACTION | Extension::DISABLE_UNKNOWN_FROM_SYNC},
6771 { "RemoveDisableReason",
6772 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION, false,
6773 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6774 { "Enable", Extension::DISABLE_USER_ACTION, true, 0, 0 },
6775 { "EnableLegacy", Extension::DISABLE_USER_ACTION, true, -1, 0 },
6778 for (const TestCase& test_case : test_cases) {
6779 SCOPED_TRACE(test_case.name);
6781 std::string id;
6782 std::string version;
6783 // Don't keep |extension| around longer than necessary.
6785 const Extension* extension =
6786 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6787 // The extension should now be installed and enabled.
6788 ASSERT_TRUE(extension);
6789 id = extension->id();
6790 version = extension->VersionString();
6792 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6794 // Disable it if the test case says so.
6795 if (test_case.previous_disable_reasons) {
6796 service()->DisableExtension(id, test_case.previous_disable_reasons);
6797 ASSERT_TRUE(registry()->disabled_extensions().Contains(id));
6800 // Now a sync update comes in.
6801 sync_pb::EntitySpecifics specifics;
6802 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6803 ext_specifics->set_id(id);
6804 ext_specifics->set_enabled(test_case.sync_enable);
6805 ext_specifics->set_version(version);
6806 if (test_case.sync_disable_reasons != -1)
6807 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6809 syncer::SyncData sync_data =
6810 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6811 syncer::SyncChange sync_change(FROM_HERE,
6812 syncer::SyncChange::ACTION_UPDATE,
6813 sync_data);
6814 syncer::SyncChangeList list(1, sync_change);
6815 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6817 // Check expectations.
6818 const bool expect_enabled = !test_case.expect_disable_reasons;
6819 EXPECT_EQ(expect_enabled, service()->IsExtensionEnabled(id));
6820 EXPECT_EQ(test_case.expect_disable_reasons, prefs->GetDisableReasons(id));
6822 // Remove the extension again, so we can install it again for the next case.
6823 UninstallExtension(id, false, expect_enabled ? Extension::ENABLED
6824 : Extension::DISABLED);
6828 TEST_F(ExtensionServiceTest, ProcessSyncDataPermissionApproval) {
6829 // This is the update URL specified in the test extension. Setting it here is
6830 // necessary to make it considered syncable.
6831 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6832 switches::kAppsGalleryUpdateURL,
6833 "http://localhost/autoupdate/updates.xml");
6835 InitializeEmptyExtensionService();
6836 extension_sync_service()->MergeDataAndStartSyncing(
6837 syncer::EXTENSIONS,
6838 syncer::SyncDataList(),
6839 scoped_ptr<syncer::SyncChangeProcessor>(
6840 new syncer::FakeSyncChangeProcessor),
6841 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6843 const base::FilePath base_path =
6844 data_dir().AppendASCII("permissions_increase");
6845 const base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
6846 const base::FilePath path_v1 = base_path.AppendASCII("v1");
6847 const base::FilePath path_v2 = base_path.AppendASCII("v2");
6849 base::ScopedTempDir crx_dir;
6850 ASSERT_TRUE(crx_dir.CreateUniqueTempDir());
6851 const base::FilePath crx_path_v1 = crx_dir.path().AppendASCII("temp1.crx");
6852 PackCRX(path_v1, pem_path, crx_path_v1);
6853 const base::FilePath crx_path_v2 = crx_dir.path().AppendASCII("temp2.crx");
6854 PackCRX(path_v2, pem_path, crx_path_v2);
6856 const std::string v1("1");
6857 const std::string v2("2");
6859 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6861 struct TestCase {
6862 const char* name; // For failure output only.
6863 const std::string& sync_version; // The version coming in from Sync.
6864 // The disable reason(s) coming in from Sync, or -1 for "not set".
6865 int sync_disable_reasons;
6866 // Whether the extension's permissions should be auto-granted.
6867 bool expect_permissions_granted;
6868 } test_cases[] = {
6869 // Sync tells us to re-enable an older version. No permissions should be
6870 // granted, since we can't be sure if the user actually approved the right
6871 // set of permissions. Note that the extension will get disabled again the
6872 // next time ExtensionService::CheckPermissionsIncrease runs because of the
6873 // extra permissions.
6874 { "OldVersion", v1, 0, false },
6875 // Legacy case: Sync tells us to re-enable the extension, but doesn't
6876 // specify disable reasons. No permissions should be granted.
6877 { "Legacy", v2, -1, false },
6878 // Sync tells us to re-enable the extension and explicitly removes the
6879 // disable reasons. Now the extension should have its permissions granted.
6880 { "GrantPermissions", v2, 0, true },
6883 for (const TestCase& test_case : test_cases) {
6884 SCOPED_TRACE(test_case.name);
6886 std::string id;
6887 // Don't keep |extension| around longer than necessary (it'll be destroyed
6888 // during updating).
6890 const Extension* extension = InstallCRX(crx_path_v1, INSTALL_NEW);
6891 // The extension should now be installed and enabled.
6892 ASSERT_TRUE(extension);
6893 ASSERT_EQ(v1, extension->VersionString());
6894 id = extension->id();
6896 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6898 scoped_refptr<PermissionSet> granted_permissions_v1(
6899 prefs->GetGrantedPermissions(id));
6901 // Update to a new version with increased permissions.
6902 UpdateExtension(id, crx_path_v2, DISABLED);
6904 // Now the extension should be disabled due to a permissions increase.
6906 const Extension* extension =
6907 registry()->disabled_extensions().GetByID(id);
6908 ASSERT_TRUE(extension);
6909 ASSERT_EQ(v2, extension->VersionString());
6911 ASSERT_TRUE(prefs->HasDisableReason(
6912 id, Extension::DISABLE_PERMISSIONS_INCREASE));
6914 // No new permissions should have been granted.
6915 scoped_refptr<PermissionSet> granted_permissions_v2(
6916 prefs->GetGrantedPermissions(id));
6917 ASSERT_EQ(*granted_permissions_v1, *granted_permissions_v2);
6919 // Now a sync update comes in.
6920 sync_pb::EntitySpecifics specifics;
6921 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6922 ext_specifics->set_id(id);
6923 ext_specifics->set_enabled(true);
6924 ext_specifics->set_version(test_case.sync_version);
6925 if (test_case.sync_disable_reasons != -1)
6926 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6928 syncer::SyncData sync_data =
6929 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6930 syncer::SyncChange sync_change(FROM_HERE,
6931 syncer::SyncChange::ACTION_UPDATE,
6932 sync_data);
6933 syncer::SyncChangeList list(1, sync_change);
6934 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6936 // Check expectations.
6937 EXPECT_TRUE(registry()->GetExtensionById(id, ExtensionRegistry::ENABLED));
6938 scoped_refptr<PermissionSet> granted_permissions(
6939 prefs->GetGrantedPermissions(id));
6940 if (test_case.expect_permissions_granted) {
6941 scoped_refptr<PermissionSet> active_permissions(
6942 prefs->GetActivePermissions(id));
6943 EXPECT_EQ(*granted_permissions, *active_permissions);
6944 } else {
6945 EXPECT_EQ(*granted_permissions, *granted_permissions_v1);
6947 EXPECT_EQ(Extension::DISABLE_NONE, prefs->GetDisableReasons(id));
6949 // Remove the extension again, so we can install it again for the next case.
6950 UninstallExtension(id, false);
6954 #if defined(ENABLE_SUPERVISED_USERS)
6955 class ScopedSupervisedUserServiceDelegate
6956 : public SupervisedUserService::Delegate {
6957 public:
6958 explicit ScopedSupervisedUserServiceDelegate(SupervisedUserService* service)
6959 : service_(service) {
6960 service_->SetDelegate(this);
6962 ~ScopedSupervisedUserServiceDelegate() override {
6963 service_->SetDelegate(nullptr);
6966 // This prevents the legacy supervised user init code from running.
6967 bool SetActive(bool active) override { return true; }
6969 private:
6970 SupervisedUserService* service_;
6973 class MockPermissionRequestCreator : public PermissionRequestCreator {
6974 public:
6975 MockPermissionRequestCreator() {}
6976 ~MockPermissionRequestCreator() override {}
6978 bool IsEnabled() const override { return true; }
6980 void CreateURLAccessRequest(const GURL& url_requested,
6981 const SuccessCallback& callback) override {
6982 FAIL();
6985 MOCK_METHOD2(CreateExtensionUpdateRequest,
6986 void(const std::string& id,
6987 const SupervisedUserService::SuccessCallback& callback));
6989 private:
6990 DISALLOW_COPY_AND_ASSIGN(MockPermissionRequestCreator);
6993 TEST_F(ExtensionServiceTest, SupervisedUser_InstallOnlyAllowedByCustodian) {
6994 ExtensionServiceInitParams params = CreateDefaultInitParams();
6995 params.profile_is_supervised = true;
6996 InitializeExtensionService(params);
6998 SupervisedUserService* supervised_user_service =
6999 SupervisedUserServiceFactory::GetForProfile(profile());
7000 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7001 supervised_user_service->Init();
7003 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7004 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7005 const Extension* extensions[] = {
7006 InstallCRX(path1, INSTALL_FAILED),
7007 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7010 // Only the extension with the "installed by custodian" flag should have been
7011 // installed and enabled.
7012 EXPECT_FALSE(extensions[0]);
7013 ASSERT_TRUE(extensions[1]);
7014 EXPECT_TRUE(registry()->enabled_extensions().Contains(extensions[1]->id()));
7017 TEST_F(ExtensionServiceTest, SupervisedUser_PreinstalledExtension) {
7018 ExtensionServiceInitParams params = CreateDefaultInitParams();
7019 // Do *not* set the profile to supervised here!
7020 InitializeExtensionService(params);
7022 SupervisedUserService* supervised_user_service =
7023 SupervisedUserServiceFactory::GetForProfile(profile());
7024 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7025 supervised_user_service->Init();
7027 // Install an extension.
7028 base::FilePath path = data_dir().AppendASCII("good.crx");
7029 const Extension* extension = InstallCRX(path, INSTALL_NEW);
7030 std::string id = extension->id();
7032 // Now make the profile supervised.
7033 profile()->AsTestingProfile()->SetSupervisedUserId(
7034 supervised_users::kChildAccountSUID);
7036 // The extension should not be enabled anymore.
7037 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7040 TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithoutPermissionIncrease) {
7041 ExtensionServiceInitParams params = CreateDefaultInitParams();
7042 params.profile_is_supervised = true;
7043 InitializeExtensionService(params);
7045 SupervisedUserService* supervised_user_service =
7046 SupervisedUserServiceFactory::GetForProfile(profile());
7047 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7048 supervised_user_service->Init();
7050 base::FilePath base_path = data_dir().AppendASCII("autoupdate");
7051 base::FilePath pem_path = base_path.AppendASCII("key.pem");
7053 base::FilePath path = base_path.AppendASCII("v1");
7054 const Extension* extension =
7055 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
7056 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7057 // The extension must now be installed and enabled.
7058 ASSERT_TRUE(extension);
7059 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7061 // Save the id, as the extension object will be destroyed during updating.
7062 std::string id = extension->id();
7064 std::string old_version = extension->VersionString();
7066 // Update to a new version.
7067 path = base_path.AppendASCII("v2");
7068 PackCRXAndUpdateExtension(id, path, pem_path, ENABLED);
7070 // The extension should still be there and enabled.
7071 extension = registry()->enabled_extensions().GetByID(id);
7072 ASSERT_TRUE(extension);
7073 // The version should have changed.
7074 EXPECT_NE(extension->VersionString(), old_version);
7077 TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithPermissionIncrease) {
7078 ExtensionServiceInitParams params = CreateDefaultInitParams();
7079 params.profile_is_supervised = true;
7080 InitializeExtensionService(params);
7082 SupervisedUserService* supervised_user_service =
7083 SupervisedUserServiceFactory::GetForProfile(profile());
7084 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7085 supervised_user_service->Init();
7086 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
7087 supervised_user_service->AddPermissionRequestCreator(
7088 make_scoped_ptr(creator));
7090 base::FilePath base_path = data_dir().AppendASCII("permissions_increase");
7091 base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
7093 base::FilePath path = base_path.AppendASCII("v1");
7094 const Extension* extension =
7095 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
7096 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7097 // The extension must now be installed and enabled.
7098 ASSERT_TRUE(extension);
7099 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7101 // Save the id, as the extension object will be destroyed during updating.
7102 std::string id = extension->id();
7104 std::string old_version = extension->VersionString();
7106 // Update to a new version with increased permissions.
7107 EXPECT_CALL(*creator,
7108 CreateExtensionUpdateRequest(id + ":2", testing::_));
7109 path = base_path.AppendASCII("v2");
7110 PackCRXAndUpdateExtension(id, path, pem_path, DISABLED);
7112 // The extension should still be there, but disabled.
7113 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7114 extension = registry()->disabled_extensions().GetByID(id);
7115 ASSERT_TRUE(extension);
7116 // The version should have changed.
7117 EXPECT_NE(extension->VersionString(), old_version);
7120 TEST_F(ExtensionServiceTest,
7121 SupervisedUser_SyncUninstallByCustodianSkipsPolicy) {
7122 InitializeEmptyExtensionService();
7123 extension_sync_service()->MergeDataAndStartSyncing(
7124 syncer::EXTENSIONS,
7125 syncer::SyncDataList(),
7126 scoped_ptr<syncer::SyncChangeProcessor>(
7127 new syncer::FakeSyncChangeProcessor),
7128 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
7130 // Install two extensions.
7131 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7132 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7133 const Extension* extensions[] = {
7134 InstallCRX(path1, INSTALL_NEW),
7135 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7138 // Add a policy provider that will disallow any changes.
7139 extensions::TestManagementPolicyProvider provider(
7140 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
7141 GetManagementPolicy()->RegisterProvider(&provider);
7143 // Create a sync deletion for each extension.
7144 syncer::SyncChangeList change_list;
7145 for (size_t i = 0; i < arraysize(extensions); i++) {
7146 const std::string& id = extensions[i]->id();
7147 sync_pb::EntitySpecifics specifics;
7148 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
7149 ext_specifics->set_id(id);
7150 ext_specifics->set_version("1.0");
7151 ext_specifics->set_installed_by_custodian(
7152 extensions[i]->was_installed_by_custodian());
7153 syncer::SyncData sync_data =
7154 syncer::SyncData::CreateLocalData(id, "Name", specifics);
7155 change_list.push_back(syncer::SyncChange(FROM_HERE,
7156 syncer::SyncChange::ACTION_DELETE,
7157 sync_data));
7160 // Save the extension ids, as uninstalling destroys the Extension instance.
7161 std::string extension_ids[] = {
7162 extensions[0]->id(),
7163 extensions[1]->id()
7166 // Now apply the uninstallations.
7167 extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
7169 // Uninstalling the extension without installed_by_custodian should have been
7170 // blocked by policy, so it should still be there.
7171 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_ids[0]));
7173 // But installed_by_custodian should result in bypassing the policy check.
7174 EXPECT_FALSE(
7175 registry()->GenerateInstalledExtensionsSet()->Contains(extension_ids[1]));
7177 #endif // defined(ENABLE_SUPERVISED_USERS)
7179 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
7180 InitializeEmptyExtensionService();
7182 base::FilePath path = data_dir().AppendASCII("good.crx");
7183 InstallCRX(path, INSTALL_NEW);
7184 ValidatePrefKeyCount(1u);
7185 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7186 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7188 extensions::PendingExtensionManager* pending =
7189 service()->pending_extension_manager();
7190 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7192 // Skip install when the location is the same.
7193 EXPECT_FALSE(
7194 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
7195 std::string(),
7196 GURL(kGoodUpdateURL),
7197 Manifest::INTERNAL,
7198 Extension::NO_FLAGS,
7199 false));
7200 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7202 // Install when the location has higher priority.
7203 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
7204 kGoodId,
7205 std::string(),
7206 GURL(kGoodUpdateURL),
7207 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7208 Extension::NO_FLAGS,
7209 false));
7210 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7212 // Try the low priority again. Should be rejected.
7213 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(
7214 kGoodId,
7215 std::string(),
7216 GURL(kGoodUpdateURL),
7217 Manifest::EXTERNAL_PREF_DOWNLOAD,
7218 Extension::NO_FLAGS,
7219 false));
7220 // The existing record should still be present in the pending extension
7221 // manager.
7222 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7224 pending->Remove(kGoodId);
7226 // Skip install when the location has the same priority as the installed
7227 // location.
7228 EXPECT_FALSE(
7229 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
7230 std::string(),
7231 GURL(kGoodUpdateURL),
7232 Manifest::INTERNAL,
7233 Extension::NO_FLAGS,
7234 false));
7236 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7239 TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
7240 Version older_version("0.1.0.0");
7241 Version newer_version("2.0.0.0");
7243 // We don't want the extension to be installed. A path that doesn't
7244 // point to a valid CRX ensures this.
7245 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
7247 const int kCreationFlags = 0;
7248 const bool kDontMarkAcknowledged = false;
7249 const bool kDontInstallImmediately = false;
7251 InitializeEmptyExtensionService();
7253 // The test below uses install source constants to test that
7254 // priority is enforced. It assumes a specific ranking of install
7255 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
7256 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
7257 // The following assertions verify these assumptions:
7258 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
7259 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
7260 Manifest::EXTERNAL_PREF));
7261 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
7262 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
7263 Manifest::INTERNAL));
7264 ASSERT_EQ(Manifest::EXTERNAL_PREF,
7265 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
7266 Manifest::INTERNAL));
7268 extensions::PendingExtensionManager* pending =
7269 service()->pending_extension_manager();
7270 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7273 // Simulate an external source adding the extension as INTERNAL.
7274 content::WindowedNotificationObserver observer(
7275 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7276 content::NotificationService::AllSources());
7277 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7278 kGoodId,
7279 &older_version,
7280 kInvalidPathToCrx,
7281 Manifest::INTERNAL,
7282 kCreationFlags,
7283 kDontMarkAcknowledged,
7284 kDontInstallImmediately));
7285 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7286 observer.Wait();
7287 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7291 // Simulate an external source adding the extension as EXTERNAL_PREF.
7292 content::WindowedNotificationObserver observer(
7293 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7294 content::NotificationService::AllSources());
7295 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7296 kGoodId,
7297 &older_version,
7298 kInvalidPathToCrx,
7299 Manifest::EXTERNAL_PREF,
7300 kCreationFlags,
7301 kDontMarkAcknowledged,
7302 kDontInstallImmediately));
7303 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7304 observer.Wait();
7305 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7308 // Simulate an external source adding as EXTERNAL_PREF again.
7309 // This is rejected because the version and the location are the same as
7310 // the previous installation, which is still pending.
7311 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7312 kGoodId,
7313 &older_version,
7314 kInvalidPathToCrx,
7315 Manifest::EXTERNAL_PREF,
7316 kCreationFlags,
7317 kDontMarkAcknowledged,
7318 kDontInstallImmediately));
7319 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7321 // Try INTERNAL again. Should fail.
7322 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7323 kGoodId,
7324 &older_version,
7325 kInvalidPathToCrx,
7326 Manifest::INTERNAL,
7327 kCreationFlags,
7328 kDontMarkAcknowledged,
7329 kDontInstallImmediately));
7330 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7333 // Now the registry adds the extension.
7334 content::WindowedNotificationObserver observer(
7335 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7336 content::NotificationService::AllSources());
7337 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7338 kGoodId,
7339 &older_version,
7340 kInvalidPathToCrx,
7341 Manifest::EXTERNAL_REGISTRY,
7342 kCreationFlags,
7343 kDontMarkAcknowledged,
7344 kDontInstallImmediately));
7345 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7346 observer.Wait();
7347 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7350 // Registry outranks both external pref and internal, so both fail.
7351 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7352 kGoodId,
7353 &older_version,
7354 kInvalidPathToCrx,
7355 Manifest::EXTERNAL_PREF,
7356 kCreationFlags,
7357 kDontMarkAcknowledged,
7358 kDontInstallImmediately));
7359 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7361 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7362 kGoodId,
7363 &older_version,
7364 kInvalidPathToCrx,
7365 Manifest::INTERNAL,
7366 kCreationFlags,
7367 kDontMarkAcknowledged,
7368 kDontInstallImmediately));
7369 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7371 pending->Remove(kGoodId);
7373 // Install the extension.
7374 base::FilePath path = data_dir().AppendASCII("good.crx");
7375 const Extension* ext = InstallCRX(path, INSTALL_NEW);
7376 ValidatePrefKeyCount(1u);
7377 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7378 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7380 // Now test the logic of OnExternalExtensionFileFound() when the extension
7381 // being added is already installed.
7383 // Tests assume |older_version| is less than the installed version, and
7384 // |newer_version| is greater. Verify this:
7385 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
7386 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
7388 // An external install for the same location should fail if the version is
7389 // older, or the same, and succeed if the version is newer.
7391 // Older than the installed version...
7392 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7393 kGoodId,
7394 &older_version,
7395 kInvalidPathToCrx,
7396 Manifest::INTERNAL,
7397 kCreationFlags,
7398 kDontMarkAcknowledged,
7399 kDontInstallImmediately));
7400 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7402 // Same version as the installed version...
7403 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7404 kGoodId,
7405 ext->version(),
7406 kInvalidPathToCrx,
7407 Manifest::INTERNAL,
7408 kCreationFlags,
7409 kDontMarkAcknowledged,
7410 kDontInstallImmediately));
7411 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7413 // Newer than the installed version...
7414 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7415 kGoodId,
7416 &newer_version,
7417 kInvalidPathToCrx,
7418 Manifest::INTERNAL,
7419 kCreationFlags,
7420 kDontMarkAcknowledged,
7421 kDontInstallImmediately));
7422 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7424 // An external install for a higher priority install source should succeed
7425 // if the version is greater. |older_version| is not...
7426 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7427 kGoodId,
7428 &older_version,
7429 kInvalidPathToCrx,
7430 Manifest::EXTERNAL_PREF,
7431 kCreationFlags,
7432 kDontMarkAcknowledged,
7433 kDontInstallImmediately));
7434 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7436 // |newer_version| is newer.
7437 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7438 kGoodId,
7439 &newer_version,
7440 kInvalidPathToCrx,
7441 Manifest::EXTERNAL_PREF,
7442 kCreationFlags,
7443 kDontMarkAcknowledged,
7444 kDontInstallImmediately));
7445 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7447 // An external install for an even higher priority install source should
7448 // succeed if the version is greater.
7449 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7450 kGoodId,
7451 &newer_version,
7452 kInvalidPathToCrx,
7453 Manifest::EXTERNAL_REGISTRY,
7454 kCreationFlags,
7455 kDontMarkAcknowledged,
7456 kDontInstallImmediately));
7457 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7459 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
7460 // adding from external pref will now fail.
7461 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7462 kGoodId,
7463 &newer_version,
7464 kInvalidPathToCrx,
7465 Manifest::EXTERNAL_PREF,
7466 kCreationFlags,
7467 kDontMarkAcknowledged,
7468 kDontInstallImmediately));
7469 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7472 TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
7473 Version kVersion123("1.2.3");
7474 Version kVersion124("1.2.4");
7475 Version kVersion125("1.2.5");
7476 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
7477 const int kCreationFlags = 0;
7478 const bool kDontMarkAcknowledged = false;
7479 const bool kDontInstallImmediately = false;
7481 InitializeEmptyExtensionService();
7483 extensions::PendingExtensionManager* pending =
7484 service()->pending_extension_manager();
7485 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7487 // An external provider starts installing from a local crx.
7488 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7489 kGoodId,
7490 &kVersion123,
7491 kInvalidPathToCrx,
7492 Manifest::EXTERNAL_PREF,
7493 kCreationFlags,
7494 kDontMarkAcknowledged,
7495 kDontInstallImmediately));
7496 const extensions::PendingExtensionInfo* info;
7497 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7498 EXPECT_TRUE(info->version().IsValid());
7499 EXPECT_TRUE(info->version().Equals(kVersion123));
7501 // Adding a newer version overrides the currently pending version.
7502 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7503 kGoodId,
7504 &kVersion124,
7505 kInvalidPathToCrx,
7506 Manifest::EXTERNAL_PREF,
7507 kCreationFlags,
7508 kDontMarkAcknowledged,
7509 kDontInstallImmediately));
7510 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7511 EXPECT_TRUE(info->version().IsValid());
7512 EXPECT_TRUE(info->version().Equals(kVersion124));
7514 // Adding an older version fails.
7515 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7516 kGoodId,
7517 &kVersion123,
7518 kInvalidPathToCrx,
7519 Manifest::EXTERNAL_PREF,
7520 kCreationFlags,
7521 kDontMarkAcknowledged,
7522 kDontInstallImmediately));
7523 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7524 EXPECT_TRUE(info->version().IsValid());
7525 EXPECT_TRUE(info->version().Equals(kVersion124));
7527 // Adding an older version fails even when coming from a higher-priority
7528 // location.
7529 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7530 kGoodId,
7531 &kVersion123,
7532 kInvalidPathToCrx,
7533 Manifest::EXTERNAL_REGISTRY,
7534 kCreationFlags,
7535 kDontMarkAcknowledged,
7536 kDontInstallImmediately));
7537 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7538 EXPECT_TRUE(info->version().IsValid());
7539 EXPECT_TRUE(info->version().Equals(kVersion124));
7541 // Adding the latest version from the webstore overrides a specific version.
7542 GURL kUpdateUrl("http://example.com/update");
7543 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
7544 kGoodId,
7545 std::string(),
7546 kUpdateUrl,
7547 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7548 Extension::NO_FLAGS,
7549 false));
7550 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7551 EXPECT_FALSE(info->version().IsValid());
7554 // This makes sure we can package and install CRX files that use whitelisted
7555 // permissions.
7556 TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
7557 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
7558 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
7559 extensions::switches::kWhitelistedExtensionID, test_id);
7561 InitializeEmptyExtensionService();
7562 base::FilePath path = data_dir().AppendASCII("permissions");
7563 base::FilePath pem_path = path
7564 .AppendASCII("whitelist.pem");
7565 path = path
7566 .AppendASCII("whitelist");
7568 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
7569 EXPECT_EQ(0u, GetErrors().size());
7570 ASSERT_EQ(1u, registry()->enabled_extensions().size());
7571 EXPECT_EQ(test_id, extension->id());
7574 // Test that when multiple sources try to install an extension,
7575 // we consistently choose the right one. To make tests easy to read,
7576 // methods that fake requests to install crx files in several ways
7577 // are provided.
7578 class ExtensionSourcePriorityTest : public ExtensionServiceTest {
7579 public:
7580 void SetUp() override {
7581 ExtensionServiceTest::SetUp();
7583 // All tests use a single extension. Put the id and path in member vars
7584 // that all methods can read.
7585 crx_id_ = kGoodId;
7586 crx_path_ = data_dir().AppendASCII("good.crx");
7589 // Fake an external source adding a URL to fetch an extension from.
7590 bool AddPendingExternalPrefUrl() {
7591 return service()->pending_extension_manager()->AddFromExternalUpdateUrl(
7592 crx_id_,
7593 std::string(),
7594 GURL(),
7595 Manifest::EXTERNAL_PREF_DOWNLOAD,
7596 Extension::NO_FLAGS,
7597 false);
7600 // Fake an external file from external_extensions.json.
7601 bool AddPendingExternalPrefFileInstall() {
7602 Version version("1.0.0.0");
7604 return service()->OnExternalExtensionFileFound(crx_id_,
7605 &version,
7606 crx_path_,
7607 Manifest::EXTERNAL_PREF,
7608 Extension::NO_FLAGS,
7609 false,
7610 false);
7613 // Fake a request from sync to install an extension.
7614 bool AddPendingSyncInstall() {
7615 return service()->pending_extension_manager()->AddFromSync(
7616 crx_id_,
7617 GURL(kGoodUpdateURL),
7618 &IsExtension,
7619 kGoodRemoteInstall,
7620 kGoodInstalledByCustodian);
7623 // Fake a policy install.
7624 bool AddPendingPolicyInstall() {
7625 // Get path to the CRX with id |kGoodId|.
7626 return service()->OnExternalExtensionUpdateUrlFound(
7627 crx_id_,
7628 std::string(),
7629 GURL(),
7630 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7631 Extension::NO_FLAGS,
7632 false);
7635 // Get the install source of a pending extension.
7636 Manifest::Location GetPendingLocation() {
7637 const extensions::PendingExtensionInfo* info;
7638 EXPECT_TRUE(
7639 (info = service()->pending_extension_manager()->GetById(crx_id_)));
7640 return info->install_source();
7643 // Is an extension pending from a sync request?
7644 bool GetPendingIsFromSync() {
7645 const extensions::PendingExtensionInfo* info;
7646 EXPECT_TRUE(
7647 (info = service()->pending_extension_manager()->GetById(crx_id_)));
7648 return info->is_from_sync();
7651 // Is the CRX id these tests use pending?
7652 bool IsCrxPending() {
7653 return service()->pending_extension_manager()->IsIdPending(crx_id_);
7656 // Is an extension installed?
7657 bool IsCrxInstalled() {
7658 return (service()->GetExtensionById(crx_id_, true) != NULL);
7661 protected:
7662 // All tests use a single extension. Making the id and path member
7663 // vars avoids pasing the same argument to every method.
7664 std::string crx_id_;
7665 base::FilePath crx_path_;
7668 // Test that a pending request for installation of an external CRX from
7669 // an update URL overrides a pending request to install the same extension
7670 // from sync.
7671 TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
7672 InitializeEmptyExtensionService();
7674 ASSERT_FALSE(IsCrxInstalled());
7676 // Install pending extension from sync.
7677 content::WindowedNotificationObserver observer(
7678 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7679 content::NotificationService::AllSources());
7680 EXPECT_TRUE(AddPendingSyncInstall());
7681 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
7682 EXPECT_TRUE(GetPendingIsFromSync());
7683 ASSERT_FALSE(IsCrxInstalled());
7685 // Install pending as external prefs json would.
7686 AddPendingExternalPrefFileInstall();
7687 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
7688 ASSERT_FALSE(IsCrxInstalled());
7690 // Another request from sync should be ignored.
7691 EXPECT_FALSE(AddPendingSyncInstall());
7692 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
7693 ASSERT_FALSE(IsCrxInstalled());
7695 observer.Wait();
7696 VerifyCrxInstall(crx_path_, INSTALL_NEW);
7697 ASSERT_TRUE(IsCrxInstalled());
7700 // Test that an install of an external CRX from an update overrides
7701 // an install of the same extension from sync.
7702 TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
7703 InitializeEmptyExtensionService();
7704 ASSERT_FALSE(IsCrxInstalled());
7706 EXPECT_TRUE(AddPendingSyncInstall());
7707 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
7708 EXPECT_TRUE(GetPendingIsFromSync());
7709 ASSERT_FALSE(IsCrxInstalled());
7711 ASSERT_TRUE(AddPendingExternalPrefUrl());
7712 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
7713 EXPECT_FALSE(GetPendingIsFromSync());
7714 ASSERT_FALSE(IsCrxInstalled());
7716 EXPECT_FALSE(AddPendingSyncInstall());
7717 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
7718 EXPECT_FALSE(GetPendingIsFromSync());
7719 ASSERT_FALSE(IsCrxInstalled());
7722 // Test that an external install request stops sync from installing
7723 // the same extension.
7724 TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
7725 InitializeEmptyExtensionService();
7726 ASSERT_FALSE(IsCrxInstalled());
7728 // External prefs starts an install.
7729 AddPendingExternalPrefFileInstall();
7731 // Crx installer was made, but has not yet run.
7732 ASSERT_FALSE(IsCrxInstalled());
7734 // Before the CRX installer runs, Sync requests that the same extension
7735 // be installed. Should fail, because an external source is pending.
7736 content::WindowedNotificationObserver observer(
7737 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7738 content::NotificationService::AllSources());
7739 ASSERT_FALSE(AddPendingSyncInstall());
7741 // Wait for the external source to install.
7742 observer.Wait();
7743 VerifyCrxInstall(crx_path_, INSTALL_NEW);
7744 ASSERT_TRUE(IsCrxInstalled());
7746 // Now that the extension is installed, sync request should fail
7747 // because the extension is already installed.
7748 ASSERT_FALSE(AddPendingSyncInstall());
7751 // Test that installing an external extension displays a GlobalError.
7752 TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
7753 FeatureSwitch::ScopedOverride prompt(
7754 FeatureSwitch::prompt_for_external_extensions(), true);
7756 InitializeEmptyExtensionService();
7757 MockExtensionProvider* provider =
7758 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7759 AddMockExternalProvider(provider);
7761 service()->external_install_manager()->UpdateExternalExtensionAlert();
7762 // Should return false, meaning there aren't any extensions that the user
7763 // needs to know about.
7764 EXPECT_FALSE(
7765 service()->external_install_manager()->HasExternalInstallError());
7767 // This is a normal extension, installed normally.
7768 // This should NOT trigger an alert.
7769 service()->set_extensions_enabled(true);
7770 base::FilePath path = data_dir().AppendASCII("good.crx");
7771 InstallCRX(path, INSTALL_NEW);
7773 service()->CheckForExternalUpdates();
7774 base::RunLoop().RunUntilIdle();
7775 EXPECT_FALSE(
7776 service()->external_install_manager()->HasExternalInstallError());
7778 // A hosted app, installed externally.
7779 // This should NOT trigger an alert.
7780 provider->UpdateOrAddExtension(
7781 hosted_app, "1.0.0.0", data_dir().AppendASCII("hosted_app.crx"));
7783 content::WindowedNotificationObserver observer(
7784 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7785 content::NotificationService::AllSources());
7786 service()->CheckForExternalUpdates();
7787 observer.Wait();
7788 EXPECT_FALSE(
7789 service()->external_install_manager()->HasExternalInstallError());
7791 // Another normal extension, but installed externally.
7792 // This SHOULD trigger an alert.
7793 provider->UpdateOrAddExtension(
7794 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7796 content::WindowedNotificationObserver observer2(
7797 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7798 content::NotificationService::AllSources());
7799 service()->CheckForExternalUpdates();
7800 observer2.Wait();
7801 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7804 // Test that external extensions are initially disabled, and that enabling
7805 // them clears the prompt.
7806 TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
7807 FeatureSwitch::ScopedOverride prompt(
7808 FeatureSwitch::prompt_for_external_extensions(), true);
7810 InitializeEmptyExtensionService();
7811 MockExtensionProvider* provider =
7812 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7813 AddMockExternalProvider(provider);
7815 provider->UpdateOrAddExtension(
7816 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7818 content::WindowedNotificationObserver observer(
7819 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7820 content::NotificationService::AllSources());
7821 service()->CheckForExternalUpdates();
7822 observer.Wait();
7823 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7824 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
7826 const Extension* extension =
7827 registry()->disabled_extensions().GetByID(page_action);
7828 EXPECT_TRUE(extension);
7829 EXPECT_EQ(page_action, extension->id());
7831 service()->EnableExtension(page_action);
7832 EXPECT_FALSE(
7833 service()->external_install_manager()->HasExternalInstallError());
7834 EXPECT_TRUE(service()->IsExtensionEnabled(page_action));
7837 // Test that installing multiple external extensions works.
7838 // Flaky on windows; http://crbug.com/295757 .
7839 #if defined(OS_WIN)
7840 #define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
7841 #else
7842 #define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
7843 #endif
7844 TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
7845 FeatureSwitch::ScopedOverride prompt(
7846 FeatureSwitch::prompt_for_external_extensions(), true);
7848 InitializeEmptyExtensionService();
7849 MockExtensionProvider* provider =
7850 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7851 AddMockExternalProvider(provider);
7853 provider->UpdateOrAddExtension(
7854 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7855 provider->UpdateOrAddExtension(
7856 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
7857 provider->UpdateOrAddExtension(
7858 theme_crx, "2.0", data_dir().AppendASCII("theme.crx"));
7860 int count = 3;
7861 content::WindowedNotificationObserver observer(
7862 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7863 base::Bind(&WaitForCountNotificationsCallback, &count));
7864 service()->CheckForExternalUpdates();
7865 observer.Wait();
7866 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7867 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
7868 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
7869 EXPECT_FALSE(service()->IsExtensionEnabled(theme_crx));
7871 service()->EnableExtension(page_action);
7872 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7873 EXPECT_FALSE(service()
7874 ->external_install_manager()
7875 ->HasExternalInstallBubbleForTesting());
7877 service()->EnableExtension(theme_crx);
7878 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7879 EXPECT_FALSE(service()
7880 ->external_install_manager()
7881 ->HasExternalInstallBubbleForTesting());
7883 service()->EnableExtension(good_crx);
7884 EXPECT_FALSE(
7885 service()->external_install_manager()->HasExternalInstallError());
7886 EXPECT_FALSE(service()
7887 ->external_install_manager()
7888 ->HasExternalInstallBubbleForTesting());
7891 // Test that there is a bubble for external extensions that update
7892 // from the webstore if the profile is not new.
7893 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
7894 FeatureSwitch::ScopedOverride prompt(
7895 FeatureSwitch::prompt_for_external_extensions(), true);
7897 // This sets up the ExtensionPrefs used by our ExtensionService to be
7898 // post-first run.
7899 ExtensionServiceInitParams params = CreateDefaultInitParams();
7900 params.is_first_run = false;
7901 InitializeExtensionService(params);
7903 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7904 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7905 data_dir().AppendASCII("update_from_webstore.pem"),
7906 crx_path);
7908 MockExtensionProvider* provider =
7909 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7910 AddMockExternalProvider(provider);
7911 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7913 content::WindowedNotificationObserver observer(
7914 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7915 content::NotificationService::AllSources());
7916 service()->CheckForExternalUpdates();
7917 observer.Wait();
7918 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7919 EXPECT_TRUE(service()
7920 ->external_install_manager()
7921 ->HasExternalInstallBubbleForTesting());
7922 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7925 // Test that there is no bubble for external extensions if the profile is new.
7926 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
7927 FeatureSwitch::ScopedOverride prompt(
7928 FeatureSwitch::prompt_for_external_extensions(), true);
7930 InitializeEmptyExtensionService();
7932 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7933 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7934 data_dir().AppendASCII("update_from_webstore.pem"),
7935 crx_path);
7937 MockExtensionProvider* provider =
7938 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7939 AddMockExternalProvider(provider);
7940 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7942 content::WindowedNotificationObserver observer(
7943 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7944 content::NotificationService::AllSources());
7945 service()->CheckForExternalUpdates();
7946 observer.Wait();
7947 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7948 EXPECT_FALSE(service()
7949 ->external_install_manager()
7950 ->HasExternalInstallBubbleForTesting());
7951 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7954 // Test that clicking to remove the extension on an external install warning
7955 // uninstalls the extension.
7956 TEST_F(ExtensionServiceTest, ExternalInstallClickToRemove) {
7957 FeatureSwitch::ScopedOverride prompt(
7958 FeatureSwitch::prompt_for_external_extensions(), true);
7960 ExtensionServiceInitParams params = CreateDefaultInitParams();
7961 params.is_first_run = false;
7962 InitializeExtensionService(params);
7964 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7965 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7966 data_dir().AppendASCII("update_from_webstore.pem"),
7967 crx_path);
7969 MockExtensionProvider* provider =
7970 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
7971 AddMockExternalProvider(provider);
7972 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7974 content::WindowedNotificationObserver observer(
7975 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7976 content::NotificationService::AllSources());
7977 service_->CheckForExternalUpdates();
7978 observer.Wait();
7979 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
7981 // We check both enabled and disabled, since these are "eventually exclusive"
7982 // sets.
7983 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
7984 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7986 // Click the negative response.
7987 service_->external_install_manager()->error_for_testing()->InstallUIAbort(
7988 true);
7989 // The Extension should be uninstalled.
7990 EXPECT_FALSE(registry()->GetExtensionById(updates_from_webstore,
7991 ExtensionRegistry::EVERYTHING));
7992 // The error should be removed.
7993 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
7996 // Test that clicking to keep the extension on an external install warning
7997 // re-enables the extension.
7998 TEST_F(ExtensionServiceTest, ExternalInstallClickToKeep) {
7999 FeatureSwitch::ScopedOverride prompt(
8000 FeatureSwitch::prompt_for_external_extensions(), true);
8002 ExtensionServiceInitParams params = CreateDefaultInitParams();
8003 params.is_first_run = false;
8004 InitializeExtensionService(params);
8006 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
8007 PackCRX(data_dir().AppendASCII("update_from_webstore"),
8008 data_dir().AppendASCII("update_from_webstore.pem"),
8009 crx_path);
8011 MockExtensionProvider* provider =
8012 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
8013 AddMockExternalProvider(provider);
8014 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
8016 content::WindowedNotificationObserver observer(
8017 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
8018 content::NotificationService::AllSources());
8019 service_->CheckForExternalUpdates();
8020 observer.Wait();
8021 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
8023 // We check both enabled and disabled, since these are "eventually exclusive"
8024 // sets.
8025 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
8026 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8028 // Accept the extension.
8029 service_->external_install_manager()->error_for_testing()->InstallUIProceed();
8031 // It should be enabled again.
8032 EXPECT_TRUE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8033 EXPECT_FALSE(
8034 registry()->disabled_extensions().GetByID(updates_from_webstore));
8036 // The error should be removed.
8037 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
8040 TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) {
8041 InitializeEmptyExtensionService();
8043 scoped_refptr<Extension> extension = extensions::ExtensionBuilder()
8044 .SetManifest(extensions::DictionaryBuilder()
8045 .Set("name", "extension")
8046 .Set("version", "1.0")
8047 .Set("manifest_version", 2).Build())
8048 .Build();
8049 ASSERT_TRUE(extension.get());
8050 const std::string& id = extension->id();
8052 std::set<std::string> id_set;
8053 id_set.insert(id);
8054 extensions::ExtensionNotificationObserver notifications(
8055 content::NotificationService::AllSources(), id_set);
8057 // Installation should be allowed but the extension should never have been
8058 // loaded and it should be blacklisted in prefs.
8059 service()->OnExtensionInstalled(
8060 extension.get(),
8061 syncer::StringOrdinal(),
8062 (extensions::kInstallFlagIsBlacklistedForMalware |
8063 extensions::kInstallFlagInstallImmediately));
8064 base::RunLoop().RunUntilIdle();
8066 // Extension was installed but not loaded.
8067 EXPECT_TRUE(notifications.CheckNotifications(
8068 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED));
8069 EXPECT_TRUE(service()->GetInstalledExtension(id));
8071 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
8072 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(id));
8074 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlacklisted(id));
8075 EXPECT_TRUE(
8076 ExtensionPrefs::Get(profile())->IsBlacklistedExtensionAcknowledged(id));
8079 // Tests a profile being destroyed correctly disables extensions.
8080 TEST_F(ExtensionServiceTest, DestroyingProfileClearsExtensions) {
8081 InitializeEmptyExtensionService();
8083 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
8084 EXPECT_NE(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8085 EXPECT_EQ(1u, registry()->enabled_extensions().size());
8086 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8087 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8088 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
8090 service()->Observe(chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
8091 content::Source<Profile>(profile()),
8092 content::NotificationService::NoDetails());
8093 EXPECT_EQ(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8094 EXPECT_EQ(0u, registry()->enabled_extensions().size());
8095 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8096 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8097 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());