Add a webstorePrivate API to show a permission prompt for delegated bundle installs
[chromium-blink-merge.git] / chrome / browser / extensions / extension_service_unittest.cc
blob46d7411ab21cbbf7fe1f1635276d2e3ebf254c00
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/string16.h"
26 #include "base/strings/string_number_conversions.h"
27 #include "base/strings/string_util.h"
28 #include "base/strings/utf_string_conversions.h"
29 #include "base/thread_task_runner_handle.h"
30 #include "base/version.h"
31 #include "chrome/browser/browser_process.h"
32 #include "chrome/browser/chrome_notification_types.h"
33 #include "chrome/browser/extensions/app_sync_data.h"
34 #include "chrome/browser/extensions/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/pref_names.h"
76 #include "chrome/common/url_constants.h"
77 #include "chrome/test/base/scoped_browser_locale.h"
78 #include "chrome/test/base/testing_pref_service_syncable.h"
79 #include "chrome/test/base/testing_profile.h"
80 #include "components/crx_file/id_util.h"
81 #include "components/pref_registry/pref_registry_syncable.h"
82 #include "content/public/browser/dom_storage_context.h"
83 #include "content/public/browser/gpu_data_manager.h"
84 #include "content/public/browser/indexed_db_context.h"
85 #include "content/public/browser/notification_registrar.h"
86 #include "content/public/browser/notification_service.h"
87 #include "content/public/browser/plugin_service.h"
88 #include "content/public/browser/render_process_host.h"
89 #include "content/public/browser/storage_partition.h"
90 #include "content/public/common/content_constants.h"
91 #include "content/public/test/test_browser_thread_bundle.h"
92 #include "content/public/test/test_utils.h"
93 #include "extensions/browser/extension_dialog_auto_confirm.h"
94 #include "extensions/browser/extension_prefs.h"
95 #include "extensions/browser/extension_registry.h"
96 #include "extensions/browser/extension_system.h"
97 #include "extensions/browser/external_provider_interface.h"
98 #include "extensions/browser/install_flag.h"
99 #include "extensions/browser/management_policy.h"
100 #include "extensions/browser/test_management_policy.h"
101 #include "extensions/browser/uninstall_reason.h"
102 #include "extensions/common/constants.h"
103 #include "extensions/common/extension.h"
104 #include "extensions/common/extension_builder.h"
105 #include "extensions/common/extension_l10n_util.h"
106 #include "extensions/common/extension_resource.h"
107 #include "extensions/common/feature_switch.h"
108 #include "extensions/common/manifest_constants.h"
109 #include "extensions/common/manifest_handlers/background_info.h"
110 #include "extensions/common/manifest_handlers/permissions_parser.h"
111 #include "extensions/common/manifest_url_handlers.h"
112 #include "extensions/common/permissions/permission_set.h"
113 #include "extensions/common/permissions/permissions_data.h"
114 #include "extensions/common/switches.h"
115 #include "extensions/common/url_pattern.h"
116 #include "extensions/common/value_builder.h"
117 #include "gpu/config/gpu_info.h"
118 #include "grit/browser_resources.h"
119 #include "grit/generated_resources.h"
120 #include "net/cookies/canonical_cookie.h"
121 #include "net/cookies/cookie_monster.h"
122 #include "net/cookies/cookie_options.h"
123 #include "net/url_request/url_request_context.h"
124 #include "net/url_request/url_request_context_getter.h"
125 #include "storage/browser/database/database_tracker.h"
126 #include "storage/browser/quota/quota_manager.h"
127 #include "storage/common/database/database_identifier.h"
128 #include "sync/api/fake_sync_change_processor.h"
129 #include "sync/api/string_ordinal.h"
130 #include "sync/api/sync_data.h"
131 #include "sync/api/sync_error_factory.h"
132 #include "sync/api/sync_error_factory_mock.h"
133 #include "sync/api/syncable_service.h"
134 #include "sync/protocol/app_specifics.pb.h"
135 #include "sync/protocol/extension_specifics.pb.h"
136 #include "sync/protocol/sync.pb.h"
137 #include "testing/gtest/include/gtest/gtest.h"
138 #include "testing/platform_test.h"
139 #include "ui/base/l10n/l10n_util.h"
140 #include "url/gurl.h"
142 #if defined(ENABLE_SUPERVISED_USERS)
143 #include "chrome/browser/supervised_user/permission_request_creator.h"
144 #include "chrome/browser/supervised_user/supervised_user_constants.h"
145 #include "chrome/browser/supervised_user/supervised_user_service.h"
146 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
147 #endif
149 #if defined(OS_CHROMEOS)
150 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
151 #include "chrome/browser/chromeos/settings/cros_settings.h"
152 #include "chrome/browser/chromeos/settings/device_settings_service.h"
153 #endif
155 // The blacklist tests rely on the safe-browsing database.
156 #if defined(SAFE_BROWSING_DB_LOCAL)
157 #define ENABLE_BLACKLIST_TESTS
158 #endif
160 using base::DictionaryValue;
161 using base::ListValue;
162 using base::Value;
163 using content::BrowserContext;
164 using content::BrowserThread;
165 using content::DOMStorageContext;
166 using content::IndexedDBContext;
167 using content::PluginService;
168 using extensions::APIPermission;
169 using extensions::APIPermissionSet;
170 using extensions::AppSorting;
171 using extensions::AppSyncData;
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 InitializeExtensionSyncService() {
1153 extension_sync_service_.reset(new ExtensionSyncService(
1154 profile(), ExtensionPrefs::Get(browser_context()), service()));
1157 void InitializeEmptyExtensionServiceWithTestingPrefs() {
1158 ExtensionServiceTestBase::ExtensionServiceInitParams params =
1159 CreateDefaultInitParams();
1160 params.pref_file = base::FilePath();
1161 InitializeExtensionService(params);
1164 extensions::ManagementPolicy* GetManagementPolicy() {
1165 return ExtensionSystem::Get(browser_context())->management_policy();
1168 ExtensionSyncService* extension_sync_service() {
1169 return extension_sync_service_.get();
1172 protected:
1173 typedef extensions::ExtensionManagementPrefUpdater<TestingPrefServiceSyncable>
1174 ManagementPrefUpdater;
1175 scoped_ptr<ExtensionSyncService> extension_sync_service_;
1176 extensions::ExtensionList loaded_;
1177 std::string unloaded_id_;
1178 UnloadedExtensionInfo::Reason unloaded_reason_;
1179 const Extension* installed_;
1180 bool was_update_;
1181 std::string old_name_;
1182 FeatureSwitch::ScopedOverride override_external_install_prompt_;
1184 private:
1185 // Create a CrxInstaller and install the CRX file.
1186 // Instead of calling this method yourself, use InstallCRX(), which does extra
1187 // error checking.
1188 void InstallCRXInternal(const base::FilePath& crx_path) {
1189 InstallCRXInternal(crx_path, Extension::NO_FLAGS);
1192 void InstallCRXInternal(const base::FilePath& crx_path, int creation_flags) {
1193 ASSERT_TRUE(base::PathExists(crx_path))
1194 << "Path does not exist: "<< crx_path.value().c_str();
1195 scoped_refptr<CrxInstaller> installer(
1196 CrxInstaller::CreateSilent(service()));
1197 installer->set_creation_flags(creation_flags);
1198 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT))
1199 installer->set_allow_silent_install(true);
1201 content::WindowedNotificationObserver observer(
1202 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1203 content::Source<extensions::CrxInstaller>(installer.get()));
1205 installer->InstallCrx(crx_path);
1207 observer.Wait();
1210 size_t expected_extensions_count_;
1211 content::NotificationRegistrar registrar_;
1214 // Receives notifications from a PackExtensionJob, indicating either that
1215 // packing succeeded or that there was some error.
1216 class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
1217 public:
1218 PackExtensionTestClient(const base::FilePath& expected_crx_path,
1219 const base::FilePath& expected_private_key_path);
1220 void OnPackSuccess(const base::FilePath& crx_path,
1221 const base::FilePath& private_key_path) override;
1222 void OnPackFailure(const std::string& error_message,
1223 ExtensionCreator::ErrorType type) override;
1225 private:
1226 const base::FilePath expected_crx_path_;
1227 const base::FilePath expected_private_key_path_;
1228 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
1231 PackExtensionTestClient::PackExtensionTestClient(
1232 const base::FilePath& expected_crx_path,
1233 const base::FilePath& expected_private_key_path)
1234 : expected_crx_path_(expected_crx_path),
1235 expected_private_key_path_(expected_private_key_path) {}
1237 // If packing succeeded, we make sure that the package names match our
1238 // expectations.
1239 void PackExtensionTestClient::OnPackSuccess(
1240 const base::FilePath& crx_path,
1241 const base::FilePath& private_key_path) {
1242 // We got the notification and processed it; we don't expect any further tasks
1243 // to be posted to the current thread, so we should stop blocking and continue
1244 // on with the rest of the test.
1245 // This call to |Quit()| matches the call to |Run()| in the
1246 // |PackPunctuatedExtension| test.
1247 base::MessageLoop::current()->Quit();
1248 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
1249 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
1250 ASSERT_TRUE(base::PathExists(private_key_path));
1253 // The tests are designed so that we never expect to see a packing error.
1254 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1255 ExtensionCreator::ErrorType type) {
1256 if (type == ExtensionCreator::kCRXExists)
1257 FAIL() << "Packing should not fail.";
1258 else
1259 FAIL() << "Existing CRX should have been overwritten.";
1262 // Test loading good extensions from the profile directory.
1263 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1264 InitPluginService();
1265 InitializeGoodInstalledExtensionService();
1266 service()->Init();
1268 uint32 expected_num_extensions = 3u;
1269 ASSERT_EQ(expected_num_extensions, loaded_.size());
1271 EXPECT_EQ(std::string(good0), loaded_[0]->id());
1272 EXPECT_EQ(std::string("My extension 1"),
1273 loaded_[0]->name());
1274 EXPECT_EQ(std::string("The first extension that I made."),
1275 loaded_[0]->description());
1276 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
1277 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false));
1278 EXPECT_EQ(expected_num_extensions, registry()->enabled_extensions().size());
1280 ValidatePrefKeyCount(3);
1281 ValidateIntegerPref(good0, "state", Extension::ENABLED);
1282 ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
1283 ValidateIntegerPref(good1, "state", Extension::ENABLED);
1284 ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
1285 ValidateIntegerPref(good2, "state", Extension::ENABLED);
1286 ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
1288 URLPatternSet expected_patterns;
1289 AddPattern(&expected_patterns, "file:///*");
1290 AddPattern(&expected_patterns, "http://*.google.com/*");
1291 AddPattern(&expected_patterns, "https://*.google.com/*");
1292 const Extension* extension = loaded_[0].get();
1293 const extensions::UserScriptList& scripts =
1294 extensions::ContentScriptsInfo::GetContentScripts(extension);
1295 ASSERT_EQ(2u, scripts.size());
1296 EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
1297 EXPECT_EQ(2u, scripts[0].js_scripts().size());
1298 ExtensionResource resource00(extension->id(),
1299 scripts[0].js_scripts()[0].extension_root(),
1300 scripts[0].js_scripts()[0].relative_path());
1301 base::FilePath expected_path =
1302 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
1303 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
1304 ExtensionResource resource01(extension->id(),
1305 scripts[0].js_scripts()[1].extension_root(),
1306 scripts[0].js_scripts()[1].relative_path());
1307 expected_path =
1308 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
1309 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
1310 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension));
1311 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
1312 EXPECT_EQ("http://*.news.com/*",
1313 scripts[1].url_patterns().begin()->GetAsString());
1314 ExtensionResource resource10(extension->id(),
1315 scripts[1].js_scripts()[0].extension_root(),
1316 scripts[1].js_scripts()[0].relative_path());
1317 expected_path =
1318 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
1319 expected_path = base::MakeAbsoluteFilePath(expected_path);
1320 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
1322 expected_patterns.ClearPatterns();
1323 AddPattern(&expected_patterns, "http://*.google.com/*");
1324 AddPattern(&expected_patterns, "https://*.google.com/*");
1325 EXPECT_EQ(
1326 expected_patterns,
1327 extension->permissions_data()->active_permissions()->explicit_hosts());
1329 EXPECT_EQ(std::string(good1), loaded_[1]->id());
1330 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
1331 EXPECT_EQ(std::string(), loaded_[1]->description());
1332 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
1333 extensions::BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
1334 EXPECT_EQ(0u,
1335 extensions::ContentScriptsInfo::GetContentScripts(loaded_[1].get())
1336 .size());
1338 // We don't parse the plugins section on Chrome OS.
1339 #if defined(OS_CHROMEOS)
1340 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1341 #else
1342 ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1343 const std::vector<extensions::PluginInfo>* plugins =
1344 extensions::PluginInfo::GetPlugins(loaded_[1].get());
1345 ASSERT_TRUE(plugins);
1346 ASSERT_EQ(2u, plugins->size());
1347 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
1348 plugins->at(0).path.value());
1349 EXPECT_TRUE(plugins->at(0).is_public);
1350 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1351 plugins->at(1).path.value());
1352 EXPECT_FALSE(plugins->at(1).is_public);
1353 #endif
1355 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
1357 int index = expected_num_extensions - 1;
1358 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1359 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1360 EXPECT_EQ(std::string(), loaded_[index]->description());
1361 EXPECT_EQ(0u,
1362 extensions::ContentScriptsInfo::GetContentScripts(
1363 loaded_[index].get()).size());
1364 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
1367 // Test loading bad extensions from the profile directory.
1368 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
1369 // Initialize the test dir with a bad Preferences/extensions.
1370 base::FilePath source_install_dir =
1371 data_dir().AppendASCII("bad").AppendASCII("Extensions");
1372 base::FilePath pref_path =
1373 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1375 InitializeInstalledExtensionService(pref_path, source_install_dir);
1377 service()->Init();
1379 ASSERT_EQ(4u, GetErrors().size());
1380 ASSERT_EQ(0u, loaded_.size());
1382 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[0]),
1383 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1384 extensions::manifest_errors::kManifestUnreadable)) <<
1385 base::UTF16ToUTF8(GetErrors()[0]);
1387 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[1]),
1388 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1389 extensions::manifest_errors::kManifestUnreadable)) <<
1390 base::UTF16ToUTF8(GetErrors()[1]);
1392 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[2]),
1393 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1394 extensions::manifest_errors::kMissingFile)) <<
1395 base::UTF16ToUTF8(GetErrors()[2]);
1397 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[3]),
1398 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1399 extensions::manifest_errors::kManifestUnreadable)) <<
1400 base::UTF16ToUTF8(GetErrors()[3]);
1403 // Test various cases for delayed install because of missing imports.
1404 TEST_F(ExtensionServiceTest, PendingImports) {
1405 InitPluginService();
1407 base::FilePath source_install_dir =
1408 data_dir().AppendASCII("pending_updates_with_imports").AppendASCII(
1409 "Extensions");
1410 base::FilePath pref_path =
1411 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1413 InitializeInstalledExtensionService(pref_path, source_install_dir);
1415 // Verify there are no pending extensions initially.
1416 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions());
1418 service()->Init();
1419 // Wait for GarbageCollectExtensions task to complete.
1420 base::RunLoop().RunUntilIdle();
1422 // These extensions are used by the extensions we test below, they must be
1423 // installed.
1424 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1425 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1426 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1427 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1429 // Each of these extensions should have been rejected because of dependencies
1430 // that cannot be satisfied.
1431 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1432 EXPECT_FALSE(
1433 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1434 EXPECT_FALSE(
1435 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1436 EXPECT_FALSE(
1437 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1438 EXPECT_FALSE(
1439 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1440 EXPECT_FALSE(
1441 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
1442 EXPECT_FALSE(
1443 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
1445 // Make sure the import started for the extension with a dependency.
1446 EXPECT_TRUE(
1447 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1448 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1449 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1451 EXPECT_FALSE(base::PathExists(extensions_install_dir().AppendASCII(
1452 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
1454 EXPECT_TRUE(service()->pending_extension_manager()->HasPendingExtensions());
1455 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
1456 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
1457 // Remove it because we are not testing the pending extension manager's
1458 // ability to download and install extensions.
1459 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id));
1462 // Test installing extensions. This test tries to install few extensions using
1463 // crx files. If you need to change those crx files, feel free to repackage
1464 // them, throw away the key used and change the id's above.
1465 TEST_F(ExtensionServiceTest, InstallExtension) {
1466 InitializeEmptyExtensionService();
1468 // Extensions not enabled.
1469 service()->set_extensions_enabled(false);
1470 base::FilePath path = data_dir().AppendASCII("good.crx");
1471 InstallCRX(path, INSTALL_FAILED);
1472 service()->set_extensions_enabled(true);
1474 ValidatePrefKeyCount(0);
1476 // A simple extension that should install without error.
1477 path = data_dir().AppendASCII("good.crx");
1478 InstallCRX(path, INSTALL_NEW);
1479 // TODO(erikkay): verify the contents of the installed extension.
1481 int pref_count = 0;
1482 ValidatePrefKeyCount(++pref_count);
1483 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1484 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
1486 // An extension with page actions.
1487 path = data_dir().AppendASCII("page_action.crx");
1488 InstallCRX(path, INSTALL_NEW);
1489 ValidatePrefKeyCount(++pref_count);
1490 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1491 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
1493 // Bad signature.
1494 path = data_dir().AppendASCII("bad_signature.crx");
1495 InstallCRX(path, INSTALL_FAILED);
1496 ValidatePrefKeyCount(pref_count);
1498 // 0-length extension file.
1499 path = data_dir().AppendASCII("not_an_extension.crx");
1500 InstallCRX(path, INSTALL_FAILED);
1501 ValidatePrefKeyCount(pref_count);
1503 // Bad magic number.
1504 path = data_dir().AppendASCII("bad_magic.crx");
1505 InstallCRX(path, INSTALL_FAILED);
1506 ValidatePrefKeyCount(pref_count);
1508 // Packed extensions may have folders or files that have underscores.
1509 // This will only cause a warning, rather than a fatal error.
1510 path = data_dir().AppendASCII("bad_underscore.crx");
1511 InstallCRX(path, INSTALL_NEW);
1512 ValidatePrefKeyCount(++pref_count);
1514 // A test for an extension with a 2048-bit public key.
1515 path = data_dir().AppendASCII("good2048.crx");
1516 InstallCRX(path, INSTALL_NEW);
1517 ValidatePrefKeyCount(++pref_count);
1518 ValidateIntegerPref(good2048, "state", Extension::ENABLED);
1519 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
1521 // TODO(erikkay): add more tests for many of the failure cases.
1522 // TODO(erikkay): add tests for upgrade cases.
1525 struct MockExtensionRegistryObserver
1526 : public extensions::ExtensionRegistryObserver {
1527 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
1528 const Extension* extension,
1529 bool is_update,
1530 bool from_ephemeral,
1531 const std::string& old_name) override {
1532 last_extension_installed = extension->id();
1535 void OnExtensionUninstalled(content::BrowserContext* browser_context,
1536 const Extension* extension,
1537 extensions::UninstallReason reason) override {
1538 last_extension_uninstalled = extension->id();
1541 std::string last_extension_installed;
1542 std::string last_extension_uninstalled;
1545 // Test that correct notifications are sent to ExtensionRegistryObserver on
1546 // extension install and uninstall.
1547 TEST_F(ExtensionServiceTest, InstallObserverNotified) {
1548 InitializeEmptyExtensionService();
1550 extensions::ExtensionRegistry* registry(
1551 extensions::ExtensionRegistry::Get(profile()));
1552 MockExtensionRegistryObserver observer;
1553 registry->AddObserver(&observer);
1555 // A simple extension that should install without error.
1556 ASSERT_TRUE(observer.last_extension_installed.empty());
1557 base::FilePath path = data_dir().AppendASCII("good.crx");
1558 InstallCRX(path, INSTALL_NEW);
1559 ASSERT_EQ(good_crx, observer.last_extension_installed);
1561 // Uninstall the extension.
1562 ASSERT_TRUE(observer.last_extension_uninstalled.empty());
1563 UninstallExtension(good_crx, false);
1564 ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
1566 registry->RemoveObserver(&observer);
1569 // Tests that flags passed to OnExternalExtensionFileFound() make it to the
1570 // extension object.
1571 TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
1572 const char kPrefFromBookmark[] = "from_bookmark";
1574 InitializeEmptyExtensionService();
1576 base::FilePath path = data_dir().AppendASCII("good.crx");
1577 service()->set_extensions_enabled(true);
1579 // Register and install an external extension.
1580 Version version("1.0.0.0");
1581 content::WindowedNotificationObserver observer(
1582 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1583 content::NotificationService::AllSources());
1584 if (service()->OnExternalExtensionFileFound(
1585 good_crx,
1586 &version,
1587 path,
1588 Manifest::EXTERNAL_PREF,
1589 Extension::FROM_BOOKMARK,
1590 false /* mark_acknowledged */,
1591 false /* install_immediately */)) {
1592 observer.Wait();
1595 const Extension* extension = service()->GetExtensionById(good_crx, false);
1596 ASSERT_TRUE(extension);
1597 ASSERT_TRUE(extension->from_bookmark());
1598 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1600 // Upgrade to version 2.0, the flag should be preserved.
1601 path = data_dir().AppendASCII("good2.crx");
1602 UpdateExtension(good_crx, path, ENABLED);
1603 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1604 extension = service()->GetExtensionById(good_crx, false);
1605 ASSERT_TRUE(extension);
1606 ASSERT_TRUE(extension->from_bookmark());
1609 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1610 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
1611 InitializeEmptyExtensionService();
1613 base::FilePath path = data_dir().AppendASCII("good.crx");
1614 service()->set_extensions_enabled(true);
1616 // Install an external extension.
1617 Version version("1.0.0.0");
1618 content::WindowedNotificationObserver observer(
1619 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1620 content::NotificationService::AllSources());
1621 if (service()->OnExternalExtensionFileFound(good_crx,
1622 &version,
1623 path,
1624 Manifest::EXTERNAL_PREF,
1625 Extension::NO_FLAGS,
1626 false,
1627 false)) {
1628 observer.Wait();
1631 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1633 // Uninstall it and check that its killbit gets set.
1634 UninstallExtension(good_crx, false);
1635 ValidateIntegerPref(good_crx, "state",
1636 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1638 // Try to re-install it externally. This should fail because of the killbit.
1639 service()->OnExternalExtensionFileFound(good_crx,
1640 &version,
1641 path,
1642 Manifest::EXTERNAL_PREF,
1643 Extension::NO_FLAGS,
1644 false,
1645 false);
1646 base::RunLoop().RunUntilIdle();
1647 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1648 ValidateIntegerPref(good_crx, "state",
1649 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1651 version = Version("1.0.0.1");
1652 // Repeat the same thing with a newer version of the extension.
1653 path = data_dir().AppendASCII("good2.crx");
1654 service()->OnExternalExtensionFileFound(good_crx,
1655 &version,
1656 path,
1657 Manifest::EXTERNAL_PREF,
1658 Extension::NO_FLAGS,
1659 false,
1660 false);
1661 base::RunLoop().RunUntilIdle();
1662 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1663 ValidateIntegerPref(good_crx, "state",
1664 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1666 // Try adding the same extension from an external update URL.
1667 ASSERT_FALSE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
1668 good_crx,
1669 std::string(),
1670 GURL("http:://fake.update/url"),
1671 Manifest::EXTERNAL_PREF_DOWNLOAD,
1672 Extension::NO_FLAGS,
1673 false));
1675 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
1678 // Test that uninstalling an external extension does not crash when
1679 // the extension could not be loaded.
1680 // This extension shown in preferences file requires an experimental permission.
1681 // It could not be loaded without such permission.
1682 TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
1683 base::FilePath source_install_dir =
1684 data_dir().AppendASCII("good").AppendASCII("Extensions");
1685 // The preference contains an external extension
1686 // that requires 'experimental' permission.
1687 base::FilePath pref_path = source_install_dir
1688 .DirName()
1689 .AppendASCII("PreferencesExperimental");
1691 // Aforementioned extension will not be loaded if
1692 // there is no '--enable-experimental-extension-apis' command line flag.
1693 InitializeInstalledExtensionService(pref_path, source_install_dir);
1695 service()->Init();
1697 // Check and try to uninstall it.
1698 // If we don't check whether the extension is loaded before we uninstall it
1699 // in CheckExternalUninstall, a crash will happen here because we will get or
1700 // dereference a NULL pointer (extension) inside UninstallExtension.
1701 MockExtensionProvider provider(NULL, Manifest::EXTERNAL_REGISTRY);
1702 service()->OnExternalProviderReady(&provider);
1705 // Test that external extensions with incorrect IDs are not installed.
1706 TEST_F(ExtensionServiceTest, FailOnWrongId) {
1707 InitializeEmptyExtensionService();
1708 base::FilePath path = data_dir().AppendASCII("good.crx");
1709 service()->set_extensions_enabled(true);
1711 Version version("1.0.0.0");
1713 const std::string wrong_id = all_zero;
1714 const std::string correct_id = good_crx;
1715 ASSERT_NE(correct_id, wrong_id);
1717 // Install an external extension with an ID from the external
1718 // source that is not equal to the ID in the extension manifest.
1719 content::WindowedNotificationObserver observer(
1720 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1721 content::NotificationService::AllSources());
1722 service()->OnExternalExtensionFileFound(wrong_id,
1723 &version,
1724 path,
1725 Manifest::EXTERNAL_PREF,
1726 Extension::NO_FLAGS,
1727 false,
1728 false);
1730 observer.Wait();
1731 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1733 // Try again with the right ID. Expect success.
1734 content::WindowedNotificationObserver observer2(
1735 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1736 content::NotificationService::AllSources());
1737 if (service()->OnExternalExtensionFileFound(correct_id,
1738 &version,
1739 path,
1740 Manifest::EXTERNAL_PREF,
1741 Extension::NO_FLAGS,
1742 false,
1743 false)) {
1744 observer2.Wait();
1746 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1749 // Test that external extensions with incorrect versions are not installed.
1750 TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1751 InitializeEmptyExtensionService();
1752 base::FilePath path = data_dir().AppendASCII("good.crx");
1753 service()->set_extensions_enabled(true);
1755 // Install an external extension with a version from the external
1756 // source that is not equal to the version in the extension manifest.
1757 Version wrong_version("1.2.3.4");
1758 content::WindowedNotificationObserver observer(
1759 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1760 content::NotificationService::AllSources());
1761 service()->OnExternalExtensionFileFound(good_crx,
1762 &wrong_version,
1763 path,
1764 Manifest::EXTERNAL_PREF,
1765 Extension::NO_FLAGS,
1766 false,
1767 false);
1769 observer.Wait();
1770 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1772 // Try again with the right version. Expect success.
1773 service()->pending_extension_manager()->Remove(good_crx);
1774 Version correct_version("1.0.0.0");
1775 content::WindowedNotificationObserver observer2(
1776 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1777 content::NotificationService::AllSources());
1778 if (service()->OnExternalExtensionFileFound(good_crx,
1779 &correct_version,
1780 path,
1781 Manifest::EXTERNAL_PREF,
1782 Extension::NO_FLAGS,
1783 false,
1784 false)) {
1785 observer2.Wait();
1787 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1790 // Install a user script (they get converted automatically to an extension)
1791 TEST_F(ExtensionServiceTest, InstallUserScript) {
1792 // The details of script conversion are tested elsewhere, this just tests
1793 // integration with ExtensionService.
1794 InitializeEmptyExtensionService();
1796 base::FilePath path = data_dir().AppendASCII("user_script_basic.user.js");
1798 ASSERT_TRUE(base::PathExists(path));
1799 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1800 installer->set_allow_silent_install(true);
1801 installer->InstallUserScript(
1802 path,
1803 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1805 base::RunLoop().RunUntilIdle();
1806 std::vector<base::string16> errors = GetErrors();
1807 EXPECT_TRUE(installed_) << "Nothing was installed.";
1808 EXPECT_FALSE(was_update_) << path.value();
1809 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1810 EXPECT_EQ(0u, errors.size()) << "There were errors: "
1811 << JoinString(errors, ',');
1812 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false))
1813 << path.value();
1815 installed_ = NULL;
1816 was_update_ = false;
1817 loaded_.clear();
1818 ExtensionErrorReporter::GetInstance()->ClearErrors();
1821 // Extensions don't install during shutdown.
1822 TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
1823 InitializeEmptyExtensionService();
1825 // Simulate shutdown.
1826 service()->set_browser_terminating_for_test(true);
1828 base::FilePath path = data_dir().AppendASCII("good.crx");
1829 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1830 installer->set_allow_silent_install(true);
1831 installer->InstallCrx(path);
1832 base::RunLoop().RunUntilIdle();
1834 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
1835 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
1838 // This tests that the granted permissions preferences are correctly set when
1839 // installing an extension.
1840 TEST_F(ExtensionServiceTest, GrantedPermissions) {
1841 InitializeEmptyExtensionService();
1842 base::FilePath path = data_dir().AppendASCII("permissions");
1844 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1845 path = path.AppendASCII("unknown");
1847 ASSERT_TRUE(base::PathExists(pem_path));
1848 ASSERT_TRUE(base::PathExists(path));
1850 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1852 APIPermissionSet expected_api_perms;
1853 URLPatternSet expected_host_perms;
1855 // Make sure there aren't any granted permissions before the
1856 // extension is installed.
1857 scoped_refptr<PermissionSet> known_perms(
1858 prefs->GetGrantedPermissions(permissions_crx));
1859 EXPECT_FALSE(known_perms.get());
1861 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
1863 EXPECT_EQ(0u, GetErrors().size());
1864 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1865 EXPECT_EQ(permissions_crx, extension->id());
1867 // Verify that the valid API permissions have been recognized.
1868 expected_api_perms.insert(APIPermission::kTab);
1870 AddPattern(&expected_host_perms, "http://*.google.com/*");
1871 AddPattern(&expected_host_perms, "https://*.google.com/*");
1872 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
1873 AddPattern(&expected_host_perms, "http://www.example.com/*");
1875 known_perms = prefs->GetGrantedPermissions(extension->id());
1876 EXPECT_TRUE(known_perms.get());
1877 EXPECT_FALSE(known_perms->IsEmpty());
1878 EXPECT_EQ(expected_api_perms, known_perms->apis());
1879 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1880 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
1884 #if !defined(OS_CHROMEOS)
1885 // This tests that the granted permissions preferences are correctly set for
1886 // default apps.
1887 TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
1888 InitializeEmptyExtensionService();
1889 base::FilePath path = data_dir().AppendASCII("permissions");
1891 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1892 path = path.AppendASCII("unknown");
1894 ASSERT_TRUE(base::PathExists(pem_path));
1895 ASSERT_TRUE(base::PathExists(path));
1897 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1899 APIPermissionSet expected_api_perms;
1900 URLPatternSet expected_host_perms;
1902 // Make sure there aren't any granted permissions before the
1903 // extension is installed.
1904 scoped_refptr<PermissionSet> known_perms(
1905 prefs->GetGrantedPermissions(permissions_crx));
1906 EXPECT_FALSE(known_perms.get());
1908 const Extension* extension = PackAndInstallCRX(
1909 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
1911 EXPECT_EQ(0u, GetErrors().size());
1912 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1913 EXPECT_EQ(permissions_crx, extension->id());
1915 // Verify that the valid API permissions have been recognized.
1916 expected_api_perms.insert(APIPermission::kTab);
1918 known_perms = prefs->GetGrantedPermissions(extension->id());
1919 EXPECT_TRUE(known_perms.get());
1920 EXPECT_FALSE(known_perms->IsEmpty());
1921 EXPECT_EQ(expected_api_perms, known_perms->apis());
1922 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1924 #endif
1926 #if !defined(OS_POSIX) || defined(OS_MACOSX)
1927 // Tests that the granted permissions full_access bit gets set correctly when
1928 // an extension contains an NPAPI plugin.
1929 // Only run this on platforms that support NPAPI plugins.
1930 TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
1931 InitPluginService();
1933 InitializeEmptyExtensionService();
1935 ASSERT_TRUE(base::PathExists(good1_path()));
1936 const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW);
1937 EXPECT_EQ(0u, GetErrors().size());
1938 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1939 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1941 scoped_refptr<PermissionSet> permissions(
1942 prefs->GetGrantedPermissions(extension->id()));
1943 EXPECT_FALSE(permissions->IsEmpty());
1944 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
1945 EXPECT_FALSE(permissions->apis().empty());
1946 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
1948 // Full access implies full host access too...
1949 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
1951 #endif
1953 // Tests that the extension is disabled when permissions are missing from
1954 // the extension's granted permissions preferences. (This simulates updating
1955 // the browser to a version which recognizes more permissions).
1956 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
1957 InitializeEmptyExtensionService();
1959 base::FilePath path =
1960 data_dir().AppendASCII("permissions").AppendASCII("unknown");
1962 ASSERT_TRUE(base::PathExists(path));
1964 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
1966 EXPECT_EQ(0u, GetErrors().size());
1967 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1968 std::string extension_id = extension->id();
1970 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1972 APIPermissionSet expected_api_permissions;
1973 URLPatternSet expected_host_permissions;
1975 expected_api_permissions.insert(APIPermission::kTab);
1976 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1977 AddPattern(&expected_host_permissions, "https://*.google.com/*");
1978 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
1979 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1981 std::set<std::string> host_permissions;
1983 // Test that the extension is disabled when an API permission is missing from
1984 // the extension's granted api permissions preference. (This simulates
1985 // updating the browser to a version which recognizes a new API permission).
1986 SetPref(extension_id, "granted_permissions.api",
1987 new base::ListValue(), "granted_permissions.api");
1988 service()->ReloadExtensionsForTest();
1990 EXPECT_EQ(1u, registry()->disabled_extensions().size());
1991 extension = registry()->disabled_extensions().begin()->get();
1993 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
1994 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
1995 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1997 // Now grant and re-enable the extension, making sure the prefs are updated.
1998 service()->GrantPermissionsAndEnableExtension(extension);
2000 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
2001 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
2002 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2004 scoped_refptr<PermissionSet> current_perms(
2005 prefs->GetGrantedPermissions(extension_id));
2006 ASSERT_TRUE(current_perms.get());
2007 ASSERT_FALSE(current_perms->IsEmpty());
2008 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2009 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2010 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2012 // Tests that the extension is disabled when a host permission is missing from
2013 // the extension's granted host permissions preference. (This simulates
2014 // updating the browser to a version which recognizes additional host
2015 // permissions).
2016 host_permissions.clear();
2017 current_perms = NULL;
2019 host_permissions.insert("http://*.google.com/*");
2020 host_permissions.insert("https://*.google.com/*");
2021 host_permissions.insert("http://*.google.com.hk/*");
2023 base::ListValue* api_permissions = new base::ListValue();
2024 api_permissions->Append(
2025 new base::StringValue("tabs"));
2026 SetPref(extension_id, "granted_permissions.api",
2027 api_permissions, "granted_permissions.api");
2028 SetPrefStringSet(
2029 extension_id, "granted_permissions.scriptable_host", host_permissions);
2031 service()->ReloadExtensionsForTest();
2033 EXPECT_EQ(1u, registry()->disabled_extensions().size());
2034 extension = registry()->disabled_extensions().begin()->get();
2036 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2037 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
2038 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2040 // Now grant and re-enable the extension, making sure the prefs are updated.
2041 service()->GrantPermissionsAndEnableExtension(extension);
2043 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
2044 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2046 current_perms = prefs->GetGrantedPermissions(extension_id);
2047 ASSERT_TRUE(current_perms.get());
2048 ASSERT_FALSE(current_perms->IsEmpty());
2049 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2050 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2051 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2054 // Test Packaging and installing an extension.
2055 TEST_F(ExtensionServiceTest, PackExtension) {
2056 InitializeEmptyExtensionService();
2057 base::FilePath input_directory =
2058 data_dir()
2059 .AppendASCII("good")
2060 .AppendASCII("Extensions")
2061 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2062 .AppendASCII("1.0.0.0");
2064 base::ScopedTempDir temp_dir;
2065 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2066 base::FilePath output_directory = temp_dir.path();
2068 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2069 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2071 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2072 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2073 privkey_path, ExtensionCreator::kNoRunFlags));
2074 ASSERT_TRUE(base::PathExists(crx_path));
2075 ASSERT_TRUE(base::PathExists(privkey_path));
2077 // Repeat the run with the pem file gone, and no special flags
2078 // Should refuse to overwrite the existing crx.
2079 base::DeleteFile(privkey_path, false);
2080 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2081 privkey_path, ExtensionCreator::kNoRunFlags));
2083 // OK, now try it with a flag to overwrite existing crx. Should work.
2084 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2085 privkey_path, ExtensionCreator::kOverwriteCRX));
2087 // Repeat the run allowing existing crx, but the existing pem is still
2088 // an error. Should fail.
2089 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2090 privkey_path, ExtensionCreator::kOverwriteCRX));
2092 ASSERT_TRUE(base::PathExists(privkey_path));
2093 InstallCRX(crx_path, INSTALL_NEW);
2095 // Try packing with invalid paths.
2096 creator.reset(new ExtensionCreator());
2097 ASSERT_FALSE(
2098 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
2099 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2101 // Try packing an empty directory. Should fail because an empty directory is
2102 // not a valid extension.
2103 base::ScopedTempDir temp_dir2;
2104 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
2105 creator.reset(new ExtensionCreator());
2106 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2107 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2109 // Try packing with an invalid manifest.
2110 std::string invalid_manifest_content = "I am not a manifest.";
2111 ASSERT_TRUE(base::WriteFile(
2112 temp_dir2.path().Append(extensions::kManifestFilename),
2113 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
2114 creator.reset(new ExtensionCreator());
2115 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2116 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2118 // Try packing with a private key that is a valid key, but invalid for the
2119 // extension.
2120 base::FilePath bad_private_key_dir =
2121 data_dir().AppendASCII("bad_private_key");
2122 crx_path = output_directory.AppendASCII("bad_private_key.crx");
2123 privkey_path = data_dir().AppendASCII("bad_private_key.pem");
2124 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
2125 privkey_path, ExtensionCreator::kOverwriteCRX));
2128 // Test Packaging and installing an extension whose name contains punctuation.
2129 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
2130 InitializeEmptyExtensionService();
2131 base::FilePath input_directory = data_dir()
2132 .AppendASCII("good")
2133 .AppendASCII("Extensions")
2134 .AppendASCII(good0)
2135 .AppendASCII("1.0.0.0");
2137 base::ScopedTempDir temp_dir;
2138 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2140 // Extension names containing punctuation, and the expected names for the
2141 // packed extensions.
2142 const base::FilePath punctuated_names[] = {
2143 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2144 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2145 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
2146 NormalizePathSeparators(),
2148 const base::FilePath expected_crx_names[] = {
2149 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2150 base::FilePath(
2151 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2152 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
2154 const base::FilePath expected_private_key_names[] = {
2155 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2156 base::FilePath(
2157 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2158 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
2161 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
2162 SCOPED_TRACE(punctuated_names[i].value().c_str());
2163 base::FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
2165 // Copy the extension into the output directory, as PackExtensionJob doesn't
2166 // let us choose where to output the packed extension.
2167 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
2169 base::FilePath expected_crx_path =
2170 temp_dir.path().Append(expected_crx_names[i]);
2171 base::FilePath expected_private_key_path =
2172 temp_dir.path().Append(expected_private_key_names[i]);
2173 PackExtensionTestClient pack_client(expected_crx_path,
2174 expected_private_key_path);
2175 scoped_refptr<extensions::PackExtensionJob> packer(
2176 new extensions::PackExtensionJob(&pack_client, output_dir,
2177 base::FilePath(),
2178 ExtensionCreator::kOverwriteCRX));
2179 packer->Start();
2181 // The packer will post a notification task to the current thread's message
2182 // loop when it is finished. We manually run the loop here so that we
2183 // block and catch the notification; otherwise, the process would exit.
2184 // This call to |Run()| is matched by a call to |Quit()| in the
2185 // |PackExtensionTestClient|'s notification handling code.
2186 base::MessageLoop::current()->Run();
2188 if (HasFatalFailure())
2189 return;
2191 InstallCRX(expected_crx_path, INSTALL_NEW);
2195 TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
2196 InitializeEmptyExtensionService();
2198 base::ScopedTempDir extension_temp_dir;
2199 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
2200 base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
2201 ASSERT_TRUE(
2202 base::CopyDirectory(data_dir()
2203 .AppendASCII("good")
2204 .AppendASCII("Extensions")
2205 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2206 .AppendASCII("1.0.0.0"),
2207 input_directory,
2208 /*recursive=*/true));
2210 base::ScopedTempDir output_temp_dir;
2211 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
2212 base::FilePath output_directory = output_temp_dir.path();
2214 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2215 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2217 // Pack the extension once to get a private key.
2218 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2219 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2220 privkey_path, ExtensionCreator::kNoRunFlags))
2221 << creator->error_message();
2222 ASSERT_TRUE(base::PathExists(crx_path));
2223 ASSERT_TRUE(base::PathExists(privkey_path));
2225 base::DeleteFile(crx_path, false);
2226 // Move the pem file into the extension.
2227 base::Move(privkey_path,
2228 input_directory.AppendASCII("privkey.pem"));
2230 // This pack should fail because of the contained private key.
2231 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2232 privkey_path, ExtensionCreator::kNoRunFlags));
2233 EXPECT_THAT(creator->error_message(),
2234 testing::ContainsRegex(
2235 "extension includes the key file.*privkey.pem"));
2238 // Test Packaging and installing an extension using an openssl generated key.
2239 // The openssl is generated with the following:
2240 // > openssl genrsa -out privkey.pem 1024
2241 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
2242 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
2243 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
2244 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
2245 InitializeEmptyExtensionService();
2246 base::FilePath input_directory =
2247 data_dir()
2248 .AppendASCII("good")
2249 .AppendASCII("Extensions")
2250 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2251 .AppendASCII("1.0.0.0");
2252 base::FilePath privkey_path(
2253 data_dir().AppendASCII("openssl_privkey_asn1.pem"));
2254 ASSERT_TRUE(base::PathExists(privkey_path));
2256 base::ScopedTempDir temp_dir;
2257 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2258 base::FilePath output_directory = temp_dir.path();
2260 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2262 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2263 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
2264 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2266 InstallCRX(crx_path, INSTALL_NEW);
2269 #if defined(THREAD_SANITIZER)
2270 // Flaky under Tsan. http://crbug.com/377702
2271 #define MAYBE_InstallTheme DISABLED_InstallTheme
2272 #else
2273 #define MAYBE_InstallTheme InstallTheme
2274 #endif
2276 TEST_F(ExtensionServiceTest, MAYBE_InstallTheme) {
2277 InitializeEmptyExtensionService();
2278 service()->Init();
2280 // A theme.
2281 base::FilePath path = data_dir().AppendASCII("theme.crx");
2282 InstallCRX(path, INSTALL_NEW);
2283 int pref_count = 0;
2284 ValidatePrefKeyCount(++pref_count);
2285 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2286 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2288 // A theme when extensions are disabled. Themes can be installed, even when
2289 // extensions are disabled.
2290 service()->set_extensions_enabled(false);
2291 path = data_dir().AppendASCII("theme2.crx");
2292 InstallCRX(path, INSTALL_NEW);
2293 ValidatePrefKeyCount(++pref_count);
2294 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
2295 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
2297 // A theme with extension elements. Themes cannot have extension elements,
2298 // so any such elements (like content scripts) should be ignored.
2299 service()->set_extensions_enabled(true);
2301 path = data_dir().AppendASCII("theme_with_extension.crx");
2302 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2303 ValidatePrefKeyCount(++pref_count);
2304 ASSERT_TRUE(extension);
2305 EXPECT_TRUE(extension->is_theme());
2306 EXPECT_EQ(
2308 extensions::ContentScriptsInfo::GetContentScripts(extension).size());
2311 // A theme with image resources missing (misspelt path).
2312 path = data_dir().AppendASCII("theme_missing_image.crx");
2313 InstallCRX(path, INSTALL_FAILED);
2314 ValidatePrefKeyCount(pref_count);
2317 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
2318 // Load.
2319 InitializeEmptyExtensionService();
2320 service()->Init();
2322 base::FilePath extension_path = data_dir().AppendASCII("theme_i18n");
2324 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2325 base::RunLoop().RunUntilIdle();
2326 EXPECT_EQ(0u, GetErrors().size());
2327 ASSERT_EQ(1u, loaded_.size());
2328 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2329 const Extension* theme = registry()->enabled_extensions().begin()->get();
2330 EXPECT_EQ("name", theme->name());
2331 EXPECT_EQ("description", theme->description());
2333 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a
2334 // temporary directory, but it automatically installs to the extension's
2335 // directory, and we don't want to copy the whole extension for a unittest.
2336 base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
2337 ASSERT_TRUE(base::PathExists(theme_file));
2338 ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive.
2341 #if defined(OS_POSIX)
2342 TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
2343 base::FilePath source_data_dir =
2344 data_dir().AppendASCII("unpacked").AppendASCII("symlinks_allowed");
2346 // Paths to test data files.
2347 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2348 ASSERT_TRUE(base::PathExists(source_manifest));
2349 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2350 ASSERT_TRUE(base::PathExists(source_icon));
2352 // Set up the temporary extension directory.
2353 base::ScopedTempDir temp;
2354 ASSERT_TRUE(temp.CreateUniqueTempDir());
2355 base::FilePath extension_path = temp.path();
2356 base::FilePath manifest = extension_path.Append(
2357 extensions::kManifestFilename);
2358 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2359 base::CopyFile(source_manifest, manifest);
2360 base::CreateSymbolicLink(source_icon, icon_symlink);
2362 // Load extension.
2363 InitializeEmptyExtensionService();
2364 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2365 base::RunLoop().RunUntilIdle();
2367 EXPECT_TRUE(GetErrors().empty());
2368 ASSERT_EQ(1u, loaded_.size());
2369 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2371 #endif
2373 TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
2374 InitializeEmptyExtensionService();
2375 base::FilePath extension_path = data_dir().AppendASCII("underscore_name");
2376 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2377 base::RunLoop().RunUntilIdle();
2378 EXPECT_EQ(1u, GetErrors().size());
2379 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2382 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
2383 InitializeEmptyExtensionService();
2384 service()->Init();
2386 base::FilePath theme_path = data_dir().AppendASCII("theme_i18n");
2388 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
2390 EXPECT_EQ(0u, GetErrors().size());
2391 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2392 EXPECT_EQ("name", theme->name());
2393 EXPECT_EQ("description", theme->description());
2396 TEST_F(ExtensionServiceTest, InstallApps) {
2397 InitializeEmptyExtensionService();
2399 // An empty app.
2400 const Extension* app =
2401 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2402 int pref_count = 0;
2403 ValidatePrefKeyCount(++pref_count);
2404 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2405 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2406 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
2408 // Another app with non-overlapping extent. Should succeed.
2409 PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2410 ValidatePrefKeyCount(++pref_count);
2412 // A third app whose extent overlaps the first. Should fail.
2413 PackAndInstallCRX(data_dir().AppendASCII("app3"), INSTALL_FAILED);
2414 ValidatePrefKeyCount(pref_count);
2417 // Tests that file access is OFF by default.
2418 TEST_F(ExtensionServiceTest, DefaultFileAccess) {
2419 InitializeEmptyExtensionService();
2420 const Extension* extension = PackAndInstallCRX(
2421 data_dir().AppendASCII("permissions").AppendASCII("files"), INSTALL_NEW);
2422 EXPECT_EQ(0u, GetErrors().size());
2423 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2424 EXPECT_FALSE(
2425 ExtensionPrefs::Get(profile())->AllowFileAccess(extension->id()));
2428 TEST_F(ExtensionServiceTest, UpdateApps) {
2429 InitializeEmptyExtensionService();
2430 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2432 // First install v1 of a hosted app.
2433 const Extension* extension =
2434 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2435 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2436 std::string id = extension->id();
2437 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2439 // Now try updating to v2.
2440 UpdateExtension(id,
2441 extensions_path.AppendASCII("v2.crx"),
2442 ENABLED);
2443 ASSERT_EQ(std::string("2"),
2444 service()->GetExtensionById(id, false)->version()->GetString());
2447 // Verifies that the NTP page and launch ordinals are kept when updating apps.
2448 TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
2449 InitializeEmptyExtensionService();
2450 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2451 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2453 // First install v1 of a hosted app.
2454 const Extension* extension =
2455 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2456 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2457 std::string id = extension->id();
2458 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2460 // Modify the ordinals so we can distinguish them from the defaults.
2461 syncer::StringOrdinal new_page_ordinal =
2462 sorting->GetPageOrdinal(id).CreateAfter();
2463 syncer::StringOrdinal new_launch_ordinal =
2464 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2466 sorting->SetPageOrdinal(id, new_page_ordinal);
2467 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2469 // Now try updating to v2.
2470 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2471 ASSERT_EQ(std::string("2"),
2472 service()->GetExtensionById(id, false)->version()->GetString());
2474 // Verify that the ordinals match.
2475 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2476 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
2479 // Ensures that the CWS has properly initialized ordinals.
2480 TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
2481 InitializeEmptyExtensionService();
2482 service()->component_loader()->Add(
2483 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
2484 service()->Init();
2486 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2487 EXPECT_TRUE(
2488 sorting->GetPageOrdinal(extensions::kWebStoreAppId).IsValid());
2489 EXPECT_TRUE(
2490 sorting->GetAppLaunchOrdinal(extensions::kWebStoreAppId).IsValid());
2493 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
2494 InitializeEmptyExtensionService();
2495 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2497 int pref_count = 0;
2499 // Install app1 with unlimited storage.
2500 const Extension* extension =
2501 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2502 ValidatePrefKeyCount(++pref_count);
2503 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2504 const std::string id1 = extension->id();
2505 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2506 APIPermission::kUnlimitedStorage));
2507 EXPECT_TRUE(extension->web_extent().MatchesURL(
2508 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2509 const GURL origin1(
2510 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2511 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2512 origin1));
2514 // Install app2 from the same origin with unlimited storage.
2515 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2516 ValidatePrefKeyCount(++pref_count);
2517 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2518 const std::string id2 = extension->id();
2519 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2520 APIPermission::kUnlimitedStorage));
2521 EXPECT_TRUE(extension->web_extent().MatchesURL(
2522 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2523 const GURL origin2(
2524 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2525 EXPECT_EQ(origin1, origin2);
2526 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2527 origin2));
2529 // Uninstall one of them, unlimited storage should still be granted
2530 // to the origin.
2531 UninstallExtension(id1, false);
2532 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2533 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2534 origin1));
2536 // Uninstall the other, unlimited storage should be revoked.
2537 UninstallExtension(id2, false);
2538 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2539 EXPECT_FALSE(
2540 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2541 origin2));
2544 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
2545 InitializeEmptyExtensionService();
2546 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2548 int pref_count = 0;
2550 const Extension* extension =
2551 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2552 ValidatePrefKeyCount(++pref_count);
2553 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2554 EXPECT_TRUE(extension->is_app());
2555 const std::string id1 = extension->id();
2556 const GURL origin1(
2557 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2558 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2559 origin1));
2561 // App 4 has a different origin (maps.google.com).
2562 extension = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
2563 ValidatePrefKeyCount(++pref_count);
2564 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2565 const std::string id2 = extension->id();
2566 const GURL origin2(
2567 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2568 ASSERT_NE(origin1, origin2);
2569 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2570 origin2));
2572 UninstallExtension(id1, false);
2573 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2575 UninstallExtension(id2, false);
2577 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2578 EXPECT_FALSE(
2579 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2580 origin1));
2581 EXPECT_FALSE(
2582 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2583 origin2));
2586 // Test that when an extension version is reinstalled, nothing happens.
2587 TEST_F(ExtensionServiceTest, Reinstall) {
2588 InitializeEmptyExtensionService();
2590 // A simple extension that should install without error.
2591 base::FilePath path = data_dir().AppendASCII("good.crx");
2592 InstallCRX(path, INSTALL_NEW);
2594 ValidatePrefKeyCount(1);
2595 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2596 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2598 // Reinstall the same version, it should overwrite the previous one.
2599 InstallCRX(path, INSTALL_UPDATED);
2601 ValidatePrefKeyCount(1);
2602 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2603 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2606 // Test that we can determine if extensions came from the
2607 // Chrome web store.
2608 TEST_F(ExtensionServiceTest, FromWebStore) {
2609 InitializeEmptyExtensionService();
2611 // A simple extension that should install without error.
2612 base::FilePath path = data_dir().AppendASCII("good.crx");
2613 // Not from web store.
2614 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2615 std::string id = extension->id();
2617 ValidatePrefKeyCount(1);
2618 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
2619 ASSERT_FALSE(extension->from_webstore());
2621 // Test install from web store.
2622 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
2624 ValidatePrefKeyCount(1);
2625 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2627 // Reload so extension gets reinitialized with new value.
2628 service()->ReloadExtensionsForTest();
2629 extension = service()->GetExtensionById(id, false);
2630 ASSERT_TRUE(extension->from_webstore());
2632 // Upgrade to version 2.0
2633 path = data_dir().AppendASCII("good2.crx");
2634 UpdateExtension(good_crx, path, ENABLED);
2635 ValidatePrefKeyCount(1);
2636 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2639 // Test upgrading a signed extension.
2640 TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
2641 InitializeEmptyExtensionService();
2643 base::FilePath path = data_dir().AppendASCII("good.crx");
2644 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2645 std::string id = extension->id();
2647 ASSERT_EQ("1.0.0.0", extension->version()->GetString());
2648 ASSERT_EQ(0u, GetErrors().size());
2650 // Upgrade to version 1.0.0.1.
2651 // Also test that the extension's old and new title are correctly retrieved.
2652 path = data_dir().AppendASCII("good2.crx");
2653 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
2654 extension = service()->GetExtensionById(id, false);
2656 ASSERT_EQ("1.0.0.1", extension->version()->GetString());
2657 ASSERT_EQ("My updated extension 1", extension->name());
2658 ASSERT_EQ(0u, GetErrors().size());
2661 // Test upgrading a signed extension with a bad signature.
2662 TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
2663 InitializeEmptyExtensionService();
2665 base::FilePath path = data_dir().AppendASCII("good.crx");
2666 InstallCRX(path, INSTALL_NEW);
2668 // Try upgrading with a bad signature. This should fail during the unpack,
2669 // because the key will not match the signature.
2670 path = data_dir().AppendASCII("bad_signature.crx");
2671 InstallCRX(path, INSTALL_FAILED);
2674 // Test a normal update via the UpdateExtension API
2675 TEST_F(ExtensionServiceTest, UpdateExtension) {
2676 InitializeEmptyExtensionService();
2678 base::FilePath path = data_dir().AppendASCII("good.crx");
2680 const Extension* good = InstallCRX(path, INSTALL_NEW);
2681 ASSERT_EQ("1.0.0.0", good->VersionString());
2682 ASSERT_EQ(good_crx, good->id());
2684 path = data_dir().AppendASCII("good2.crx");
2685 UpdateExtension(good_crx, path, ENABLED);
2686 ASSERT_EQ(
2687 "1.0.0.1",
2688 service()->GetExtensionById(good_crx, false)->version()->GetString());
2691 // Extensions should not be updated during browser shutdown.
2692 TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
2693 InitializeEmptyExtensionService();
2695 // Install an extension.
2696 base::FilePath path = data_dir().AppendASCII("good.crx");
2697 const Extension* good = InstallCRX(path, INSTALL_NEW);
2698 ASSERT_EQ(good_crx, good->id());
2700 // Simulate shutdown.
2701 service()->set_browser_terminating_for_test(true);
2703 // Update should fail and extension should not be updated.
2704 path = data_dir().AppendASCII("good2.crx");
2705 bool updated = service()->UpdateExtension(
2706 extensions::CRXFileInfo(good_crx, path), true, NULL);
2707 ASSERT_FALSE(updated);
2708 ASSERT_EQ(
2709 "1.0.0.0",
2710 service()->GetExtensionById(good_crx, false)->version()->GetString());
2713 // Test updating a not-already-installed extension - this should fail
2714 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
2715 InitializeEmptyExtensionService();
2717 base::FilePath path = data_dir().AppendASCII("good.crx");
2718 UpdateExtension(good_crx, path, UPDATED);
2719 base::RunLoop().RunUntilIdle();
2721 ASSERT_EQ(0u, registry()->enabled_extensions().size());
2722 ASSERT_FALSE(installed_);
2723 ASSERT_EQ(0u, loaded_.size());
2726 // Makes sure you can't downgrade an extension via UpdateExtension
2727 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
2728 InitializeEmptyExtensionService();
2730 base::FilePath path = data_dir().AppendASCII("good2.crx");
2732 const Extension* good = InstallCRX(path, INSTALL_NEW);
2733 ASSERT_EQ("1.0.0.1", good->VersionString());
2734 ASSERT_EQ(good_crx, good->id());
2736 // Change path from good2.crx -> good.crx
2737 path = data_dir().AppendASCII("good.crx");
2738 UpdateExtension(good_crx, path, FAILED);
2739 ASSERT_EQ(
2740 "1.0.0.1",
2741 service()->GetExtensionById(good_crx, false)->version()->GetString());
2744 // Make sure calling update with an identical version does nothing
2745 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
2746 InitializeEmptyExtensionService();
2748 base::FilePath path = data_dir().AppendASCII("good.crx");
2750 const Extension* good = InstallCRX(path, INSTALL_NEW);
2751 ASSERT_EQ(good_crx, good->id());
2752 UpdateExtension(good_crx, path, FAILED_SILENTLY);
2755 // Tests that updating an extension does not clobber old state.
2756 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
2757 InitializeEmptyExtensionService();
2759 base::FilePath path = data_dir().AppendASCII("good.crx");
2761 const Extension* good = InstallCRX(path, INSTALL_NEW);
2762 ASSERT_EQ("1.0.0.0", good->VersionString());
2763 ASSERT_EQ(good_crx, good->id());
2765 // Disable it and allow it to run in incognito. These settings should carry
2766 // over to the updated version.
2767 service()->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
2768 extensions::util::SetIsIncognitoEnabled(good->id(), profile(), true);
2770 path = data_dir().AppendASCII("good2.crx");
2771 UpdateExtension(good_crx, path, INSTALLED);
2772 ASSERT_EQ(1u, registry()->disabled_extensions().size());
2773 const Extension* good2 = service()->GetExtensionById(good_crx, true);
2774 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2775 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good2->id(), profile()));
2776 EXPECT_EQ(Extension::DISABLE_USER_ACTION,
2777 ExtensionPrefs::Get(profile())->GetDisableReasons(good2->id()));
2780 // Tests that updating preserves extension location.
2781 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
2782 InitializeEmptyExtensionService();
2784 base::FilePath path = data_dir().AppendASCII("good.crx");
2786 const Extension* good =
2787 InstallCRXWithLocation(path, Manifest::EXTERNAL_PREF, INSTALL_NEW);
2789 ASSERT_EQ("1.0.0.0", good->VersionString());
2790 ASSERT_EQ(good_crx, good->id());
2792 path = data_dir().AppendASCII("good2.crx");
2793 UpdateExtension(good_crx, path, ENABLED);
2794 const Extension* good2 = service()->GetExtensionById(good_crx, false);
2795 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2796 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
2799 // Makes sure that LOAD extension types can downgrade.
2800 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
2801 InitializeEmptyExtensionService();
2803 base::ScopedTempDir temp;
2804 ASSERT_TRUE(temp.CreateUniqueTempDir());
2806 // We'll write the extension manifest dynamically to a temporary path
2807 // to make it easier to change the version number.
2808 base::FilePath extension_path = temp.path();
2809 base::FilePath manifest_path =
2810 extension_path.Append(extensions::kManifestFilename);
2811 ASSERT_FALSE(base::PathExists(manifest_path));
2813 // Start with version 2.0.
2814 base::DictionaryValue manifest;
2815 manifest.SetString("version", "2.0");
2816 manifest.SetString("name", "LOAD Downgrade Test");
2817 manifest.SetInteger("manifest_version", 2);
2819 JSONFileValueSerializer serializer(manifest_path);
2820 ASSERT_TRUE(serializer.Serialize(manifest));
2822 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2823 base::RunLoop().RunUntilIdle();
2825 EXPECT_EQ(0u, GetErrors().size());
2826 ASSERT_EQ(1u, loaded_.size());
2827 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2828 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2829 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2831 // Now set the version number to 1.0, reload the extensions and verify that
2832 // the downgrade was accepted.
2833 manifest.SetString("version", "1.0");
2834 ASSERT_TRUE(serializer.Serialize(manifest));
2836 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2837 base::RunLoop().RunUntilIdle();
2839 EXPECT_EQ(0u, GetErrors().size());
2840 ASSERT_EQ(1u, loaded_.size());
2841 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2842 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2843 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2846 #if !defined(OS_POSIX) || defined(OS_MACOSX)
2847 // LOAD extensions with plugins require approval.
2848 // Only run this on platforms that support NPAPI plugins.
2849 TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
2850 base::FilePath extension_with_plugin_path = good1_path();
2851 base::FilePath extension_no_plugin_path = good2_path();
2853 InitPluginService();
2854 InitializeEmptyExtensionService();
2855 service()->set_show_extensions_prompts(true);
2857 // Start by canceling any install prompts.
2858 scoped_ptr<extensions::ScopedTestDialogAutoConfirm> auto_confirm(
2859 new extensions::ScopedTestDialogAutoConfirm(
2860 extensions::ScopedTestDialogAutoConfirm::CANCEL));
2862 // The extension that has a plugin should not install.
2863 extensions::UnpackedInstaller::Create(service())
2864 ->Load(extension_with_plugin_path);
2865 base::RunLoop().RunUntilIdle();
2866 EXPECT_EQ(0u, GetErrors().size());
2867 EXPECT_EQ(0u, loaded_.size());
2868 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2869 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2871 // But the extension with no plugin should since there's no prompt.
2872 ExtensionErrorReporter::GetInstance()->ClearErrors();
2873 extensions::UnpackedInstaller::Create(service())
2874 ->Load(extension_no_plugin_path);
2875 base::RunLoop().RunUntilIdle();
2876 EXPECT_EQ(0u, GetErrors().size());
2877 EXPECT_EQ(1u, loaded_.size());
2878 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2879 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2880 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2882 // The plugin extension should install if we accept the dialog.
2883 auto_confirm.reset();
2884 auto_confirm.reset(new extensions::ScopedTestDialogAutoConfirm(
2885 extensions::ScopedTestDialogAutoConfirm::ACCEPT));
2887 ExtensionErrorReporter::GetInstance()->ClearErrors();
2888 extensions::UnpackedInstaller::Create(service())
2889 ->Load(extension_with_plugin_path);
2890 base::RunLoop().RunUntilIdle();
2891 EXPECT_EQ(0u, GetErrors().size());
2892 EXPECT_EQ(2u, loaded_.size());
2893 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2894 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2895 EXPECT_TRUE(registry()->enabled_extensions().Contains(good1));
2896 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2898 // Make sure the granted permissions have been setup.
2899 scoped_refptr<PermissionSet> permissions(
2900 ExtensionPrefs::Get(profile())->GetGrantedPermissions(good1));
2901 EXPECT_FALSE(permissions->IsEmpty());
2902 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
2903 EXPECT_FALSE(permissions->apis().empty());
2904 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
2906 // We should be able to reload the extension without getting another prompt.
2907 loaded_.clear();
2908 auto_confirm.reset();
2909 auto_confirm.reset(new extensions::ScopedTestDialogAutoConfirm(
2910 extensions::ScopedTestDialogAutoConfirm::CANCEL));
2912 service()->ReloadExtension(good1);
2913 base::RunLoop().RunUntilIdle();
2914 EXPECT_EQ(1u, loaded_.size());
2915 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2916 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2918 #endif // !defined(OS_POSIX) || defined(OS_MACOSX)
2920 namespace {
2922 bool IsExtension(const Extension* extension) {
2923 return extension->GetType() == Manifest::TYPE_EXTENSION;
2926 #if defined(ENABLE_BLACKLIST_TESTS)
2927 std::set<std::string> StringSet(const std::string& s) {
2928 std::set<std::string> set;
2929 set.insert(s);
2930 return set;
2932 std::set<std::string> StringSet(const std::string& s1, const std::string& s2) {
2933 std::set<std::string> set = StringSet(s1);
2934 set.insert(s2);
2935 return set;
2937 #endif // defined(ENABLE_BLACKLIST_TESTS)
2939 } // namespace
2941 // Test adding a pending extension.
2942 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
2943 InitializeEmptyExtensionService();
2945 const std::string kFakeId(all_zero);
2946 const GURL kFakeUpdateURL("http:://fake.update/url");
2947 const bool kFakeRemoteInstall(false);
2948 const bool kFakeInstalledByCustodian(false);
2950 EXPECT_TRUE(
2951 service()->pending_extension_manager()->AddFromSync(
2952 kFakeId,
2953 kFakeUpdateURL,
2954 &IsExtension,
2955 kFakeRemoteInstall,
2956 kFakeInstalledByCustodian));
2958 const extensions::PendingExtensionInfo* pending_extension_info;
2959 ASSERT_TRUE((pending_extension_info =
2960 service()->pending_extension_manager()->GetById(kFakeId)));
2961 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
2962 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
2963 // Use
2964 // EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install())
2965 // instead of
2966 // EXPECT_EQ(kFakeRemoteInstall, pending_extension_info->remote_install())
2967 // as gcc 4.7 issues the following warning on EXPECT_EQ(false, x), which is
2968 // turned into an error with -Werror=conversion-null:
2969 // converting 'false' to pointer type for argument 1 of
2970 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)'
2971 // https://code.google.com/p/googletest/issues/detail?id=458
2972 EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install());
2975 namespace {
2976 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2977 const char kGoodUpdateURL[] = "http://good.update/url";
2978 const bool kGoodIsFromSync = true;
2979 const bool kGoodRemoteInstall = false;
2980 const bool kGoodInstalledByCustodian = false;
2981 } // namespace
2983 // Test updating a pending extension.
2984 TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
2985 InitializeEmptyExtensionService();
2986 EXPECT_TRUE(
2987 service()->pending_extension_manager()->AddFromSync(
2988 kGoodId,
2989 GURL(kGoodUpdateURL),
2990 &IsExtension,
2991 kGoodRemoteInstall,
2992 kGoodInstalledByCustodian));
2993 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2995 base::FilePath path = data_dir().AppendASCII("good.crx");
2996 UpdateExtension(kGoodId, path, ENABLED);
2998 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3000 const Extension* extension = service()->GetExtensionById(kGoodId, true);
3001 ASSERT_TRUE(extension);
3004 namespace {
3006 bool IsTheme(const Extension* extension) {
3007 return extension->is_theme();
3010 } // namespace
3012 // Test updating a pending theme.
3013 // Disabled due to ASAN failure. http://crbug.com/108320
3014 TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
3015 InitializeEmptyExtensionService();
3016 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3017 theme_crx, GURL(), &IsTheme, false, false));
3018 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3020 base::FilePath path = data_dir().AppendASCII("theme.crx");
3021 UpdateExtension(theme_crx, path, ENABLED);
3023 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3025 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3026 ASSERT_TRUE(extension);
3028 EXPECT_FALSE(
3029 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3030 EXPECT_TRUE(service()->IsExtensionEnabled(theme_crx));
3033 #if defined(OS_CHROMEOS)
3034 // Always fails on ChromeOS: http://crbug.com/79737
3035 #define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
3036 #else
3037 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
3038 #endif
3039 // Test updating a pending CRX as if the source is an external extension
3040 // with an update URL. In this case we don't know if the CRX is a theme
3041 // or not.
3042 TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
3043 InitializeEmptyExtensionService();
3044 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3045 theme_crx,
3046 std::string(),
3047 GURL(),
3048 Manifest::EXTERNAL_PREF_DOWNLOAD,
3049 Extension::NO_FLAGS,
3050 false));
3052 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3054 base::FilePath path = data_dir().AppendASCII("theme.crx");
3055 UpdateExtension(theme_crx, path, ENABLED);
3057 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3059 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3060 ASSERT_TRUE(extension);
3062 EXPECT_FALSE(
3063 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3064 EXPECT_TRUE(service()->IsExtensionEnabled(extension->id()));
3065 EXPECT_FALSE(
3066 extensions::util::IsIncognitoEnabled(extension->id(), profile()));
3069 // Test updating a pending CRX as if the source is an external extension
3070 // with an update URL. The external update should overwrite a sync update,
3071 // but a sync update should not overwrite a non-sync update.
3072 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
3073 InitializeEmptyExtensionService();
3075 // Add a crx to be installed from the update mechanism.
3076 EXPECT_TRUE(
3077 service()->pending_extension_manager()->AddFromSync(
3078 kGoodId,
3079 GURL(kGoodUpdateURL),
3080 &IsExtension,
3081 kGoodRemoteInstall,
3082 kGoodInstalledByCustodian));
3084 // Check that there is a pending crx, with is_from_sync set to true.
3085 const extensions::PendingExtensionInfo* pending_extension_info;
3086 ASSERT_TRUE((pending_extension_info =
3087 service()->pending_extension_manager()->GetById(kGoodId)));
3088 EXPECT_TRUE(pending_extension_info->is_from_sync());
3090 // Add a crx to be updated, with the same ID, from a non-sync source.
3091 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3092 kGoodId,
3093 std::string(),
3094 GURL(kGoodUpdateURL),
3095 Manifest::EXTERNAL_PREF_DOWNLOAD,
3096 Extension::NO_FLAGS,
3097 false));
3099 // Check that there is a pending crx, with is_from_sync set to false.
3100 ASSERT_TRUE((pending_extension_info =
3101 service()->pending_extension_manager()->GetById(kGoodId)));
3102 EXPECT_FALSE(pending_extension_info->is_from_sync());
3103 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3104 pending_extension_info->install_source());
3106 // Add a crx to be installed from the update mechanism.
3107 EXPECT_FALSE(
3108 service()->pending_extension_manager()->AddFromSync(
3109 kGoodId,
3110 GURL(kGoodUpdateURL),
3111 &IsExtension,
3112 kGoodRemoteInstall,
3113 kGoodInstalledByCustodian));
3115 // Check that the external, non-sync update was not overridden.
3116 ASSERT_TRUE((pending_extension_info =
3117 service()->pending_extension_manager()->GetById(kGoodId)));
3118 EXPECT_FALSE(pending_extension_info->is_from_sync());
3119 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3120 pending_extension_info->install_source());
3123 // Updating a theme should fail if the updater is explicitly told that
3124 // the CRX is not a theme.
3125 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
3126 InitializeEmptyExtensionService();
3127 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3128 theme_crx, GURL(), &IsExtension, false, false));
3130 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3132 base::FilePath path = data_dir().AppendASCII("theme.crx");
3133 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
3135 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3137 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3138 ASSERT_FALSE(extension);
3141 // TODO(akalin): Test updating a pending extension non-silently once
3142 // we can mock out ExtensionInstallUI and inject our version into
3143 // UpdateExtension().
3145 // Test updating a pending extension which fails the should-install test.
3146 TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
3147 InitializeEmptyExtensionService();
3148 // Add pending extension with a flipped is_theme.
3149 EXPECT_TRUE(
3150 service()->pending_extension_manager()->AddFromSync(
3151 kGoodId,
3152 GURL(kGoodUpdateURL),
3153 &IsTheme,
3154 kGoodRemoteInstall,
3155 kGoodInstalledByCustodian));
3156 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3158 base::FilePath path = data_dir().AppendASCII("good.crx");
3159 UpdateExtension(kGoodId, path, UPDATED);
3161 // TODO(akalin): Figure out how to check that the extensions
3162 // directory is cleaned up properly in OnExtensionInstalled().
3164 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3167 // TODO(akalin): Figure out how to test that installs of pending
3168 // unsyncable extensions are blocked.
3170 // Test updating a pending extension for one that is not pending.
3171 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
3172 InitializeEmptyExtensionService();
3174 base::FilePath path = data_dir().AppendASCII("good.crx");
3175 UpdateExtension(kGoodId, path, UPDATED);
3177 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3180 // Test updating a pending extension for one that is already
3181 // installed.
3182 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
3183 InitializeEmptyExtensionService();
3185 base::FilePath path = data_dir().AppendASCII("good.crx");
3186 const Extension* good = InstallCRX(path, INSTALL_NEW);
3187 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3189 EXPECT_FALSE(good->is_theme());
3191 // Use AddExtensionImpl() as AddFrom*() would balk.
3192 service()->pending_extension_manager()->AddExtensionImpl(
3193 good->id(),
3194 std::string(),
3195 extensions::ManifestURL::GetUpdateURL(good),
3196 Version(),
3197 &IsExtension,
3198 kGoodIsFromSync,
3199 Manifest::INTERNAL,
3200 Extension::NO_FLAGS,
3201 false,
3202 kGoodRemoteInstall);
3203 UpdateExtension(good->id(), path, ENABLED);
3205 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3208 #if defined(ENABLE_BLACKLIST_TESTS)
3209 // Tests blacklisting then unblacklisting extensions after the service has been
3210 // initialized.
3211 TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
3212 extensions::TestBlacklist test_blacklist;
3213 // A profile with 3 extensions installed: good0, good1, and good2.
3214 InitializeGoodInstalledExtensionService();
3215 test_blacklist.Attach(service()->blacklist_);
3216 service()->Init();
3218 const extensions::ExtensionSet& enabled_extensions =
3219 registry()->enabled_extensions();
3220 const extensions::ExtensionSet& blacklisted_extensions =
3221 registry()->blacklisted_extensions();
3223 EXPECT_TRUE(enabled_extensions.Contains(good0) &&
3224 !blacklisted_extensions.Contains(good0));
3225 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3226 !blacklisted_extensions.Contains(good1));
3227 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3228 !blacklisted_extensions.Contains(good2));
3230 EXPECT_FALSE(IsPrefExist(good0, "blacklist"));
3231 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3232 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3233 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3235 // Blacklist good0 and good1 (and an invalid extension ID).
3236 test_blacklist.SetBlacklistState(
3237 good0, extensions::BLACKLISTED_MALWARE, true);
3238 test_blacklist.SetBlacklistState(
3239 good1, extensions::BLACKLISTED_MALWARE, true);
3240 test_blacklist.SetBlacklistState(
3241 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3242 base::RunLoop().RunUntilIdle();
3244 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3245 blacklisted_extensions.Contains(good0));
3246 EXPECT_TRUE(!enabled_extensions.Contains(good1) &&
3247 blacklisted_extensions.Contains(good1));
3248 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3249 !blacklisted_extensions.Contains(good2));
3251 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3252 EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true));
3253 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3254 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3256 // Un-blacklist good1 and blacklist good2.
3257 test_blacklist.Clear(false);
3258 test_blacklist.SetBlacklistState(
3259 good0, extensions::BLACKLISTED_MALWARE, true);
3260 test_blacklist.SetBlacklistState(
3261 good2, extensions::BLACKLISTED_MALWARE, true);
3262 test_blacklist.SetBlacklistState(
3263 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3264 base::RunLoop().RunUntilIdle();
3266 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3267 blacklisted_extensions.Contains(good0));
3268 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3269 !blacklisted_extensions.Contains(good1));
3270 EXPECT_TRUE(!enabled_extensions.Contains(good2) &&
3271 blacklisted_extensions.Contains(good2));
3273 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3274 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3275 EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true));
3276 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3278 #endif // defined(ENABLE_BLACKLIST_TESTS)
3280 #if defined(ENABLE_BLACKLIST_TESTS)
3281 // Tests trying to install a blacklisted extension.
3282 TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
3283 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3284 new FakeSafeBrowsingDatabaseManager(true));
3285 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3287 InitializeEmptyExtensionService();
3288 service()->Init();
3290 // After blacklisting good_crx, we cannot install it.
3291 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
3292 base::RunLoop().RunUntilIdle();
3294 base::FilePath path = data_dir().AppendASCII("good.crx");
3295 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3296 // decide to install this silently. Somebody should fix these tests, all
3297 // 6,000 lines of them. Hah!
3298 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
3299 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3301 #endif // defined(ENABLE_BLACKLIST_TESTS)
3303 #if defined(ENABLE_BLACKLIST_TESTS)
3304 // Unload blacklisted extension on policy change.
3305 TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
3306 extensions::TestBlacklist test_blacklist;
3308 // A profile with no extensions installed.
3309 InitializeEmptyExtensionServiceWithTestingPrefs();
3310 test_blacklist.Attach(service()->blacklist_);
3312 base::FilePath path = data_dir().AppendASCII("good.crx");
3314 const Extension* good = InstallCRX(path, INSTALL_NEW);
3315 EXPECT_EQ(good_crx, good->id());
3316 UpdateExtension(good_crx, path, FAILED_SILENTLY);
3317 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3320 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3321 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3324 test_blacklist.SetBlacklistState(
3325 good_crx, extensions::BLACKLISTED_MALWARE, true);
3326 base::RunLoop().RunUntilIdle();
3328 // The good_crx is blacklisted and the whitelist doesn't negate it.
3329 ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true));
3330 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3332 #endif // defined(ENABLE_BLACKLIST_TESTS)
3334 #if defined(ENABLE_BLACKLIST_TESTS)
3335 // Tests that a blacklisted extension is eventually unloaded on startup, if it
3336 // wasn't already.
3337 TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
3338 extensions::TestBlacklist test_blacklist;
3340 // A profile with 3 extensions installed: good0, good1, and good2.
3341 InitializeGoodInstalledExtensionService();
3342 test_blacklist.Attach(service()->blacklist_);
3344 // Blacklist good1 before the service initializes.
3345 test_blacklist.SetBlacklistState(
3346 good1, extensions::BLACKLISTED_MALWARE, false);
3348 // Load extensions.
3349 service()->Init();
3350 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet
3352 base::RunLoop().RunUntilIdle();
3354 ASSERT_EQ(1u, registry()->blacklisted_extensions().size());
3355 ASSERT_EQ(2u, registry()->enabled_extensions().size());
3357 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
3358 ASSERT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3359 ASSERT_TRUE(registry()->enabled_extensions().Contains(good2));
3361 #endif // defined(ENABLE_BLACKLIST_TESTS)
3363 #if defined(ENABLE_BLACKLIST_TESTS)
3364 // Tests extensions blacklisted in prefs on startup; one still blacklisted by
3365 // safe browsing, the other not. The not-blacklisted one should recover.
3366 TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) {
3367 extensions::TestBlacklist test_blacklist;
3369 InitializeGoodInstalledExtensionService();
3370 test_blacklist.Attach(service()->blacklist_);
3371 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good0, true);
3372 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good1, true);
3374 test_blacklist.SetBlacklistState(
3375 good1, extensions::BLACKLISTED_MALWARE, false);
3377 // Extension service hasn't loaded yet, but IsExtensionEnabled reads out of
3378 // prefs. Ensure it takes into account the blacklist state (crbug.com/373842).
3379 EXPECT_FALSE(service()->IsExtensionEnabled(good0));
3380 EXPECT_FALSE(service()->IsExtensionEnabled(good1));
3381 EXPECT_TRUE(service()->IsExtensionEnabled(good2));
3383 service()->Init();
3385 EXPECT_EQ(2u, registry()->blacklisted_extensions().size());
3386 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3388 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good0));
3389 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3390 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3392 // Give time for the blacklist to update.
3393 base::RunLoop().RunUntilIdle();
3395 EXPECT_EQ(1u, registry()->blacklisted_extensions().size());
3396 EXPECT_EQ(2u, registry()->enabled_extensions().size());
3398 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3399 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3400 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3402 #endif // defined(ENABLE_BLACKLIST_TESTS)
3404 #if defined(ENABLE_BLACKLIST_TESTS)
3405 // Extension is added to blacklist with BLACKLISTED_POTENTIALLY_UNWANTED state
3406 // after it is installed. It is then successfully re-enabled by the user.
3407 TEST_F(ExtensionServiceTest, GreylistedExtensionDisabled) {
3408 extensions::TestBlacklist test_blacklist;
3409 // A profile with 3 extensions installed: good0, good1, and good2.
3410 InitializeGoodInstalledExtensionService();
3411 test_blacklist.Attach(service()->blacklist_);
3412 service()->Init();
3414 const extensions::ExtensionSet& enabled_extensions =
3415 registry()->enabled_extensions();
3416 const extensions::ExtensionSet& disabled_extensions =
3417 registry()->disabled_extensions();
3419 EXPECT_TRUE(enabled_extensions.Contains(good0));
3420 EXPECT_TRUE(enabled_extensions.Contains(good1));
3421 EXPECT_TRUE(enabled_extensions.Contains(good2));
3423 // Blacklist good0 and good1 (and an invalid extension ID).
3424 test_blacklist.SetBlacklistState(
3425 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3426 test_blacklist.SetBlacklistState(
3427 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3428 test_blacklist.SetBlacklistState(
3429 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3430 base::RunLoop().RunUntilIdle();
3432 EXPECT_FALSE(enabled_extensions.Contains(good0));
3433 EXPECT_TRUE(disabled_extensions.Contains(good0));
3434 EXPECT_FALSE(enabled_extensions.Contains(good1));
3435 EXPECT_TRUE(disabled_extensions.Contains(good1));
3436 EXPECT_TRUE(enabled_extensions.Contains(good2));
3437 EXPECT_FALSE(disabled_extensions.Contains(good2));
3439 ValidateIntegerPref(
3440 good0, "blacklist_state", extensions::BLACKLISTED_CWS_POLICY_VIOLATION);
3441 ValidateIntegerPref(
3442 good1, "blacklist_state", extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
3444 // Now user enables good0.
3445 service()->EnableExtension(good0);
3447 EXPECT_TRUE(enabled_extensions.Contains(good0));
3448 EXPECT_FALSE(disabled_extensions.Contains(good0));
3449 EXPECT_FALSE(enabled_extensions.Contains(good1));
3450 EXPECT_TRUE(disabled_extensions.Contains(good1));
3452 // Remove extensions from blacklist.
3453 test_blacklist.SetBlacklistState(
3454 good0, extensions::NOT_BLACKLISTED, true);
3455 test_blacklist.SetBlacklistState(
3456 good1, extensions::NOT_BLACKLISTED, true);
3457 base::RunLoop().RunUntilIdle();
3459 // All extensions are enabled.
3460 EXPECT_TRUE(enabled_extensions.Contains(good0));
3461 EXPECT_FALSE(disabled_extensions.Contains(good0));
3462 EXPECT_TRUE(enabled_extensions.Contains(good1));
3463 EXPECT_FALSE(disabled_extensions.Contains(good1));
3464 EXPECT_TRUE(enabled_extensions.Contains(good2));
3465 EXPECT_FALSE(disabled_extensions.Contains(good2));
3467 #endif // defined(ENABLE_BLACKLIST_TESTS)
3469 #if defined(ENABLE_BLACKLIST_TESTS)
3470 // When extension is removed from greylist, do not re-enable it if it is
3471 // disabled by user.
3472 TEST_F(ExtensionServiceTest, GreylistDontEnableManuallyDisabled) {
3473 extensions::TestBlacklist test_blacklist;
3474 // A profile with 3 extensions installed: good0, good1, and good2.
3475 InitializeGoodInstalledExtensionService();
3476 test_blacklist.Attach(service()->blacklist_);
3477 service()->Init();
3479 const extensions::ExtensionSet& enabled_extensions =
3480 registry()->enabled_extensions();
3481 const extensions::ExtensionSet& disabled_extensions =
3482 registry()->disabled_extensions();
3484 // Manually disable.
3485 service()->DisableExtension(good0,
3486 extensions::Extension::DISABLE_USER_ACTION);
3488 test_blacklist.SetBlacklistState(
3489 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3490 test_blacklist.SetBlacklistState(
3491 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3492 test_blacklist.SetBlacklistState(
3493 good2, extensions::BLACKLISTED_SECURITY_VULNERABILITY, true);
3494 base::RunLoop().RunUntilIdle();
3496 // All extensions disabled.
3497 EXPECT_FALSE(enabled_extensions.Contains(good0));
3498 EXPECT_TRUE(disabled_extensions.Contains(good0));
3499 EXPECT_FALSE(enabled_extensions.Contains(good1));
3500 EXPECT_TRUE(disabled_extensions.Contains(good1));
3501 EXPECT_FALSE(enabled_extensions.Contains(good2));
3502 EXPECT_TRUE(disabled_extensions.Contains(good2));
3504 // Greylisted extension can be enabled.
3505 service()->EnableExtension(good1);
3506 EXPECT_TRUE(enabled_extensions.Contains(good1));
3507 EXPECT_FALSE(disabled_extensions.Contains(good1));
3509 // good1 is now manually disabled.
3510 service()->DisableExtension(good1,
3511 extensions::Extension::DISABLE_USER_ACTION);
3512 EXPECT_FALSE(enabled_extensions.Contains(good1));
3513 EXPECT_TRUE(disabled_extensions.Contains(good1));
3515 // Remove extensions from blacklist.
3516 test_blacklist.SetBlacklistState(
3517 good0, extensions::NOT_BLACKLISTED, true);
3518 test_blacklist.SetBlacklistState(
3519 good1, extensions::NOT_BLACKLISTED, true);
3520 test_blacklist.SetBlacklistState(
3521 good2, extensions::NOT_BLACKLISTED, true);
3522 base::RunLoop().RunUntilIdle();
3524 // good0 and good1 remain disabled.
3525 EXPECT_FALSE(enabled_extensions.Contains(good0));
3526 EXPECT_TRUE(disabled_extensions.Contains(good0));
3527 EXPECT_FALSE(enabled_extensions.Contains(good1));
3528 EXPECT_TRUE(disabled_extensions.Contains(good1));
3529 EXPECT_TRUE(enabled_extensions.Contains(good2));
3530 EXPECT_FALSE(disabled_extensions.Contains(good2));
3532 #endif // defined(ENABLE_BLACKLIST_TESTS)
3534 #if defined(ENABLE_BLACKLIST_TESTS)
3535 // Blacklisted extension with unknown state are not enabled/disabled.
3536 TEST_F(ExtensionServiceTest, GreylistUnknownDontChange) {
3537 extensions::TestBlacklist test_blacklist;
3538 // A profile with 3 extensions installed: good0, good1, and good2.
3539 InitializeGoodInstalledExtensionService();
3540 test_blacklist.Attach(service()->blacklist_);
3541 service()->Init();
3543 const extensions::ExtensionSet& enabled_extensions =
3544 registry()->enabled_extensions();
3545 const extensions::ExtensionSet& disabled_extensions =
3546 registry()->disabled_extensions();
3548 test_blacklist.SetBlacklistState(
3549 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3550 test_blacklist.SetBlacklistState(
3551 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3552 base::RunLoop().RunUntilIdle();
3554 EXPECT_FALSE(enabled_extensions.Contains(good0));
3555 EXPECT_TRUE(disabled_extensions.Contains(good0));
3556 EXPECT_FALSE(enabled_extensions.Contains(good1));
3557 EXPECT_TRUE(disabled_extensions.Contains(good1));
3558 EXPECT_TRUE(enabled_extensions.Contains(good2));
3559 EXPECT_FALSE(disabled_extensions.Contains(good2));
3561 test_blacklist.SetBlacklistState(
3562 good0, extensions::NOT_BLACKLISTED, true);
3563 test_blacklist.SetBlacklistState(
3564 good1, extensions::BLACKLISTED_UNKNOWN, true);
3565 test_blacklist.SetBlacklistState(
3566 good2, extensions::BLACKLISTED_UNKNOWN, true);
3567 base::RunLoop().RunUntilIdle();
3569 // good0 re-enabled, other remain as they were.
3570 EXPECT_TRUE(enabled_extensions.Contains(good0));
3571 EXPECT_FALSE(disabled_extensions.Contains(good0));
3572 EXPECT_FALSE(enabled_extensions.Contains(good1));
3573 EXPECT_TRUE(disabled_extensions.Contains(good1));
3574 EXPECT_TRUE(enabled_extensions.Contains(good2));
3575 EXPECT_FALSE(disabled_extensions.Contains(good2));
3578 // Tests that blacklisted extensions cannot be reloaded, both those loaded
3579 // before and after extension service startup.
3580 TEST_F(ExtensionServiceTest, ReloadBlacklistedExtension) {
3581 extensions::TestBlacklist test_blacklist;
3583 InitializeGoodInstalledExtensionService();
3584 test_blacklist.Attach(service()->blacklist_);
3586 test_blacklist.SetBlacklistState(
3587 good1, extensions::BLACKLISTED_MALWARE, false);
3588 service()->Init();
3589 test_blacklist.SetBlacklistState(
3590 good2, extensions::BLACKLISTED_MALWARE, false);
3591 base::RunLoop().RunUntilIdle();
3593 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3594 EXPECT_EQ(StringSet(good1, good2),
3595 registry()->blacklisted_extensions().GetIDs());
3597 service()->ReloadExtension(good1);
3598 service()->ReloadExtension(good2);
3599 base::RunLoop().RunUntilIdle();
3601 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3602 EXPECT_EQ(StringSet(good1, good2),
3603 registry()->blacklisted_extensions().GetIDs());
3605 #endif // defined(ENABLE_BLACKLIST_TESTS)
3607 // Tests blocking then unblocking enabled extensions after the service has been
3608 // initialized.
3609 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledExtension) {
3610 InitializeGoodInstalledExtensionService();
3611 service()->Init();
3613 AssertExtensionBlocksAndUnblocks(true, good0);
3616 // Tests blocking then unblocking disabled extensions after the service has been
3617 // initialized.
3618 TEST_F(ExtensionServiceTest, BlockAndUnblockDisabledExtension) {
3619 InitializeGoodInstalledExtensionService();
3620 service()->Init();
3622 service()->DisableExtension(good0, Extension::DISABLE_RELOAD);
3624 AssertExtensionBlocksAndUnblocks(true, good0);
3627 // Tests blocking then unblocking terminated extensions after the service has
3628 // been initialized.
3629 TEST_F(ExtensionServiceTest, BlockAndUnblockTerminatedExtension) {
3630 InitializeGoodInstalledExtensionService();
3631 service()->Init();
3633 TerminateExtension(good0);
3635 AssertExtensionBlocksAndUnblocks(true, good0);
3638 // Tests blocking then unblocking policy-forced extensions after the service has
3639 // been initialized.
3640 TEST_F(ExtensionServiceTest, BlockAndUnblockPolicyExtension) {
3641 InitializeEmptyExtensionServiceWithTestingPrefs();
3644 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3645 // // Blacklist everything.
3646 // pref.SetBlacklistedByDefault(true);
3647 // Mark good.crx for force-installation.
3648 pref.SetIndividualExtensionAutoInstalled(
3649 good_crx, "http://example.com/update_url", true);
3652 // Have policy force-install an extension.
3653 MockExtensionProvider* provider =
3654 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3655 AddMockExternalProvider(provider);
3656 provider->UpdateOrAddExtension(
3657 good_crx, "1.0.0.0", data_dir().AppendASCII("good_crx"));
3659 // Reloading extensions should find our externally registered extension
3660 // and install it.
3661 content::WindowedNotificationObserver observer(
3662 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3663 content::NotificationService::AllSources());
3664 service()->CheckForExternalUpdates();
3665 observer.Wait();
3667 AssertExtensionBlocksAndUnblocks(false, good_crx);
3671 #if defined(ENABLE_BLACKLIST_TESTS)
3672 // Tests blocking then unblocking extensions that are blacklisted both before
3673 // and after Init().
3674 TEST_F(ExtensionServiceTest, BlockAndUnblockBlacklistedExtension) {
3675 extensions::TestBlacklist test_blacklist;
3677 InitializeGoodInstalledExtensionService();
3678 test_blacklist.Attach(service()->blacklist_);
3680 test_blacklist.SetBlacklistState(
3681 good0, extensions::BLACKLISTED_MALWARE, true);
3682 base::RunLoop().RunUntilIdle();
3684 service()->Init();
3686 test_blacklist.SetBlacklistState(
3687 good1, extensions::BLACKLISTED_MALWARE, true);
3688 base::RunLoop().RunUntilIdle();
3690 // Blacklisted extensions stay blacklisted.
3691 AssertExtensionBlocksAndUnblocks(false, good0);
3692 AssertExtensionBlocksAndUnblocks(false, good1);
3694 service()->BlockAllExtensions();
3696 // Remove an extension from the blacklist while the service is blocked.
3697 test_blacklist.SetBlacklistState(
3698 good0, extensions::NOT_BLACKLISTED, true);
3699 // Add an extension to the blacklist while the service is blocked.
3700 test_blacklist.SetBlacklistState(
3701 good2, extensions::BLACKLISTED_MALWARE, true);
3702 base::RunLoop().RunUntilIdle();
3704 // Go directly to blocked, do not pass go, do not collect $200.
3705 ASSERT_TRUE(IsBlocked(good0));
3706 // Get on the blacklist - even if you were blocked!
3707 ASSERT_FALSE(IsBlocked(good2));
3709 #endif // defined(ENABLE_BLACKLIST_TESTS)
3711 // Tests blocking then unblocking enabled component extensions after the service
3712 // has been initialized.
3713 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledComponentExtension) {
3714 InitializeEmptyExtensionServiceWithTestingPrefs();
3716 // Install a component extension.
3717 base::FilePath path = data_dir()
3718 .AppendASCII("good")
3719 .AppendASCII("Extensions")
3720 .AppendASCII(good0)
3721 .AppendASCII("1.0.0.0");
3722 std::string manifest;
3723 ASSERT_TRUE(base::ReadFileToString(
3724 path.Append(extensions::kManifestFilename), &manifest));
3725 service()->component_loader()->Add(manifest, path);
3726 service()->Init();
3728 // Component extension should never block.
3729 AssertExtensionBlocksAndUnblocks(false, good0);
3732 // Tests blocking then unblocking a theme after the service has been
3733 // initialized.
3734 TEST_F(ExtensionServiceTest, BlockAndUnblockTheme) {
3735 InitializeEmptyExtensionService();
3736 service()->Init();
3738 base::FilePath path = data_dir().AppendASCII("theme.crx");
3739 InstallCRX(path, INSTALL_NEW);
3741 AssertExtensionBlocksAndUnblocks(true, theme_crx);
3744 // Tests that blocking extensions before Init() results in loading blocked
3745 // extensions.
3746 TEST_F(ExtensionServiceTest, WillNotLoadExtensionsWhenBlocked) {
3747 InitializeGoodInstalledExtensionService();
3749 service()->BlockAllExtensions();
3751 service()->Init();
3753 ASSERT_TRUE(IsBlocked(good0));
3754 ASSERT_TRUE(IsBlocked(good0));
3755 ASSERT_TRUE(IsBlocked(good0));
3758 // Tests that IsEnabledExtension won't crash on an uninstalled extension.
3759 TEST_F(ExtensionServiceTest, IsEnabledExtensionBlockedAndNotInstalled) {
3760 InitializeEmptyExtensionService();
3762 service()->BlockAllExtensions();
3764 service()->IsExtensionEnabled(theme_crx);
3767 // Will not install extension blacklisted by policy.
3768 TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
3769 InitializeEmptyExtensionServiceWithTestingPrefs();
3771 // Blacklist everything.
3773 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3774 pref.SetBlacklistedByDefault(true);
3777 // Blacklist prevents us from installing good_crx.
3778 base::FilePath path = data_dir().AppendASCII("good.crx");
3779 InstallCRX(path, INSTALL_FAILED);
3780 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3782 // Now whitelist this particular extension.
3784 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3785 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3788 // Ensure we can now install good_crx.
3789 InstallCRX(path, INSTALL_NEW);
3790 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3793 // Extension blacklisted by policy get unloaded after installing.
3794 TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
3795 InitializeEmptyExtensionServiceWithTestingPrefs();
3797 // Install good_crx.
3798 base::FilePath path = data_dir().AppendASCII("good.crx");
3799 InstallCRX(path, INSTALL_NEW);
3800 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3803 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3804 // Blacklist this extension.
3805 pref.SetIndividualExtensionInstallationAllowed(good_crx, false);
3808 // Extension should not be running now.
3809 base::RunLoop().RunUntilIdle();
3810 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3813 // Tests that component extensions are not blacklisted by policy.
3814 TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
3815 InitializeEmptyExtensionServiceWithTestingPrefs();
3817 // Blacklist everything.
3819 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3820 pref.SetBlacklistedByDefault(true);
3823 // Install a component extension.
3824 base::FilePath path = data_dir()
3825 .AppendASCII("good")
3826 .AppendASCII("Extensions")
3827 .AppendASCII(good0)
3828 .AppendASCII("1.0.0.0");
3829 std::string manifest;
3830 ASSERT_TRUE(base::ReadFileToString(
3831 path.Append(extensions::kManifestFilename), &manifest));
3832 service()->component_loader()->Add(manifest, path);
3833 service()->Init();
3835 // Extension should be installed despite blacklist.
3836 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3837 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3839 // Poke external providers and make sure the extension is still present.
3840 service()->CheckForExternalUpdates();
3841 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3842 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3844 // Extension should not be uninstalled on blacklist changes.
3846 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3847 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3849 base::RunLoop().RunUntilIdle();
3850 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3851 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3854 // Tests that policy-installed extensions are not blacklisted by policy.
3855 TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
3856 InitializeEmptyExtensionServiceWithTestingPrefs();
3859 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3860 // Blacklist everything.
3861 pref.SetBlacklistedByDefault(true);
3862 // Mark good.crx for force-installation.
3863 pref.SetIndividualExtensionAutoInstalled(
3864 good_crx, "http://example.com/update_url", true);
3867 // Have policy force-install an extension.
3868 MockExtensionProvider* provider =
3869 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3870 AddMockExternalProvider(provider);
3871 provider->UpdateOrAddExtension(
3872 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
3874 // Reloading extensions should find our externally registered extension
3875 // and install it.
3876 content::WindowedNotificationObserver observer(
3877 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3878 content::NotificationService::AllSources());
3879 service()->CheckForExternalUpdates();
3880 observer.Wait();
3882 // Extension should be installed despite blacklist.
3883 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3884 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3886 // Blacklist update should not uninstall the extension.
3888 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3889 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3891 base::RunLoop().RunUntilIdle();
3892 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3893 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3896 // Tests that extensions cannot be installed if the policy provider prohibits
3897 // it. This functionality is implemented in CrxInstaller::ConfirmInstall().
3898 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
3899 InitializeEmptyExtensionService();
3901 GetManagementPolicy()->UnregisterAllProviders();
3902 extensions::TestManagementPolicyProvider provider_(
3903 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3904 GetManagementPolicy()->RegisterProvider(&provider_);
3906 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_FAILED);
3907 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3910 // Tests that extensions cannot be loaded from prefs if the policy provider
3911 // prohibits it. This functionality is implemented in InstalledLoader::Load().
3912 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
3913 InitializeEmptyExtensionService();
3915 // Create a fake extension to be loaded as though it were read from prefs.
3916 base::FilePath path =
3917 data_dir().AppendASCII("management").AppendASCII("simple_extension");
3918 base::DictionaryValue manifest;
3919 manifest.SetString(keys::kName, "simple_extension");
3920 manifest.SetString(keys::kVersion, "1");
3921 // UNPACKED is for extensions loaded from a directory. We use it here, even
3922 // though we're testing loading from prefs, so that we don't need to provide
3923 // an extension key.
3924 extensions::ExtensionInfo extension_info(
3925 &manifest, std::string(), path, Manifest::UNPACKED);
3927 // Ensure we can load it with no management policy in place.
3928 GetManagementPolicy()->UnregisterAllProviders();
3929 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3930 extensions::InstalledLoader(service()).Load(extension_info, false);
3931 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3933 const Extension* extension =
3934 (registry()->enabled_extensions().begin())->get();
3935 EXPECT_TRUE(
3936 service()->UninstallExtension(extension->id(),
3937 extensions::UNINSTALL_REASON_FOR_TESTING,
3938 base::Bind(&base::DoNothing),
3939 NULL));
3940 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3942 // Ensure we cannot load it if management policy prohibits installation.
3943 extensions::TestManagementPolicyProvider provider_(
3944 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3945 GetManagementPolicy()->RegisterProvider(&provider_);
3947 extensions::InstalledLoader(service()).Load(extension_info, false);
3948 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3951 // Tests disabling an extension when prohibited by the ManagementPolicy.
3952 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
3953 InitializeEmptyExtensionService();
3955 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3956 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3957 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3959 GetManagementPolicy()->UnregisterAllProviders();
3960 extensions::TestManagementPolicyProvider provider(
3961 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3962 GetManagementPolicy()->RegisterProvider(&provider);
3964 // Attempt to disable it.
3965 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3967 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3968 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3969 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3972 // Tests uninstalling an extension when prohibited by the ManagementPolicy.
3973 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
3974 InitializeEmptyExtensionService();
3976 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3977 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3978 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3980 GetManagementPolicy()->UnregisterAllProviders();
3981 extensions::TestManagementPolicyProvider provider(
3982 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3983 GetManagementPolicy()->RegisterProvider(&provider);
3985 // Attempt to uninstall it.
3986 EXPECT_FALSE(
3987 service()->UninstallExtension(good_crx,
3988 extensions::UNINSTALL_REASON_FOR_TESTING,
3989 base::Bind(&base::DoNothing),
3990 NULL));
3992 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3993 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3996 // Tests that previously installed extensions that are now prohibited from
3997 // being installed are removed.
3998 TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
3999 InitializeEmptyExtensionService();
4001 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4002 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
4003 EXPECT_EQ(2u, registry()->enabled_extensions().size());
4004 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4006 GetManagementPolicy()->UnregisterAllProviders();
4007 extensions::TestManagementPolicyProvider provider(
4008 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
4009 GetManagementPolicy()->RegisterProvider(&provider);
4011 // Run the policy check.
4012 service()->CheckManagementPolicy();
4013 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4014 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4017 // Tests that previously disabled extensions that are now required to be
4018 // enabled are re-enabled on reinstall.
4019 TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
4020 InitializeEmptyExtensionService();
4022 // Install, then disable, an extension.
4023 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4024 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4025 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4026 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4028 // Register an ExtensionManagementPolicy that requires the extension to remain
4029 // enabled.
4030 GetManagementPolicy()->UnregisterAllProviders();
4031 extensions::TestManagementPolicyProvider provider(
4032 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
4033 GetManagementPolicy()->RegisterProvider(&provider);
4035 // Reinstall the extension.
4036 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_UPDATED);
4037 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4038 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4041 // Tests that extensions disabled by management policy can be installed but
4042 // will get disabled after installing.
4043 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsEnableOnInstalled) {
4044 InitializeEmptyExtensionService();
4046 // Register an ExtensionManagementPolicy that disables all extensions, with
4047 // a specified Extension::DisableReason.
4048 GetManagementPolicy()->UnregisterAllProviders();
4049 extensions::TestManagementPolicyProvider provider(
4050 extensions::TestManagementPolicyProvider::MUST_REMAIN_DISABLED);
4051 provider.SetDisableReason(Extension::DISABLE_NOT_VERIFIED);
4052 GetManagementPolicy()->RegisterProvider(&provider);
4054 // Attempts to install an extensions, it should be installed but disabled.
4055 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4056 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4057 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_WITHOUT_LOAD);
4058 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4059 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4061 // Verifies that the disable reason is set properly.
4062 EXPECT_EQ(Extension::DISABLE_NOT_VERIFIED,
4063 service()->extension_prefs_->GetDisableReasons(kGoodId));
4066 // Tests that extensions with conflicting required permissions by enterprise
4067 // policy cannot be installed.
4068 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionNewExtensionInstall) {
4069 InitializeEmptyExtensionServiceWithTestingPrefs();
4070 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4073 // Update policy to block one of the required permissions of target.
4074 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4075 pref.AddBlockedPermission("*", "tabs");
4078 // The extension should be failed to install.
4079 PackAndInstallCRX(path, INSTALL_FAILED);
4082 // Update policy to block one of the optional permissions instead.
4083 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4084 pref.ClearBlockedPermissions("*");
4085 pref.AddBlockedPermission("*", "history");
4088 // The extension should succeed to install this time.
4089 std::string id = PackAndInstallCRX(path, INSTALL_NEW)->id();
4091 // Uninstall the extension and update policy to block some arbitrary
4092 // unknown permission.
4093 UninstallExtension(id, false);
4095 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4096 pref.ClearBlockedPermissions("*");
4097 pref.AddBlockedPermission("*", "unknown.permission.for.testing");
4100 // The extension should succeed to install as well.
4101 PackAndInstallCRX(path, INSTALL_NEW);
4104 // Tests that extension supposed to be force installed but with conflicting
4105 // required permissions cannot be installed.
4106 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionConflictsWithForceInstall) {
4107 InitializeEmptyExtensionServiceWithTestingPrefs();
4109 // Pack the crx file.
4110 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4111 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4112 base::ScopedTempDir temp_dir;
4113 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4114 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
4116 PackCRX(path, pem_path, crx_path);
4119 // Block one of the required permissions.
4120 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4121 pref.AddBlockedPermission("*", "tabs");
4124 // Use MockExtensionProvider to simulate force installing extension.
4125 MockExtensionProvider* provider =
4126 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4127 AddMockExternalProvider(provider);
4128 provider->UpdateOrAddExtension(permissions_blocklist, "1.0", crx_path);
4131 // Attempts to force install this extension.
4132 content::WindowedNotificationObserver observer(
4133 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4134 content::NotificationService::AllSources());
4135 service()->CheckForExternalUpdates();
4136 observer.Wait();
4139 // The extension should not be installed.
4140 ASSERT_FALSE(service()->GetInstalledExtension(permissions_blocklist));
4142 // Remove this extension from pending extension manager as we would like to
4143 // give another attempt later.
4144 service()->pending_extension_manager()->Remove(permissions_blocklist);
4147 // Clears the permission block list.
4148 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4149 pref.ClearBlockedPermissions("*");
4153 // Attempts to force install this extension again.
4154 content::WindowedNotificationObserver observer(
4155 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4156 content::NotificationService::AllSources());
4157 service()->CheckForExternalUpdates();
4158 observer.Wait();
4161 const Extension* installed =
4162 service()->GetInstalledExtension(permissions_blocklist);
4163 ASSERT_TRUE(installed);
4164 EXPECT_EQ(installed->location(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4167 // Tests that newer versions of an extension with conflicting required
4168 // permissions by enterprise policy cannot be updated to.
4169 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionExtensionUpdate) {
4170 InitializeEmptyExtensionServiceWithTestingPrefs();
4172 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4173 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4174 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4176 // Install 'permissions_blocklist'.
4177 const Extension* installed = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
4178 EXPECT_EQ(installed->id(), permissions_blocklist);
4181 // Block one of the required permissions of 'permissions_blocklist2'.
4182 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4183 pref.AddBlockedPermission("*", "downloads");
4186 // Install 'permissions_blocklist' again, should be updated.
4187 const Extension* updated = PackAndInstallCRX(path, pem_path, INSTALL_UPDATED);
4188 EXPECT_EQ(updated->id(), permissions_blocklist);
4190 std::string old_version = updated->VersionString();
4192 // Attempts to update to 'permissions_blocklist2' should fail.
4193 PackAndInstallCRX(path2, pem_path, INSTALL_FAILED);
4195 // Verify that the old version is still enabled.
4196 updated = service()->GetExtensionById(permissions_blocklist, false);
4197 ASSERT_TRUE(updated);
4198 EXPECT_EQ(old_version, updated->VersionString());
4201 // Tests that policy update with additional permissions blocked revoke
4202 // conflicting granted optional permissions and unload extensions with
4203 // conflicting required permissions, including the force installed ones.
4204 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionPolicyUpdate) {
4205 InitializeEmptyExtensionServiceWithTestingPrefs();
4207 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4208 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4209 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4211 // Pack the crx file.
4212 base::ScopedTempDir temp_dir;
4213 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4214 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
4216 PackCRX(path2, pem_path, crx_path);
4218 // Install two arbitary extensions with specified manifest.
4219 std::string ext1 = PackAndInstallCRX(path, INSTALL_NEW)->id();
4220 std::string ext2 = PackAndInstallCRX(path2, INSTALL_NEW)->id();
4221 ASSERT_NE(ext1, permissions_blocklist);
4222 ASSERT_NE(ext2, permissions_blocklist);
4223 ASSERT_NE(ext1, ext2);
4225 // Force install another extension with known id and same manifest as 'ext2'.
4226 std::string ext2_forced = permissions_blocklist;
4227 MockExtensionProvider* provider =
4228 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4229 AddMockExternalProvider(provider);
4230 provider->UpdateOrAddExtension(ext2_forced, "2.0", crx_path);
4232 content::WindowedNotificationObserver observer(
4233 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4234 content::NotificationService::AllSources());
4235 service()->CheckForExternalUpdates();
4236 observer.Wait();
4238 extensions::ExtensionRegistry* registry =
4239 extensions::ExtensionRegistry::Get(profile());
4241 // Verify all three extensions are installed and enabled.
4242 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext1));
4243 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2));
4244 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2_forced));
4246 // Grant all optional permissions to each extension.
4247 GrantAllOptionalPermissions(ext1);
4248 GrantAllOptionalPermissions(ext2);
4249 GrantAllOptionalPermissions(ext2_forced);
4251 scoped_refptr<const PermissionSet> active_permissions(
4252 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1));
4253 EXPECT_TRUE(active_permissions->HasAPIPermission(
4254 extensions::APIPermission::kDownloads));
4256 // Set policy to block 'downloads' permission.
4258 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4259 pref.AddBlockedPermission("*", "downloads");
4262 base::RunLoop().RunUntilIdle();
4264 // 'ext1' should still be enabled, but with 'downloads' permission revoked.
4265 EXPECT_TRUE(registry->enabled_extensions().GetByID(ext1));
4266 active_permissions =
4267 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1);
4268 EXPECT_FALSE(active_permissions->HasAPIPermission(
4269 extensions::APIPermission::kDownloads));
4271 // 'ext2' should be disabled because one of its required permissions is
4272 // blocked.
4273 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2));
4275 // 'ext2_forced' should be handled the same as 'ext2'
4276 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2_forced));
4279 // Flaky on windows; http://crbug.com/309833
4280 #if defined(OS_WIN)
4281 #define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
4282 #else
4283 #define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
4284 #endif
4285 TEST_F(ExtensionServiceTest, MAYBE_ExternalExtensionAutoAcknowledgement) {
4286 InitializeEmptyExtensionService();
4287 service()->set_extensions_enabled(true);
4290 // Register and install an external extension.
4291 MockExtensionProvider* provider =
4292 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
4293 AddMockExternalProvider(provider);
4294 provider->UpdateOrAddExtension(
4295 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
4298 // Have policy force-install an extension.
4299 MockExtensionProvider* provider = new MockExtensionProvider(
4300 service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4301 AddMockExternalProvider(provider);
4302 provider->UpdateOrAddExtension(
4303 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
4306 // Providers are set up. Let them run.
4307 int count = 2;
4308 content::WindowedNotificationObserver observer(
4309 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4310 base::Bind(&WaitForCountNotificationsCallback, &count));
4311 service()->CheckForExternalUpdates();
4313 observer.Wait();
4315 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4316 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4317 EXPECT_TRUE(service()->GetExtensionById(page_action, false));
4318 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4319 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
4320 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
4323 #if !defined(OS_CHROMEOS)
4324 // This tests if default apps are installed correctly.
4325 TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
4326 InitializeEmptyExtensionService();
4327 service()->set_extensions_enabled(true);
4330 std::string json_data =
4332 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
4333 " \"external_crx\": \"good.crx\","
4334 " \"external_version\": \"1.0.0.0\","
4335 " \"is_bookmark_app\": false"
4336 " }"
4337 "}";
4338 default_apps::Provider* provider = new default_apps::Provider(
4339 profile(),
4340 service(),
4341 new extensions::ExternalTestingLoader(json_data, data_dir()),
4342 Manifest::INTERNAL,
4343 Manifest::INVALID_LOCATION,
4344 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4346 AddMockExternalProvider(provider);
4349 ASSERT_EQ(0u, registry()->enabled_extensions().size());
4350 content::WindowedNotificationObserver observer(
4351 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4352 content::NotificationService::AllSources());
4353 service()->CheckForExternalUpdates();
4354 observer.Wait();
4356 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4357 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4358 const Extension* extension = service()->GetExtensionById(good_crx, false);
4359 EXPECT_TRUE(extension->from_webstore());
4360 EXPECT_TRUE(extension->was_installed_by_default());
4362 #endif
4364 // Tests disabling extensions
4365 TEST_F(ExtensionServiceTest, DisableExtension) {
4366 InitializeEmptyExtensionService();
4368 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4369 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4370 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4372 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4373 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4374 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4375 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4377 // Disable it.
4378 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4380 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4381 EXPECT_FALSE(service()->GetExtensionById(good_crx, false));
4382 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4383 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4384 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4385 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4388 TEST_F(ExtensionServiceTest, TerminateExtension) {
4389 InitializeEmptyExtensionService();
4391 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4392 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4393 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4394 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4395 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4397 TerminateExtension(good_crx);
4399 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4400 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4401 EXPECT_EQ(1u, registry()->terminated_extensions().size());
4402 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4405 TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
4406 InitializeEmptyExtensionService();
4408 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4409 TerminateExtension(good_crx);
4410 EXPECT_TRUE(registry()->GetExtensionById(
4411 good_crx, extensions::ExtensionRegistry::TERMINATED));
4413 // Disable it.
4414 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4416 EXPECT_FALSE(registry()->GetExtensionById(
4417 good_crx, extensions::ExtensionRegistry::TERMINATED));
4418 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4420 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4421 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4422 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4423 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4426 // Tests disabling all extensions (simulating --disable-extensions flag).
4427 TEST_F(ExtensionServiceTest, DisableAllExtensions) {
4428 InitializeEmptyExtensionService();
4430 base::FilePath path = data_dir().AppendASCII("good.crx");
4431 InstallCRX(path, INSTALL_NEW);
4433 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4434 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4436 // Disable extensions.
4437 service()->set_extensions_enabled(false);
4438 service()->ReloadExtensionsForTest();
4440 // There shouldn't be extensions in either list.
4441 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4442 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4444 // This shouldn't do anything when all extensions are disabled.
4445 service()->EnableExtension(good_crx);
4446 service()->ReloadExtensionsForTest();
4448 // There still shouldn't be extensions in either list.
4449 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4450 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4452 // And then re-enable the extensions.
4453 service()->set_extensions_enabled(true);
4454 service()->ReloadExtensionsForTest();
4456 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4457 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4460 // Tests reloading extensions.
4461 TEST_F(ExtensionServiceTest, ReloadExtensions) {
4462 InitializeEmptyExtensionService();
4464 // Simple extension that should install without error.
4465 base::FilePath path = data_dir().AppendASCII("good.crx");
4466 InstallCRX(path, INSTALL_NEW,
4467 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4468 const char* const extension_id = good_crx;
4469 service()->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
4471 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4472 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4474 service()->ReloadExtensionsForTest();
4476 // The creation flags should not change when reloading the extension.
4477 const Extension* extension = service()->GetExtensionById(good_crx, true);
4478 EXPECT_TRUE(extension->from_webstore());
4479 EXPECT_TRUE(extension->was_installed_by_default());
4480 EXPECT_FALSE(extension->from_bookmark());
4482 // Extension counts shouldn't change.
4483 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4484 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4486 service()->EnableExtension(extension_id);
4488 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4489 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4491 // Need to clear |loaded_| manually before reloading as the
4492 // EnableExtension() call above inserted into it and
4493 // UnloadAllExtensions() doesn't send out notifications.
4494 loaded_.clear();
4495 service()->ReloadExtensionsForTest();
4497 // Extension counts shouldn't change.
4498 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4499 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4502 // Tests reloading an extension.
4503 TEST_F(ExtensionServiceTest, ReloadExtension) {
4504 InitializeEmptyExtensionService();
4506 // Simple extension that should install without error.
4507 const char extension_id[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
4508 base::FilePath ext = data_dir()
4509 .AppendASCII("good")
4510 .AppendASCII("Extensions")
4511 .AppendASCII(extension_id)
4512 .AppendASCII("1.0.0.0");
4513 extensions::UnpackedInstaller::Create(service())->Load(ext);
4514 base::RunLoop().RunUntilIdle();
4516 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4517 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4519 service()->ReloadExtension(extension_id);
4521 // Extension should be disabled now, waiting to be reloaded.
4522 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4523 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4524 EXPECT_EQ(Extension::DISABLE_RELOAD,
4525 ExtensionPrefs::Get(profile())->GetDisableReasons(extension_id));
4527 // Reloading again should not crash.
4528 service()->ReloadExtension(extension_id);
4530 // Finish reloading
4531 base::RunLoop().RunUntilIdle();
4533 // Extension should be enabled again.
4534 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4535 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4538 TEST_F(ExtensionServiceTest, UninstallExtension) {
4539 InitializeEmptyExtensionService();
4540 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4541 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4542 UninstallExtension(good_crx, false);
4543 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4544 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4547 TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
4548 InitializeEmptyExtensionService();
4549 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4550 TerminateExtension(good_crx);
4551 UninstallExtension(good_crx, false);
4552 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4555 // Tests the uninstaller helper.
4556 TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
4557 InitializeEmptyExtensionService();
4558 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4559 UninstallExtension(good_crx, true);
4560 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4563 TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
4564 InitializeEmptyExtensionService();
4565 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4566 TerminateExtension(good_crx);
4567 UninstallExtension(good_crx, true);
4568 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4571 // An extension disabled because of unsupported requirements should re-enabled
4572 // if updated to a version with supported requirements as long as there are no
4573 // other disable reasons.
4574 TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
4575 InitializeEmptyExtensionService();
4576 BlackListWebGL();
4578 base::FilePath path = data_dir().AppendASCII("requirements");
4579 base::FilePath pem_path =
4580 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4581 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4582 pem_path,
4583 INSTALL_NEW);
4584 std::string id = extension_v1->id();
4585 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4587 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4589 PackCRX(path.AppendASCII("v2_bad_requirements"),
4590 pem_path,
4591 v2_bad_requirements_crx);
4592 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4593 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4595 base::FilePath v3_good_crx = GetTemporaryFile();
4597 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4598 UpdateExtension(id, v3_good_crx, ENABLED);
4599 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4602 // Extensions disabled through user action should stay disabled.
4603 TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
4604 InitializeEmptyExtensionService();
4605 BlackListWebGL();
4607 base::FilePath path = data_dir().AppendASCII("requirements");
4608 base::FilePath pem_path =
4609 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4610 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4611 pem_path,
4612 INSTALL_NEW);
4613 std::string id = extension_v1->id();
4614 service()->DisableExtension(id, Extension::DISABLE_USER_ACTION);
4615 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4617 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4619 PackCRX(path.AppendASCII("v2_bad_requirements"),
4620 pem_path,
4621 v2_bad_requirements_crx);
4622 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4623 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4625 base::FilePath v3_good_crx = GetTemporaryFile();
4627 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4628 UpdateExtension(id, v3_good_crx, INSTALLED);
4629 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4632 // The extension should not re-enabled because it was disabled from a
4633 // permission increase.
4634 TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
4635 InitializeEmptyExtensionService();
4636 BlackListWebGL();
4638 base::FilePath path = data_dir().AppendASCII("requirements");
4639 base::FilePath pem_path =
4640 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4641 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4642 pem_path,
4643 INSTALL_NEW);
4644 std::string id = extension_v1->id();
4645 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4647 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
4649 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
4650 pem_path,
4651 v2_bad_requirements_and_permissions_crx);
4652 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
4653 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4655 base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
4657 PackCRX(path.AppendASCII("v3_bad_permissions"),
4658 pem_path,
4659 v3_bad_permissions_crx);
4660 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
4661 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4664 // Unpacked extensions are not allowed to be installed if they have unsupported
4665 // requirements.
4666 TEST_F(ExtensionServiceTest, UnpackedRequirements) {
4667 InitializeEmptyExtensionService();
4668 BlackListWebGL();
4670 base::FilePath path =
4671 data_dir().AppendASCII("requirements").AppendASCII("v2_bad_requirements");
4672 extensions::UnpackedInstaller::Create(service())->Load(path);
4673 base::RunLoop().RunUntilIdle();
4674 EXPECT_EQ(1u, GetErrors().size());
4675 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4678 class ExtensionCookieCallback {
4679 public:
4680 ExtensionCookieCallback()
4681 : result_(false),
4682 weak_factory_(base::MessageLoop::current()) {}
4684 void SetCookieCallback(bool result) {
4685 base::ThreadTaskRunnerHandle::Get()->PostTask(
4686 FROM_HERE,
4687 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4688 result_ = result;
4691 void GetAllCookiesCallback(const net::CookieList& list) {
4692 base::ThreadTaskRunnerHandle::Get()->PostTask(
4693 FROM_HERE,
4694 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4695 list_ = list;
4697 net::CookieList list_;
4698 bool result_;
4699 base::WeakPtrFactory<base::MessageLoop> weak_factory_;
4702 // Verifies extension state is removed upon uninstall.
4703 TEST_F(ExtensionServiceTest, ClearExtensionData) {
4704 InitializeEmptyExtensionService();
4705 ExtensionCookieCallback callback;
4707 // Load a test extension.
4708 base::FilePath path = data_dir();
4709 path = path.AppendASCII("good.crx");
4710 const Extension* extension = InstallCRX(path, INSTALL_NEW);
4711 ASSERT_TRUE(extension);
4712 GURL ext_url(extension->url());
4713 std::string origin_id = storage::GetIdentifierFromOrigin(ext_url);
4715 // Set a cookie for the extension.
4716 net::CookieMonster* cookie_monster = profile()
4717 ->GetRequestContextForExtensions()
4718 ->GetURLRequestContext()
4719 ->cookie_store()
4720 ->GetCookieMonster();
4721 ASSERT_TRUE(cookie_monster);
4722 net::CookieOptions options;
4723 cookie_monster->SetCookieWithOptionsAsync(
4724 ext_url, "dummy=value", options,
4725 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4726 base::Unretained(&callback)));
4727 base::RunLoop().RunUntilIdle();
4728 EXPECT_TRUE(callback.result_);
4730 cookie_monster->GetAllCookiesForURLAsync(
4731 ext_url,
4732 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4733 base::Unretained(&callback)));
4734 base::RunLoop().RunUntilIdle();
4735 EXPECT_EQ(1U, callback.list_.size());
4737 // Open a database.
4738 storage::DatabaseTracker* db_tracker =
4739 BrowserContext::GetDefaultStoragePartition(profile())
4740 ->GetDatabaseTracker();
4741 base::string16 db_name = base::UTF8ToUTF16("db");
4742 base::string16 description = base::UTF8ToUTF16("db_description");
4743 int64 size;
4744 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4745 db_tracker->DatabaseClosed(origin_id, db_name);
4746 std::vector<storage::OriginInfo> origins;
4747 db_tracker->GetAllOriginsInfo(&origins);
4748 EXPECT_EQ(1U, origins.size());
4749 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4751 // Create local storage. We only simulate this by creating the backing files.
4752 // Note: This test depends on details of how the dom_storage library
4753 // stores data in the host file system.
4754 base::FilePath lso_dir_path =
4755 profile()->GetPath().AppendASCII("Local Storage");
4756 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4757 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4758 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4759 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4760 EXPECT_TRUE(base::PathExists(lso_file_path));
4762 // Create indexed db. Similarly, it is enough to only simulate this by
4763 // creating the directory on the disk.
4764 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4765 profile())->GetIndexedDBContext();
4766 idb_context->SetTaskRunnerForTesting(
4767 base::MessageLoop::current()->task_runner().get());
4768 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4769 EXPECT_TRUE(base::CreateDirectory(idb_path));
4770 EXPECT_TRUE(base::DirectoryExists(idb_path));
4772 // Uninstall the extension.
4773 base::RunLoop run_loop;
4774 ASSERT_TRUE(
4775 service()->UninstallExtension(good_crx,
4776 extensions::UNINSTALL_REASON_FOR_TESTING,
4777 run_loop.QuitClosure(),
4778 NULL));
4779 // The data deletion happens on the IO thread.
4780 run_loop.Run();
4782 // Check that the cookie is gone.
4783 cookie_monster->GetAllCookiesForURLAsync(
4784 ext_url,
4785 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4786 base::Unretained(&callback)));
4787 base::RunLoop().RunUntilIdle();
4788 EXPECT_EQ(0U, callback.list_.size());
4790 // The database should have vanished as well.
4791 origins.clear();
4792 db_tracker->GetAllOriginsInfo(&origins);
4793 EXPECT_EQ(0U, origins.size());
4795 // Check that the LSO file has been removed.
4796 EXPECT_FALSE(base::PathExists(lso_file_path));
4798 // Check if the indexed db has disappeared too.
4799 EXPECT_FALSE(base::DirectoryExists(idb_path));
4802 // Verifies app state is removed upon uninstall.
4803 TEST_F(ExtensionServiceTest, ClearAppData) {
4804 InitializeEmptyExtensionService();
4805 ExtensionCookieCallback callback;
4807 int pref_count = 0;
4809 // Install app1 with unlimited storage.
4810 const Extension* extension =
4811 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
4812 ValidatePrefKeyCount(++pref_count);
4813 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4814 const std::string id1 = extension->id();
4815 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4816 APIPermission::kUnlimitedStorage));
4817 const GURL origin1(
4818 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4819 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4820 origin1));
4821 std::string origin_id = storage::GetIdentifierFromOrigin(origin1);
4823 // Install app2 from the same origin with unlimited storage.
4824 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
4825 ValidatePrefKeyCount(++pref_count);
4826 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4827 const std::string id2 = extension->id();
4828 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4829 APIPermission::kUnlimitedStorage));
4830 EXPECT_TRUE(extension->web_extent().MatchesURL(
4831 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
4832 const GURL origin2(
4833 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4834 EXPECT_EQ(origin1, origin2);
4835 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4836 origin2));
4838 // Set a cookie for the extension.
4839 net::CookieMonster* cookie_monster = profile()
4840 ->GetRequestContext()
4841 ->GetURLRequestContext()
4842 ->cookie_store()
4843 ->GetCookieMonster();
4844 ASSERT_TRUE(cookie_monster);
4845 net::CookieOptions options;
4846 cookie_monster->SetCookieWithOptionsAsync(
4847 origin1, "dummy=value", options,
4848 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4849 base::Unretained(&callback)));
4850 base::RunLoop().RunUntilIdle();
4851 EXPECT_TRUE(callback.result_);
4853 cookie_monster->GetAllCookiesForURLAsync(
4854 origin1,
4855 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4856 base::Unretained(&callback)));
4857 base::RunLoop().RunUntilIdle();
4858 EXPECT_EQ(1U, callback.list_.size());
4860 // Open a database.
4861 storage::DatabaseTracker* db_tracker =
4862 BrowserContext::GetDefaultStoragePartition(profile())
4863 ->GetDatabaseTracker();
4864 base::string16 db_name = base::UTF8ToUTF16("db");
4865 base::string16 description = base::UTF8ToUTF16("db_description");
4866 int64 size;
4867 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4868 db_tracker->DatabaseClosed(origin_id, db_name);
4869 std::vector<storage::OriginInfo> origins;
4870 db_tracker->GetAllOriginsInfo(&origins);
4871 EXPECT_EQ(1U, origins.size());
4872 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4874 // Create local storage. We only simulate this by creating the backing files.
4875 // Note: This test depends on details of how the dom_storage library
4876 // stores data in the host file system.
4877 base::FilePath lso_dir_path =
4878 profile()->GetPath().AppendASCII("Local Storage");
4879 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4880 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4881 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4882 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4883 EXPECT_TRUE(base::PathExists(lso_file_path));
4885 // Create indexed db. Similarly, it is enough to only simulate this by
4886 // creating the directory on the disk.
4887 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4888 profile())->GetIndexedDBContext();
4889 idb_context->SetTaskRunnerForTesting(
4890 base::MessageLoop::current()->task_runner().get());
4891 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4892 EXPECT_TRUE(base::CreateDirectory(idb_path));
4893 EXPECT_TRUE(base::DirectoryExists(idb_path));
4895 // Uninstall one of them, unlimited storage should still be granted
4896 // to the origin.
4897 UninstallExtension(id1, false);
4898 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4899 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4900 origin1));
4902 // Check that the cookie is still there.
4903 cookie_monster->GetAllCookiesForURLAsync(
4904 origin1,
4905 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4906 base::Unretained(&callback)));
4907 base::RunLoop().RunUntilIdle();
4908 EXPECT_EQ(1U, callback.list_.size());
4910 // Now uninstall the other. Storage should be cleared for the apps.
4911 UninstallExtension(id2, false);
4912 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4913 EXPECT_FALSE(
4914 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4915 origin1));
4917 // Check that the cookie is gone.
4918 cookie_monster->GetAllCookiesForURLAsync(
4919 origin1,
4920 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4921 base::Unretained(&callback)));
4922 base::RunLoop().RunUntilIdle();
4923 EXPECT_EQ(0U, callback.list_.size());
4925 // The database should have vanished as well.
4926 origins.clear();
4927 db_tracker->GetAllOriginsInfo(&origins);
4928 EXPECT_EQ(0U, origins.size());
4930 // Check that the LSO file has been removed.
4931 EXPECT_FALSE(base::PathExists(lso_file_path));
4933 // Check if the indexed db has disappeared too.
4934 EXPECT_FALSE(base::DirectoryExists(idb_path));
4937 // Tests loading single extensions (like --load-extension)
4938 // Flaky crashes. http://crbug.com/231806
4939 TEST_F(ExtensionServiceTest, DISABLED_LoadExtension) {
4940 InitializeEmptyExtensionService();
4942 base::FilePath ext1 = data_dir()
4943 .AppendASCII("good")
4944 .AppendASCII("Extensions")
4945 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4946 .AppendASCII("1.0.0.0");
4947 extensions::UnpackedInstaller::Create(service())->Load(ext1);
4948 base::RunLoop().RunUntilIdle();
4949 EXPECT_EQ(0u, GetErrors().size());
4950 ASSERT_EQ(1u, loaded_.size());
4951 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
4952 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4954 ValidatePrefKeyCount(1);
4956 base::FilePath no_manifest =
4957 data_dir()
4958 .AppendASCII("bad")
4959 // .AppendASCII("Extensions")
4960 .AppendASCII("cccccccccccccccccccccccccccccccc")
4961 .AppendASCII("1");
4962 extensions::UnpackedInstaller::Create(service())->Load(no_manifest);
4963 base::RunLoop().RunUntilIdle();
4964 EXPECT_EQ(1u, GetErrors().size());
4965 ASSERT_EQ(1u, loaded_.size());
4966 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4968 // Test uninstall.
4969 std::string id = loaded_[0]->id();
4970 EXPECT_FALSE(unloaded_id_.length());
4971 service()->UninstallExtension(id,
4972 extensions::UNINSTALL_REASON_FOR_TESTING,
4973 base::Bind(&base::DoNothing),
4974 NULL);
4975 base::RunLoop().RunUntilIdle();
4976 EXPECT_EQ(id, unloaded_id_);
4977 ASSERT_EQ(0u, loaded_.size());
4978 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4981 // Tests that we generate IDs when they are not specified in the manifest for
4982 // --load-extension.
4983 TEST_F(ExtensionServiceTest, GenerateID) {
4984 InitializeEmptyExtensionService();
4986 base::FilePath no_id_ext = data_dir().AppendASCII("no_id");
4987 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
4988 base::RunLoop().RunUntilIdle();
4989 EXPECT_EQ(0u, GetErrors().size());
4990 ASSERT_EQ(1u, loaded_.size());
4991 ASSERT_TRUE(crx_file::id_util::IdIsValid(loaded_[0]->id()));
4992 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
4994 ValidatePrefKeyCount(1);
4996 std::string previous_id = loaded_[0]->id();
4998 // If we reload the same path, we should get the same extension ID.
4999 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
5000 base::RunLoop().RunUntilIdle();
5001 ASSERT_EQ(1u, loaded_.size());
5002 ASSERT_EQ(previous_id, loaded_[0]->id());
5005 TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
5006 InitializeEmptyExtensionService();
5008 base::FilePath bad_locale =
5009 data_dir().AppendASCII("unpacked").AppendASCII("bad_messages_file");
5010 extensions::UnpackedInstaller::Create(service())->Load(bad_locale);
5011 base::RunLoop().RunUntilIdle();
5012 EXPECT_EQ(1u, GetErrors().size());
5013 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
5014 .AppendASCII("ms")
5015 .AppendASCII("messages.json");
5016 EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
5017 testing::HasSubstr(
5018 base::UTF16ToUTF8(ms_messages_file.LossyDisplayName())),
5019 testing::HasSubstr("Dictionary keys must be quoted.")));
5020 ASSERT_EQ(0u, loaded_.size());
5023 void ExtensionServiceTest::TestExternalProvider(
5024 MockExtensionProvider* provider, Manifest::Location location) {
5025 // Verify that starting with no providers loads no extensions.
5026 service()->Init();
5027 ASSERT_EQ(0u, loaded_.size());
5029 provider->set_visit_count(0);
5031 // Register a test extension externally using the mock registry provider.
5032 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5034 // Add the extension.
5035 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5037 // Reloading extensions should find our externally registered extension
5038 // and install it.
5039 content::WindowedNotificationObserver observer(
5040 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5041 content::NotificationService::AllSources());
5042 service()->CheckForExternalUpdates();
5043 observer.Wait();
5045 ASSERT_EQ(0u, GetErrors().size());
5046 ASSERT_EQ(1u, loaded_.size());
5047 ASSERT_EQ(location, loaded_[0]->location());
5048 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
5049 ValidatePrefKeyCount(1);
5050 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5051 ValidateIntegerPref(good_crx, "location", location);
5053 // Reload extensions without changing anything. The extension should be
5054 // loaded again.
5055 loaded_.clear();
5056 service()->ReloadExtensionsForTest();
5057 base::RunLoop().RunUntilIdle();
5058 ASSERT_EQ(0u, GetErrors().size());
5059 ASSERT_EQ(1u, loaded_.size());
5060 ValidatePrefKeyCount(1);
5061 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5062 ValidateIntegerPref(good_crx, "location", location);
5064 // Now update the extension with a new version. We should get upgraded.
5065 source_path = source_path.DirName().AppendASCII("good2.crx");
5066 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5068 loaded_.clear();
5069 content::WindowedNotificationObserver observer_2(
5070 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5071 content::NotificationService::AllSources());
5072 service()->CheckForExternalUpdates();
5073 observer_2.Wait();
5074 ASSERT_EQ(0u, GetErrors().size());
5075 ASSERT_EQ(1u, loaded_.size());
5076 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
5077 ValidatePrefKeyCount(1);
5078 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5079 ValidateIntegerPref(good_crx, "location", location);
5081 // Uninstall the extension and reload. Nothing should happen because the
5082 // preference should prevent us from reinstalling.
5083 std::string id = loaded_[0]->id();
5084 bool no_uninstall =
5085 GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL);
5086 service()->UninstallExtension(id,
5087 extensions::UNINSTALL_REASON_FOR_TESTING,
5088 base::Bind(&base::DoNothing),
5089 NULL);
5090 base::RunLoop().RunUntilIdle();
5092 base::FilePath install_path = extensions_install_dir().AppendASCII(id);
5093 if (no_uninstall) {
5094 // Policy controlled extensions should not have been touched by uninstall.
5095 ASSERT_TRUE(base::PathExists(install_path));
5096 } else {
5097 // The extension should also be gone from the install directory.
5098 ASSERT_FALSE(base::PathExists(install_path));
5099 loaded_.clear();
5100 service()->CheckForExternalUpdates();
5101 base::RunLoop().RunUntilIdle();
5102 ASSERT_EQ(0u, loaded_.size());
5103 ValidatePrefKeyCount(1);
5104 ValidateIntegerPref(good_crx, "state",
5105 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
5106 ValidateIntegerPref(good_crx, "location", location);
5108 // Now clear the preference and reinstall.
5109 SetPrefInteg(good_crx, "state", Extension::ENABLED);
5111 loaded_.clear();
5112 content::WindowedNotificationObserver observer(
5113 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5114 content::NotificationService::AllSources());
5115 service()->CheckForExternalUpdates();
5116 observer.Wait();
5117 ASSERT_EQ(1u, loaded_.size());
5119 ValidatePrefKeyCount(1);
5120 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5121 ValidateIntegerPref(good_crx, "location", location);
5123 if (GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL)) {
5124 EXPECT_EQ(2, provider->visit_count());
5125 } else {
5126 // Now test an externally triggered uninstall (deleting the registry key or
5127 // the pref entry).
5128 provider->RemoveExtension(good_crx);
5130 loaded_.clear();
5131 service()->OnExternalProviderReady(provider);
5132 base::RunLoop().RunUntilIdle();
5133 ASSERT_EQ(0u, loaded_.size());
5134 ValidatePrefKeyCount(0);
5136 // The extension should also be gone from the install directory.
5137 ASSERT_FALSE(base::PathExists(install_path));
5139 // Now test the case where user uninstalls and then the extension is removed
5140 // from the external provider.
5141 content::WindowedNotificationObserver observer(
5142 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5143 content::NotificationService::AllSources());
5144 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5145 service()->CheckForExternalUpdates();
5146 observer.Wait();
5148 ASSERT_EQ(1u, loaded_.size());
5149 ASSERT_EQ(0u, GetErrors().size());
5151 // User uninstalls.
5152 loaded_.clear();
5153 service()->UninstallExtension(id,
5154 extensions::UNINSTALL_REASON_FOR_TESTING,
5155 base::Bind(&base::DoNothing),
5156 NULL);
5157 base::RunLoop().RunUntilIdle();
5158 ASSERT_EQ(0u, loaded_.size());
5160 // Then remove the extension from the extension provider.
5161 provider->RemoveExtension(good_crx);
5163 // Should still be at 0.
5164 loaded_.clear();
5165 extensions::InstalledLoader(service()).LoadAllExtensions();
5166 base::RunLoop().RunUntilIdle();
5167 ASSERT_EQ(0u, loaded_.size());
5168 ValidatePrefKeyCount(1);
5170 EXPECT_EQ(5, provider->visit_count());
5174 // Tests the external installation feature
5175 #if defined(OS_WIN)
5176 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
5177 // This should all work, even when normal extension installation is disabled.
5178 InitializeEmptyExtensionService();
5179 service()->set_extensions_enabled(false);
5181 // Now add providers. Extension system takes ownership of the objects.
5182 MockExtensionProvider* reg_provider =
5183 new MockExtensionProvider(service(), Manifest::EXTERNAL_REGISTRY);
5184 AddMockExternalProvider(reg_provider);
5185 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
5187 #endif
5189 TEST_F(ExtensionServiceTest, ExternalInstallPref) {
5190 InitializeEmptyExtensionService();
5192 // Now add providers. Extension system takes ownership of the objects.
5193 MockExtensionProvider* pref_provider =
5194 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
5196 AddMockExternalProvider(pref_provider);
5197 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
5200 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
5201 // This should all work, even when normal extension installation is disabled.
5202 InitializeEmptyExtensionService();
5203 service()->set_extensions_enabled(false);
5205 // TODO(skerner): The mock provider is not a good model of a provider
5206 // that works with update URLs, because it adds file and version info.
5207 // Extend the mock to work with update URLs. This test checks the
5208 // behavior that is common to all external extension visitors. The
5209 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5210 // what the visitor does results in an extension being downloaded and
5211 // installed.
5212 MockExtensionProvider* pref_provider =
5213 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF_DOWNLOAD);
5214 AddMockExternalProvider(pref_provider);
5215 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
5218 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
5219 // This should all work, even when normal extension installation is disabled.
5220 InitializeEmptyExtensionService();
5221 service()->set_extensions_enabled(false);
5223 // TODO(skerner): The mock provider is not a good model of a provider
5224 // that works with update URLs, because it adds file and version info.
5225 // Extend the mock to work with update URLs. This test checks the
5226 // behavior that is common to all external extension visitors. The
5227 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5228 // what the visitor does results in an extension being downloaded and
5229 // installed.
5230 MockExtensionProvider* pref_provider =
5231 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
5232 AddMockExternalProvider(pref_provider);
5233 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
5236 // Tests that external extensions get uninstalled when the external extension
5237 // providers can't account for them.
5238 TEST_F(ExtensionServiceTest, ExternalUninstall) {
5239 // Start the extensions service with one external extension already installed.
5240 base::FilePath source_install_dir =
5241 data_dir().AppendASCII("good").AppendASCII("Extensions");
5242 base::FilePath pref_path = source_install_dir
5243 .DirName()
5244 .AppendASCII("PreferencesExternal");
5246 // This initializes the extensions service with no ExternalProviders.
5247 InitializeInstalledExtensionService(pref_path, source_install_dir);
5248 service()->set_extensions_enabled(false);
5250 service()->Init();
5252 ASSERT_EQ(0u, GetErrors().size());
5253 ASSERT_EQ(0u, loaded_.size());
5255 // Verify that it's not the disabled extensions flag causing it not to load.
5256 service()->set_extensions_enabled(true);
5257 service()->ReloadExtensionsForTest();
5258 base::RunLoop().RunUntilIdle();
5260 ASSERT_EQ(0u, GetErrors().size());
5261 ASSERT_EQ(0u, loaded_.size());
5264 // Test that running multiple update checks simultaneously does not
5265 // keep the update from succeeding.
5266 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
5267 InitializeEmptyExtensionService();
5269 MockExtensionProvider* provider =
5270 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
5271 AddMockExternalProvider(provider);
5273 // Verify that starting with no providers loads no extensions.
5274 service()->Init();
5275 ASSERT_EQ(0u, loaded_.size());
5277 // Start two checks for updates.
5278 provider->set_visit_count(0);
5279 service()->CheckForExternalUpdates();
5280 service()->CheckForExternalUpdates();
5281 base::RunLoop().RunUntilIdle();
5283 // Two calls should cause two checks for external extensions.
5284 EXPECT_EQ(2, provider->visit_count());
5285 EXPECT_EQ(0u, GetErrors().size());
5286 EXPECT_EQ(0u, loaded_.size());
5288 // Register a test extension externally using the mock registry provider.
5289 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5290 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5292 // Two checks for external updates should find the extension, and install it
5293 // once.
5294 content::WindowedNotificationObserver observer(
5295 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5296 content::NotificationService::AllSources());
5297 provider->set_visit_count(0);
5298 service()->CheckForExternalUpdates();
5299 service()->CheckForExternalUpdates();
5300 observer.Wait();
5301 EXPECT_EQ(2, provider->visit_count());
5302 ASSERT_EQ(0u, GetErrors().size());
5303 ASSERT_EQ(1u, loaded_.size());
5304 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
5305 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
5306 ValidatePrefKeyCount(1);
5307 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5308 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
5310 provider->RemoveExtension(good_crx);
5311 provider->set_visit_count(0);
5312 service()->CheckForExternalUpdates();
5313 service()->CheckForExternalUpdates();
5314 base::RunLoop().RunUntilIdle();
5316 // Two calls should cause two checks for external extensions.
5317 // Because the external source no longer includes good_crx,
5318 // good_crx will be uninstalled. So, expect that no extensions
5319 // are loaded.
5320 EXPECT_EQ(2, provider->visit_count());
5321 EXPECT_EQ(0u, GetErrors().size());
5322 EXPECT_EQ(0u, loaded_.size());
5325 TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
5326 InitializeEmptyExtensionService();
5328 // Test some valid extension records.
5329 // Set a base path to avoid erroring out on relative paths.
5330 // Paths starting with // are absolute on every platform we support.
5331 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5332 ASSERT_TRUE(base_path.IsAbsolute());
5333 MockProviderVisitor visitor(base_path);
5334 std::string json_data =
5336 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5337 " \"external_crx\": \"RandomExtension.crx\","
5338 " \"external_version\": \"1.0\""
5339 " },"
5340 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5341 " \"external_crx\": \"RandomExtension2.crx\","
5342 " \"external_version\": \"2.0\""
5343 " },"
5344 " \"cccccccccccccccccccccccccccccccc\": {"
5345 " \"external_update_url\": \"http:\\\\foo.com/update\","
5346 " \"install_parameter\": \"id\""
5347 " }"
5348 "}";
5349 EXPECT_EQ(3, visitor.Visit(json_data));
5351 // Simulate an external_extensions.json file that contains seven invalid
5352 // records:
5353 // - One that is missing the 'external_crx' key.
5354 // - One that is missing the 'external_version' key.
5355 // - One that is specifying .. in the path.
5356 // - One that specifies both a file and update URL.
5357 // - One that specifies no file or update URL.
5358 // - One that has an update URL that is not well formed.
5359 // - One that contains a malformed version.
5360 // - One that has an invalid id.
5361 // - One that has a non-dictionary value.
5362 // - One that has an integer 'external_version' instead of a string.
5363 // The final extension is valid, and we check that it is read to make sure
5364 // failures don't stop valid records from being read.
5365 json_data =
5367 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5368 " \"external_version\": \"1.0\""
5369 " },"
5370 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5371 " \"external_crx\": \"RandomExtension.crx\""
5372 " },"
5373 " \"cccccccccccccccccccccccccccccccc\": {"
5374 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
5375 " \"external_version\": \"2.0\""
5376 " },"
5377 " \"dddddddddddddddddddddddddddddddd\": {"
5378 " \"external_crx\": \"RandomExtension2.crx\","
5379 " \"external_version\": \"2.0\","
5380 " \"external_update_url\": \"http:\\\\foo.com/update\""
5381 " },"
5382 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
5383 " },"
5384 " \"ffffffffffffffffffffffffffffffff\": {"
5385 " \"external_update_url\": \"This string is not a valid URL\""
5386 " },"
5387 " \"gggggggggggggggggggggggggggggggg\": {"
5388 " \"external_crx\": \"RandomExtension3.crx\","
5389 " \"external_version\": \"This is not a valid version!\""
5390 " },"
5391 " \"This is not a valid id!\": {},"
5392 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
5393 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
5394 " \"external_crx\": \"RandomExtension4.crx\","
5395 " \"external_version\": 1.0"
5396 " },"
5397 " \"pppppppppppppppppppppppppppppppp\": {"
5398 " \"external_crx\": \"RandomValidExtension.crx\","
5399 " \"external_version\": \"1.0\""
5400 " }"
5401 "}";
5402 EXPECT_EQ(1, visitor.Visit(json_data));
5404 // Check that if a base path is not provided, use of a relative
5405 // path fails.
5406 base::FilePath empty;
5407 MockProviderVisitor visitor_no_relative_paths(empty);
5409 // Use absolute paths. Expect success.
5410 json_data =
5412 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5413 " \"external_crx\": \"//RandomExtension1.crx\","
5414 " \"external_version\": \"3.0\""
5415 " },"
5416 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5417 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
5418 " \"external_version\": \"3.0\""
5419 " }"
5420 "}";
5421 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
5423 // Use a relative path. Expect that it will error out.
5424 json_data =
5426 " \"cccccccccccccccccccccccccccccccc\": {"
5427 " \"external_crx\": \"RandomExtension2.crx\","
5428 " \"external_version\": \"3.0\""
5429 " }"
5430 "}";
5431 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
5433 // Test supported_locales.
5434 json_data =
5436 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5437 " \"external_crx\": \"RandomExtension.crx\","
5438 " \"external_version\": \"1.0\","
5439 " \"supported_locales\": [ \"en\" ]"
5440 " },"
5441 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5442 " \"external_crx\": \"RandomExtension2.crx\","
5443 " \"external_version\": \"2.0\","
5444 " \"supported_locales\": [ \"en-GB\" ]"
5445 " },"
5446 " \"cccccccccccccccccccccccccccccccc\": {"
5447 " \"external_crx\": \"RandomExtension2.crx\","
5448 " \"external_version\": \"3.0\","
5449 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
5450 " }"
5451 "}";
5453 ScopedBrowserLocale guard("en-US");
5454 EXPECT_EQ(2, visitor.Visit(json_data));
5457 // Test keep_if_present.
5458 json_data =
5460 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5461 " \"external_crx\": \"RandomExtension.crx\","
5462 " \"external_version\": \"1.0\","
5463 " \"keep_if_present\": true"
5464 " }"
5465 "}";
5467 EXPECT_EQ(0, visitor.Visit(json_data));
5470 // Test is_bookmark_app.
5471 MockProviderVisitor from_bookmark_visitor(
5472 base_path, Extension::FROM_BOOKMARK);
5473 json_data =
5475 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5476 " \"external_crx\": \"RandomExtension.crx\","
5477 " \"external_version\": \"1.0\","
5478 " \"is_bookmark_app\": true"
5479 " }"
5480 "}";
5481 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
5483 // Test is_from_webstore.
5484 MockProviderVisitor from_webstore_visitor(
5485 base_path, Extension::FROM_WEBSTORE);
5486 json_data =
5488 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5489 " \"external_crx\": \"RandomExtension.crx\","
5490 " \"external_version\": \"1.0\","
5491 " \"is_from_webstore\": true"
5492 " }"
5493 "}";
5494 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
5496 // Test was_installed_by_eom.
5497 MockProviderVisitor was_installed_by_eom_visitor(
5498 base_path, Extension::WAS_INSTALLED_BY_OEM);
5499 json_data =
5501 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5502 " \"external_crx\": \"RandomExtension.crx\","
5503 " \"external_version\": \"1.0\","
5504 " \"was_installed_by_oem\": true"
5505 " }"
5506 "}";
5507 EXPECT_EQ(1, was_installed_by_eom_visitor.Visit(json_data));
5509 // Test min_profile_created_by_version.
5510 MockProviderVisitor min_profile_created_by_version_visitor(base_path);
5511 json_data =
5513 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5514 " \"external_crx\": \"RandomExtension.crx\","
5515 " \"external_version\": \"1.0\","
5516 " \"min_profile_created_by_version\": \"42.0.0.1\""
5517 " },"
5518 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5519 " \"external_crx\": \"RandomExtension2.crx\","
5520 " \"external_version\": \"1.0\","
5521 " \"min_profile_created_by_version\": \"43.0.0.1\""
5522 " },"
5523 " \"cccccccccccccccccccccccccccccccc\": {"
5524 " \"external_crx\": \"RandomExtension3.crx\","
5525 " \"external_version\": \"3.0\","
5526 " \"min_profile_created_by_version\": \"44.0.0.1\""
5527 " }"
5528 "}";
5529 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5530 prefs::kProfileCreatedByVersion, "40.0.0.1");
5531 EXPECT_EQ(0, min_profile_created_by_version_visitor.Visit(json_data));
5532 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5533 prefs::kProfileCreatedByVersion, "43.0.0.1");
5534 EXPECT_EQ(2, min_profile_created_by_version_visitor.Visit(json_data));
5535 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5536 prefs::kProfileCreatedByVersion, "45.0.0.1");
5537 EXPECT_EQ(3, min_profile_created_by_version_visitor.Visit(json_data));
5540 TEST_F(ExtensionServiceTest, DoNotInstallForEnterprise) {
5541 InitializeEmptyExtensionService();
5543 const base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5544 ASSERT_TRUE(base_path.IsAbsolute());
5545 MockProviderVisitor visitor(base_path);
5546 policy::ProfilePolicyConnector* const connector =
5547 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(
5548 visitor.profile());
5549 connector->OverrideIsManagedForTesting(true);
5550 EXPECT_TRUE(connector->IsManaged());
5552 std::string json_data =
5554 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5555 " \"external_crx\": \"RandomExtension.crx\","
5556 " \"external_version\": \"1.0\","
5557 " \"do_not_install_for_enterprise\": true"
5558 " },"
5559 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5560 " \"external_crx\": \"RandomExtension2.crx\","
5561 " \"external_version\": \"1.0\""
5562 " }"
5563 "}";
5564 EXPECT_EQ(1, visitor.Visit(json_data));
5567 // Test loading good extensions from the profile directory.
5568 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
5569 // Ensure we're testing in "en" and leave global state untouched.
5570 extension_l10n_util::ScopedLocaleForTest testLocale("en");
5572 // Initialize the test dir with a good Preferences/extensions.
5573 base::FilePath source_install_dir = data_dir().AppendASCII("l10n");
5574 base::FilePath pref_path =
5575 source_install_dir.Append(chrome::kPreferencesFilename);
5576 InitializeInstalledExtensionService(pref_path, source_install_dir);
5578 service()->Init();
5580 ASSERT_EQ(3u, loaded_.size());
5582 // This was equal to "sr" on load.
5583 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
5585 // These are untouched by re-localization.
5586 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
5587 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
5589 // This one starts with Serbian name, and gets re-localized into English.
5590 EXPECT_EQ("My name is simple.", loaded_[0]->name());
5592 // These are untouched by re-localization.
5593 EXPECT_EQ("My name is simple.", loaded_[1]->name());
5594 EXPECT_EQ("no l10n", loaded_[2]->name());
5597 class ExtensionsReadyRecorder : public content::NotificationObserver {
5598 public:
5599 ExtensionsReadyRecorder() : ready_(false) {
5600 registrar_.Add(this,
5601 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
5602 content::NotificationService::AllSources());
5605 void set_ready(bool value) { ready_ = value; }
5606 bool ready() { return ready_; }
5608 private:
5609 void Observe(int type,
5610 const content::NotificationSource& source,
5611 const content::NotificationDetails& details) override {
5612 switch (type) {
5613 case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED:
5614 ready_ = true;
5615 break;
5616 default:
5617 NOTREACHED();
5621 content::NotificationRegistrar registrar_;
5622 bool ready_;
5625 // Test that we get enabled/disabled correctly for all the pref/command-line
5626 // combinations. We don't want to derive from the ExtensionServiceTest class
5627 // for this test, so we use ExtensionServiceTestSimple.
5629 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
5630 // enabled or not.
5631 class ExtensionServiceTestSimple : public testing::Test {
5632 content::TestBrowserThreadBundle thread_bundle_;
5635 TEST_F(ExtensionServiceTestSimple, Enabledness) {
5636 // Make sure the PluginService singleton is destroyed at the end of the test.
5637 base::ShadowingAtExitManager at_exit_manager;
5638 #if defined(ENABLE_PLUGINS)
5639 content::PluginService::GetInstance()->Init();
5640 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
5641 #endif
5643 ExtensionErrorReporter::Init(false); // no noisy errors
5644 ExtensionsReadyRecorder recorder;
5645 scoped_ptr<TestingProfile> profile(new TestingProfile());
5646 #if defined OS_CHROMEOS
5647 chromeos::ScopedTestDeviceSettingsService device_settings_service;
5648 chromeos::ScopedTestCrosSettings cros_settings;
5649 scoped_ptr<chromeos::ScopedTestUserManager> user_manager(
5650 new chromeos::ScopedTestUserManager);
5651 #endif
5652 scoped_ptr<base::CommandLine> command_line;
5653 base::FilePath install_dir = profile->GetPath()
5654 .AppendASCII(extensions::kInstallDirectoryName);
5656 // By default, we are enabled.
5657 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5658 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
5659 ExtensionSystem::Get(profile.get()))->
5660 CreateExtensionService(
5661 command_line.get(),
5662 install_dir,
5663 false);
5664 EXPECT_TRUE(service->extensions_enabled());
5665 service->Init();
5666 base::RunLoop().RunUntilIdle();
5667 EXPECT_TRUE(recorder.ready());
5668 #if defined OS_CHROMEOS
5669 user_manager.reset();
5670 #endif
5672 // If either the command line or pref is set, we are disabled.
5673 recorder.set_ready(false);
5674 profile.reset(new TestingProfile());
5675 command_line->AppendSwitch(switches::kDisableExtensions);
5676 service = static_cast<extensions::TestExtensionSystem*>(
5677 ExtensionSystem::Get(profile.get()))->
5678 CreateExtensionService(
5679 command_line.get(),
5680 install_dir,
5681 false);
5682 EXPECT_FALSE(service->extensions_enabled());
5683 service->Init();
5684 base::RunLoop().RunUntilIdle();
5685 EXPECT_TRUE(recorder.ready());
5687 recorder.set_ready(false);
5688 profile.reset(new TestingProfile());
5689 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5690 service = static_cast<extensions::TestExtensionSystem*>(
5691 ExtensionSystem::Get(profile.get()))->
5692 CreateExtensionService(
5693 command_line.get(),
5694 install_dir,
5695 false);
5696 EXPECT_FALSE(service->extensions_enabled());
5697 service->Init();
5698 base::RunLoop().RunUntilIdle();
5699 EXPECT_TRUE(recorder.ready());
5701 recorder.set_ready(false);
5702 profile.reset(new TestingProfile());
5703 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5704 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5705 service = static_cast<extensions::TestExtensionSystem*>(
5706 ExtensionSystem::Get(profile.get()))->
5707 CreateExtensionService(
5708 command_line.get(),
5709 install_dir,
5710 false);
5711 EXPECT_FALSE(service->extensions_enabled());
5712 service->Init();
5713 base::RunLoop().RunUntilIdle();
5714 EXPECT_TRUE(recorder.ready());
5716 // Explicitly delete all the resources used in this test.
5717 profile.reset();
5718 service = NULL;
5719 // Execute any pending deletion tasks.
5720 base::RunLoop().RunUntilIdle();
5723 // Test loading extensions that require limited and unlimited storage quotas.
5724 TEST_F(ExtensionServiceTest, StorageQuota) {
5725 InitializeEmptyExtensionService();
5727 base::FilePath extensions_path = data_dir().AppendASCII("storage_quota");
5729 base::FilePath limited_quota_ext =
5730 extensions_path.AppendASCII("limited_quota")
5731 .AppendASCII("1.0");
5733 // The old permission name for unlimited quota was "unlimited_storage", but
5734 // we changed it to "unlimitedStorage". This tests both versions.
5735 base::FilePath unlimited_quota_ext =
5736 extensions_path.AppendASCII("unlimited_quota")
5737 .AppendASCII("1.0");
5738 base::FilePath unlimited_quota_ext2 =
5739 extensions_path.AppendASCII("unlimited_quota")
5740 .AppendASCII("2.0");
5741 extensions::UnpackedInstaller::Create(service())->Load(limited_quota_ext);
5742 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext);
5743 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext2);
5744 base::RunLoop().RunUntilIdle();
5746 ASSERT_EQ(3u, loaded_.size());
5747 EXPECT_TRUE(profile());
5748 EXPECT_FALSE(profile()->IsOffTheRecord());
5749 EXPECT_FALSE(
5750 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5751 loaded_[0]->url()));
5752 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5753 loaded_[1]->url()));
5754 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5755 loaded_[2]->url()));
5758 // Tests ComponentLoader::Add().
5759 TEST_F(ExtensionServiceTest, ComponentExtensions) {
5760 InitializeEmptyExtensionService();
5762 // Component extensions should work even when extensions are disabled.
5763 service()->set_extensions_enabled(false);
5765 base::FilePath path = data_dir()
5766 .AppendASCII("good")
5767 .AppendASCII("Extensions")
5768 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
5769 .AppendASCII("1.0.0.0");
5771 std::string manifest;
5772 ASSERT_TRUE(base::ReadFileToString(
5773 path.Append(extensions::kManifestFilename), &manifest));
5775 service()->component_loader()->Add(manifest, path);
5776 service()->Init();
5778 // Note that we do not pump messages -- the extension should be loaded
5779 // immediately.
5781 EXPECT_EQ(0u, GetErrors().size());
5782 ASSERT_EQ(1u, loaded_.size());
5783 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
5784 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5786 // Component extensions get a prefs entry on first install.
5787 ValidatePrefKeyCount(1);
5789 // Reload all extensions, and make sure it comes back.
5790 std::string extension_id = (*registry()->enabled_extensions().begin())->id();
5791 loaded_.clear();
5792 service()->ReloadExtensionsForTest();
5793 ASSERT_EQ(1u, registry()->enabled_extensions().size());
5794 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id());
5797 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
5798 InitializeEmptyExtensionService();
5799 InitializeExtensionSyncService();
5801 bool flare_was_called = false;
5802 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5803 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5804 extension_sync_service()->SetSyncStartFlare(
5805 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5806 factory.GetWeakPtr(),
5807 &flare_was_called, // Safe due to WeakPtrFactory scope.
5808 &triggered_type)); // Safe due to WeakPtrFactory scope.
5810 // Install a component extension.
5811 std::string manifest;
5812 ASSERT_TRUE(base::ReadFileToString(
5813 good0_path().Append(extensions::kManifestFilename), &manifest));
5814 service()->component_loader()->Add(manifest, good0_path());
5815 ASSERT_FALSE(service()->is_ready());
5816 service()->Init();
5817 ASSERT_TRUE(service()->is_ready());
5819 // Extensions added before service is_ready() don't trigger sync startup.
5820 EXPECT_FALSE(flare_was_called);
5821 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5824 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
5825 InitializeGoodInstalledExtensionService();
5826 InitializeExtensionSyncService();
5828 bool flare_was_called = false;
5829 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5830 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5831 extension_sync_service()->SetSyncStartFlare(
5832 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5833 factory.GetWeakPtr(),
5834 &flare_was_called, // Safe due to WeakPtrFactory scope.
5835 &triggered_type)); // Safe due to WeakPtrFactory scope.
5837 ASSERT_FALSE(service()->is_ready());
5838 service()->Init();
5839 ASSERT_EQ(3u, loaded_.size());
5840 ASSERT_TRUE(service()->is_ready());
5842 // Extensions added before service is_ready() don't trigger sync startup.
5843 EXPECT_FALSE(flare_was_called);
5844 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5847 TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
5848 InitializeEmptyExtensionService();
5849 InitializeExtensionSyncService();
5850 service()->Init();
5851 ASSERT_TRUE(service()->is_ready());
5853 bool flare_was_called = false;
5854 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5855 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5856 extension_sync_service()->SetSyncStartFlare(
5857 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5858 factory.GetWeakPtr(),
5859 &flare_was_called, // Safe due to WeakPtrFactory scope.
5860 &triggered_type)); // Safe due to WeakPtrFactory scope.
5862 base::FilePath path = data_dir().AppendASCII("good.crx");
5863 InstallCRX(path, INSTALL_NEW);
5865 EXPECT_TRUE(flare_was_called);
5866 EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
5868 // Reset.
5869 flare_was_called = false;
5870 triggered_type = syncer::UNSPECIFIED;
5872 // Once sync starts, flare should no longer be invoked.
5873 extension_sync_service()->MergeDataAndStartSyncing(
5874 syncer::EXTENSIONS,
5875 syncer::SyncDataList(),
5876 scoped_ptr<syncer::SyncChangeProcessor>(
5877 new syncer::FakeSyncChangeProcessor),
5878 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5879 path = data_dir().AppendASCII("page_action.crx");
5880 InstallCRX(path, INSTALL_NEW);
5881 EXPECT_FALSE(flare_was_called);
5882 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5885 TEST_F(ExtensionServiceTest, DisableExtensionFromSync) {
5886 // Start the extensions service with one external extension already installed.
5887 base::FilePath source_install_dir =
5888 data_dir().AppendASCII("good").AppendASCII("Extensions");
5889 base::FilePath pref_path =
5890 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5892 InitializeInstalledExtensionService(pref_path, source_install_dir);
5893 InitializeExtensionSyncService();
5895 // The user has enabled sync.
5896 ProfileSyncService* sync_service =
5897 ProfileSyncServiceFactory::GetForProfile(profile());
5898 sync_service->SetSyncSetupCompleted();
5900 service()->Init();
5901 ASSERT_TRUE(service()->is_ready());
5903 ASSERT_EQ(3u, loaded_.size());
5905 // We start enabled.
5906 const Extension* extension = service()->GetExtensionById(good0, true);
5907 ASSERT_TRUE(extension);
5908 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5910 // Then sync data arrives telling us to disable |good0|.
5911 ExtensionSyncData disable_good_crx(*extension, false,
5912 Extension::DISABLE_USER_ACTION, false,
5913 false, ExtensionSyncData::BOOLEAN_UNSET);
5914 syncer::SyncDataList sync_data;
5915 sync_data.push_back(disable_good_crx.GetSyncData());
5916 extension_sync_service()->MergeDataAndStartSyncing(
5917 syncer::EXTENSIONS,
5918 sync_data,
5919 scoped_ptr<syncer::SyncChangeProcessor>(
5920 new syncer::FakeSyncChangeProcessor),
5921 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5922 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5925 TEST_F(ExtensionServiceTest, DontDisableExtensionWithPendingEnableFromSync) {
5926 // Start the extensions service with one external extension already installed.
5927 base::FilePath source_install_dir =
5928 data_dir().AppendASCII("good").AppendASCII("Extensions");
5929 base::FilePath pref_path =
5930 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5932 InitializeInstalledExtensionService(pref_path, source_install_dir);
5933 InitializeExtensionSyncService();
5935 // The user has enabled sync.
5936 ProfileSyncService* sync_service =
5937 ProfileSyncServiceFactory::GetForProfile(profile());
5938 sync_service->SetSyncSetupCompleted();
5940 service()->Init();
5941 ASSERT_TRUE(service()->is_ready());
5942 ASSERT_EQ(3u, loaded_.size());
5944 const Extension* extension = service()->GetExtensionById(good0, true);
5945 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5947 // Disable extension before first sync data arrives.
5948 service()->DisableExtension(good0, Extension::DISABLE_USER_ACTION);
5949 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5951 // Enable extension - this is now the most recent state.
5952 service()->EnableExtension(good0);
5953 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5955 // Now sync data comes in that says to disable good0. This should be
5956 // ignored.
5957 ExtensionSyncData disable_good_crx(*extension, false,
5958 Extension::DISABLE_USER_ACTION, false,
5959 false, ExtensionSyncData::BOOLEAN_UNSET);
5960 syncer::SyncDataList sync_data;
5961 sync_data.push_back(disable_good_crx.GetSyncData());
5962 extension_sync_service()->MergeDataAndStartSyncing(
5963 syncer::EXTENSIONS,
5964 sync_data,
5965 scoped_ptr<syncer::SyncChangeProcessor>(
5966 new syncer::FakeSyncChangeProcessor),
5967 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5969 // The extension was enabled locally before the sync data arrived, so it
5970 // should still be enabled now.
5971 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5974 TEST_F(ExtensionServiceTest, GetSyncData) {
5975 InitializeEmptyExtensionService();
5976 InitializeExtensionSyncService();
5977 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5978 const Extension* extension = service()->GetInstalledExtension(good_crx);
5979 ASSERT_TRUE(extension);
5981 extension_sync_service()->MergeDataAndStartSyncing(
5982 syncer::EXTENSIONS,
5983 syncer::SyncDataList(),
5984 scoped_ptr<syncer::SyncChangeProcessor>(
5985 new syncer::FakeSyncChangeProcessor),
5986 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5988 syncer::SyncDataList list =
5989 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5990 ASSERT_EQ(list.size(), 1U);
5991 scoped_ptr<ExtensionSyncData> data =
5992 ExtensionSyncData::CreateFromSyncData(list[0]);
5993 ASSERT_TRUE(data.get());
5994 EXPECT_EQ(extension->id(), data->id());
5995 EXPECT_FALSE(data->uninstalled());
5996 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
5997 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
5998 data->incognito_enabled());
5999 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6000 EXPECT_TRUE(data->version().Equals(*extension->version()));
6001 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
6002 data->update_url());
6003 EXPECT_EQ(extension->name(), data->name());
6006 TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
6007 InitializeEmptyExtensionService();
6008 InitializeExtensionSyncService();
6009 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6010 TerminateExtension(good_crx);
6011 const Extension* extension = service()->GetInstalledExtension(good_crx);
6012 ASSERT_TRUE(extension);
6014 syncer::FakeSyncChangeProcessor processor;
6015 extension_sync_service()->MergeDataAndStartSyncing(
6016 syncer::EXTENSIONS,
6017 syncer::SyncDataList(),
6018 scoped_ptr<syncer::SyncChangeProcessor>(
6019 new syncer::FakeSyncChangeProcessor),
6020 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6022 syncer::SyncDataList list =
6023 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6024 ASSERT_EQ(list.size(), 1U);
6025 scoped_ptr<ExtensionSyncData> data =
6026 ExtensionSyncData::CreateFromSyncData(list[0]);
6027 ASSERT_TRUE(data.get());
6028 EXPECT_EQ(extension->id(), data->id());
6029 EXPECT_FALSE(data->uninstalled());
6030 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
6031 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
6032 data->incognito_enabled());
6033 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6034 EXPECT_TRUE(data->version().Equals(*extension->version()));
6035 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
6036 data->update_url());
6037 EXPECT_EQ(extension->name(), data->name());
6040 TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
6041 InitializeEmptyExtensionService();
6042 InitializeExtensionSyncService();
6043 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6044 const Extension* extension = service()->GetInstalledExtension(good_crx);
6045 ASSERT_TRUE(extension);
6047 syncer::FakeSyncChangeProcessor processor;
6048 extension_sync_service()->MergeDataAndStartSyncing(
6049 syncer::APPS,
6050 syncer::SyncDataList(),
6051 scoped_ptr<syncer::SyncChangeProcessor>(
6052 new syncer::FakeSyncChangeProcessor),
6053 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6055 syncer::SyncDataList list =
6056 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6057 ASSERT_EQ(list.size(), 0U);
6060 TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
6061 InitializeEmptyExtensionService();
6062 InitializeExtensionSyncService();
6063 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6064 const Extension* extension = service()->GetInstalledExtension(good_crx);
6065 ASSERT_TRUE(extension);
6067 syncer::FakeSyncChangeProcessor processor;
6068 extension_sync_service()->MergeDataAndStartSyncing(
6069 syncer::EXTENSIONS,
6070 syncer::SyncDataList(),
6071 scoped_ptr<syncer::SyncChangeProcessor>(
6072 new syncer::FakeSyncChangeProcessor),
6073 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6076 syncer::SyncDataList list =
6077 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6078 ASSERT_EQ(list.size(), 1U);
6079 scoped_ptr<ExtensionSyncData> data =
6080 ExtensionSyncData::CreateFromSyncData(list[0]);
6081 ASSERT_TRUE(data.get());
6082 EXPECT_TRUE(data->enabled());
6083 EXPECT_FALSE(data->incognito_enabled());
6084 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6087 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
6089 syncer::SyncDataList list =
6090 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6091 ASSERT_EQ(list.size(), 1U);
6092 scoped_ptr<ExtensionSyncData> data =
6093 ExtensionSyncData::CreateFromSyncData(list[0]);
6094 ASSERT_TRUE(data.get());
6095 EXPECT_FALSE(data->enabled());
6096 EXPECT_FALSE(data->incognito_enabled());
6097 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6100 extensions::util::SetIsIncognitoEnabled(good_crx, profile(), true);
6101 extensions::util::SetAllowedScriptingOnAllUrls(
6102 good_crx, profile(), false);
6104 syncer::SyncDataList list =
6105 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6106 ASSERT_EQ(list.size(), 1U);
6107 scoped_ptr<ExtensionSyncData> data =
6108 ExtensionSyncData::CreateFromSyncData(list[0]);
6109 ASSERT_TRUE(data.get());
6110 EXPECT_FALSE(data->enabled());
6111 EXPECT_TRUE(data->incognito_enabled());
6112 EXPECT_EQ(ExtensionSyncData::BOOLEAN_FALSE, data->all_urls_enabled());
6115 service()->EnableExtension(good_crx);
6116 extensions::util::SetAllowedScriptingOnAllUrls(
6117 good_crx, profile(), true);
6119 syncer::SyncDataList list =
6120 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6121 ASSERT_EQ(list.size(), 1U);
6122 scoped_ptr<ExtensionSyncData> data =
6123 ExtensionSyncData::CreateFromSyncData(list[0]);
6124 ASSERT_TRUE(data.get());
6125 EXPECT_TRUE(data->enabled());
6126 EXPECT_TRUE(data->incognito_enabled());
6127 EXPECT_EQ(ExtensionSyncData::BOOLEAN_TRUE, data->all_urls_enabled());
6131 TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
6132 InitializeEmptyExtensionService();
6133 InitializeExtensionSyncService();
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 InitializeExtensionSyncService();
6175 const Extension* app =
6176 PackAndInstallCRX(data_dir().AppendASCII("app"), INSTALL_NEW);
6177 ASSERT_TRUE(app);
6178 ASSERT_TRUE(app->is_app());
6180 syncer::FakeSyncChangeProcessor processor;
6181 extension_sync_service()->MergeDataAndStartSyncing(
6182 syncer::APPS,
6183 syncer::SyncDataList(),
6184 scoped_ptr<syncer::SyncChangeProcessor>(
6185 new syncer::FakeSyncChangeProcessor),
6186 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6188 syncer::StringOrdinal initial_ordinal =
6189 syncer::StringOrdinal::CreateInitialOrdinal();
6191 syncer::SyncDataList list =
6192 extension_sync_service()->GetAllSyncData(syncer::APPS);
6193 ASSERT_EQ(list.size(), 1U);
6195 scoped_ptr<AppSyncData> app_sync_data =
6196 AppSyncData::CreateFromSyncData(list[0]);
6197 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->app_launch_ordinal()));
6198 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6201 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
6202 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
6204 syncer::SyncDataList list =
6205 extension_sync_service()->GetAllSyncData(syncer::APPS);
6206 ASSERT_EQ(list.size(), 1U);
6208 scoped_ptr<AppSyncData> app_sync_data =
6209 AppSyncData::CreateFromSyncData(list[0]);
6210 ASSERT_TRUE(app_sync_data.get());
6211 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6212 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6215 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
6217 syncer::SyncDataList list =
6218 extension_sync_service()->GetAllSyncData(syncer::APPS);
6219 ASSERT_EQ(list.size(), 1U);
6221 scoped_ptr<AppSyncData> app_sync_data =
6222 AppSyncData::CreateFromSyncData(list[0]);
6223 ASSERT_TRUE(app_sync_data.get());
6224 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6225 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->page_ordinal()));
6229 // TODO (rdevlin.cronin): The OnExtensionMoved() method has been removed from
6230 // ExtensionService, so this test probably needs a new home. Unfortunately, it
6231 // relies pretty heavily on things like InitializeExtension[Sync]Service() and
6232 // PackAndInstallCRX(). When we clean up a bit more, this should move out.
6233 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
6234 InitializeEmptyExtensionService();
6235 InitializeExtensionSyncService();
6236 const size_t kAppCount = 3;
6237 const Extension* apps[kAppCount];
6238 apps[0] = PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
6239 apps[1] = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
6240 apps[2] = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
6241 for (size_t i = 0; i < kAppCount; ++i) {
6242 ASSERT_TRUE(apps[i]);
6243 ASSERT_TRUE(apps[i]->is_app());
6246 syncer::FakeSyncChangeProcessor processor;
6247 extension_sync_service()->MergeDataAndStartSyncing(
6248 syncer::APPS,
6249 syncer::SyncDataList(),
6250 scoped_ptr<syncer::SyncChangeProcessor>(
6251 new syncer::FakeSyncChangeProcessor),
6252 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6254 ExtensionPrefs::Get(service()->GetBrowserContext())
6255 ->app_sorting()
6256 ->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
6258 syncer::SyncDataList list =
6259 extension_sync_service()->GetAllSyncData(syncer::APPS);
6260 ASSERT_EQ(list.size(), 3U);
6262 scoped_ptr<AppSyncData> data[kAppCount];
6263 for (size_t i = 0; i < kAppCount; ++i) {
6264 data[i] = AppSyncData::CreateFromSyncData(list[i]);
6265 ASSERT_TRUE(data[i].get());
6268 // The sync data is not always in the same order our apps were installed in,
6269 // so we do that sorting here so we can make sure the values are changed as
6270 // expected.
6271 syncer::StringOrdinal app_launch_ordinals[kAppCount];
6272 for (size_t i = 0; i < kAppCount; ++i) {
6273 for (size_t j = 0; j < kAppCount; ++j) {
6274 if (apps[i]->id() == data[j]->id())
6275 app_launch_ordinals[i] = data[j]->app_launch_ordinal();
6279 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
6280 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
6284 TEST_F(ExtensionServiceTest, GetSyncDataList) {
6285 InitializeEmptyExtensionService();
6286 InitializeExtensionSyncService();
6287 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6288 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
6289 InstallCRX(data_dir().AppendASCII("theme.crx"), INSTALL_NEW);
6290 InstallCRX(data_dir().AppendASCII("theme2.crx"), INSTALL_NEW);
6292 syncer::FakeSyncChangeProcessor processor;
6293 extension_sync_service()->MergeDataAndStartSyncing(
6294 syncer::APPS,
6295 syncer::SyncDataList(),
6296 scoped_ptr<syncer::SyncChangeProcessor>(
6297 new syncer::FakeSyncChangeProcessor),
6298 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6299 extension_sync_service()->MergeDataAndStartSyncing(
6300 syncer::EXTENSIONS,
6301 syncer::SyncDataList(),
6302 scoped_ptr<syncer::SyncChangeProcessor>(
6303 new syncer::FakeSyncChangeProcessor),
6304 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6306 service()->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
6307 TerminateExtension(theme2_crx);
6309 EXPECT_EQ(0u, extension_sync_service()->GetAllSyncData(syncer::APPS).size());
6310 EXPECT_EQ(
6311 2u, extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS).size());
6314 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
6315 InitializeEmptyExtensionService();
6316 InitializeExtensionSyncService();
6317 syncer::FakeSyncChangeProcessor processor;
6318 extension_sync_service()->MergeDataAndStartSyncing(
6319 syncer::EXTENSIONS,
6320 syncer::SyncDataList(),
6321 scoped_ptr<syncer::SyncChangeProcessor>(
6322 new syncer::FakeSyncChangeProcessor),
6323 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6325 sync_pb::EntitySpecifics specifics;
6326 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6327 ext_specifics->set_id(good_crx);
6328 ext_specifics->set_version("1.0");
6329 syncer::SyncData sync_data =
6330 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6331 syncer::SyncChange sync_change(FROM_HERE,
6332 syncer::SyncChange::ACTION_DELETE,
6333 sync_data);
6334 syncer::SyncChangeList list(1);
6335 list[0] = sync_change;
6337 // Should do nothing.
6338 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6339 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6341 // Install the extension.
6342 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6343 InstallCRX(extension_path, INSTALL_NEW);
6344 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6346 // Should uninstall the extension.
6347 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6348 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6350 // Should again do nothing.
6351 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6352 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6355 TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
6356 InitializeEmptyExtensionService();
6357 InitializeExtensionSyncService();
6359 // Install the extension.
6360 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6361 InstallCRX(extension_path, INSTALL_NEW);
6362 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6364 sync_pb::EntitySpecifics specifics;
6365 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6366 sync_pb::ExtensionSpecifics* extension_specifics =
6367 app_specifics->mutable_extension();
6368 extension_specifics->set_id(good_crx);
6369 extension_specifics->set_version(
6370 service()->GetInstalledExtension(good_crx)->version()->GetString());
6373 extension_specifics->set_enabled(true);
6374 syncer::SyncData sync_data =
6375 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6376 syncer::SyncChange sync_change(FROM_HERE,
6377 syncer::SyncChange::ACTION_DELETE,
6378 sync_data);
6379 syncer::SyncChangeList list(1);
6380 list[0] = sync_change;
6382 // Should do nothing
6383 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6384 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6388 extension_specifics->set_enabled(false);
6389 syncer::SyncData sync_data =
6390 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6391 syncer::SyncChange sync_change(FROM_HERE,
6392 syncer::SyncChange::ACTION_UPDATE,
6393 sync_data);
6394 syncer::SyncChangeList list(1);
6395 list[0] = sync_change;
6397 // Should again do nothing.
6398 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6399 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
6403 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
6404 InitializeEmptyExtensionService();
6405 InitializeExtensionSyncService();
6406 syncer::FakeSyncChangeProcessor processor;
6407 extension_sync_service()->MergeDataAndStartSyncing(
6408 syncer::EXTENSIONS,
6409 syncer::SyncDataList(),
6410 scoped_ptr<syncer::SyncChangeProcessor>(
6411 new syncer::FakeSyncChangeProcessor),
6412 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6414 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6415 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6416 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6417 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6418 good_crx, profile()));
6419 const bool kDefaultAllowedScripting =
6420 extensions::util::DefaultAllowedScriptingOnAllUrls();
6421 EXPECT_EQ(kDefaultAllowedScripting,
6422 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6424 sync_pb::EntitySpecifics specifics;
6425 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6426 ext_specifics->set_id(good_crx);
6427 ext_specifics->set_version(
6428 service()->GetInstalledExtension(good_crx)->version()->GetString());
6429 ext_specifics->set_enabled(false);
6432 syncer::SyncData sync_data =
6433 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6434 syncer::SyncChange sync_change(FROM_HERE,
6435 syncer::SyncChange::ACTION_UPDATE,
6436 sync_data);
6437 syncer::SyncChangeList list(1);
6438 list[0] = sync_change;
6439 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6440 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6441 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6442 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6443 good_crx, profile()));
6444 EXPECT_EQ(kDefaultAllowedScripting,
6445 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6449 ext_specifics->set_enabled(true);
6450 ext_specifics->set_incognito_enabled(true);
6451 syncer::SyncData sync_data =
6452 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6453 syncer::SyncChange sync_change(FROM_HERE,
6454 syncer::SyncChange::ACTION_UPDATE,
6455 sync_data);
6456 syncer::SyncChangeList list(1);
6457 list[0] = sync_change;
6458 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6459 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6460 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6464 ext_specifics->set_enabled(false);
6465 ext_specifics->set_incognito_enabled(true);
6466 syncer::SyncData sync_data =
6467 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6468 syncer::SyncChange sync_change(FROM_HERE,
6469 syncer::SyncChange::ACTION_UPDATE,
6470 sync_data);
6471 syncer::SyncChangeList list(1);
6472 list[0] = sync_change;
6473 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6474 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6475 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6479 ext_specifics->set_enabled(true);
6480 ext_specifics->set_all_urls_enabled(!kDefaultAllowedScripting);
6481 syncer::SyncData sync_data =
6482 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6483 syncer::SyncChange sync_change(FROM_HERE,
6484 syncer::SyncChange::ACTION_UPDATE,
6485 sync_data);
6486 syncer::SyncChangeList list(1);
6487 list[0] = sync_change;
6488 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6489 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6490 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6491 good_crx, profile()));
6492 EXPECT_EQ(!kDefaultAllowedScripting,
6493 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6497 ext_specifics->set_all_urls_enabled(kDefaultAllowedScripting);
6498 syncer::SyncData sync_data =
6499 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6500 syncer::SyncChange sync_change(FROM_HERE,
6501 syncer::SyncChange::ACTION_UPDATE,
6502 sync_data);
6503 syncer::SyncChangeList list(1);
6504 list[0] = sync_change;
6505 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6506 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6507 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6508 good_crx, profile()));
6509 EXPECT_EQ(kDefaultAllowedScripting,
6510 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6513 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6516 TEST_F(ExtensionServiceTest, ProcessSyncDataNewExtension) {
6517 InitializeEmptyExtensionService();
6518 InitializeExtensionSyncService();
6519 syncer::FakeSyncChangeProcessor processor;
6520 extension_sync_service()->MergeDataAndStartSyncing(
6521 syncer::EXTENSIONS,
6522 syncer::SyncDataList(),
6523 scoped_ptr<syncer::SyncChangeProcessor>(
6524 new syncer::FakeSyncChangeProcessor),
6525 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6527 const base::FilePath path = data_dir().AppendASCII("good.crx");
6528 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6530 struct TestCase {
6531 const char* name; // For failure output only.
6532 bool sync_enabled; // The "enabled" flag coming in from Sync.
6533 // The disable reason(s) coming in from Sync, or -1 for "not set".
6534 int sync_disable_reasons;
6535 // The disable reason(s) that should be set on the installed extension.
6536 // This will usually be the same as |sync_disable_reasons|, but see the
6537 // "Legacy" case.
6538 int expect_disable_reasons;
6539 // Whether the extension's permissions should be auto-granted during
6540 // installation.
6541 bool expect_permissions_granted;
6542 } test_cases[] = {
6543 // Standard case: Extension comes in enabled; permissions should be granted
6544 // during installation.
6545 { "Standard", true, 0, 0, true },
6546 // If the extension comes in disabled, its permissions should still be
6547 // granted (the user already approved them on another machine).
6548 { "Disabled", false, Extension::DISABLE_USER_ACTION,
6549 Extension::DISABLE_USER_ACTION, true },
6550 // Legacy case (<M45): No disable reasons come in from Sync (see
6551 // crbug.com/484214). After installation, the reason should be set to
6552 // DISABLE_UNKNOWN_FROM_SYNC.
6553 { "Legacy", false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC, true },
6554 // If the extension came in disabled due to a permissions increase, then the
6555 // user has *not* approved the permissions, and they shouldn't be granted.
6556 // crbug.com/484214
6557 { "PermissionsIncrease", false, Extension::DISABLE_PERMISSIONS_INCREASE,
6558 Extension::DISABLE_PERMISSIONS_INCREASE, false },
6561 for (const TestCase& test_case : test_cases) {
6562 SCOPED_TRACE(test_case.name);
6564 sync_pb::EntitySpecifics specifics;
6565 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6566 ext_specifics->set_id(good_crx);
6567 ext_specifics->set_version(base::Version("1").GetString());
6568 ext_specifics->set_enabled(test_case.sync_enabled);
6569 if (test_case.sync_disable_reasons != -1)
6570 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6572 syncer::SyncData sync_data =
6573 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6574 syncer::SyncChange sync_change(FROM_HERE,
6575 syncer::SyncChange::ACTION_UPDATE,
6576 sync_data);
6577 syncer::SyncChangeList list(1, sync_change);
6578 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6580 ASSERT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
6581 UpdateExtension(good_crx, path, test_case.sync_enabled ? ENABLED
6582 : DISABLED);
6583 EXPECT_EQ(test_case.expect_disable_reasons,
6584 prefs->GetDisableReasons(good_crx));
6585 scoped_refptr<PermissionSet> permissions(
6586 prefs->GetGrantedPermissions(good_crx));
6587 EXPECT_EQ(test_case.expect_permissions_granted, !permissions->IsEmpty());
6588 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6590 // Remove the extension again, so we can install it again for the next case.
6591 UninstallExtension(good_crx, false,
6592 test_case.sync_enabled ? Extension::ENABLED
6593 : Extension::DISABLED);
6597 TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
6598 InitializeExtensionServiceWithUpdater();
6599 InitializeExtensionSyncService();
6600 syncer::FakeSyncChangeProcessor processor;
6601 extension_sync_service()->MergeDataAndStartSyncing(
6602 syncer::EXTENSIONS,
6603 syncer::SyncDataList(),
6604 scoped_ptr<syncer::SyncChangeProcessor>(
6605 new syncer::FakeSyncChangeProcessor),
6606 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6608 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6609 TerminateExtension(good_crx);
6610 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6611 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6613 sync_pb::EntitySpecifics specifics;
6614 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6615 ext_specifics->set_id(good_crx);
6616 ext_specifics->set_version(
6617 service()->GetInstalledExtension(good_crx)->version()->GetString());
6618 ext_specifics->set_enabled(false);
6619 ext_specifics->set_incognito_enabled(true);
6620 syncer::SyncData sync_data =
6621 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6622 syncer::SyncChange sync_change(FROM_HERE,
6623 syncer::SyncChange::ACTION_UPDATE,
6624 sync_data);
6625 syncer::SyncChangeList list(1);
6626 list[0] = sync_change;
6628 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6629 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6630 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6632 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6635 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
6636 InitializeExtensionServiceWithUpdater();
6637 InitializeExtensionSyncService();
6638 syncer::FakeSyncChangeProcessor processor;
6639 extension_sync_service()->MergeDataAndStartSyncing(
6640 syncer::EXTENSIONS,
6641 syncer::SyncDataList(),
6642 scoped_ptr<syncer::SyncChangeProcessor>(
6643 new syncer::FakeSyncChangeProcessor),
6644 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6646 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6647 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6648 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6650 sync_pb::EntitySpecifics specifics;
6651 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6652 ext_specifics->set_id(good_crx);
6653 ext_specifics->set_enabled(true);
6656 ext_specifics->set_version(
6657 service()->GetInstalledExtension(good_crx)->version()->GetString());
6658 syncer::SyncData sync_data =
6659 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6660 syncer::SyncChange sync_change(FROM_HERE,
6661 syncer::SyncChange::ACTION_UPDATE,
6662 sync_data);
6663 syncer::SyncChangeList list(1);
6664 list[0] = sync_change;
6666 // Should do nothing if extension version == sync version.
6667 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6668 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6671 // Should do nothing if extension version > sync version (but see
6672 // the TODO in ProcessExtensionSyncData).
6674 ext_specifics->set_version("0.0.0.0");
6675 syncer::SyncData sync_data =
6676 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6677 syncer::SyncChange sync_change(FROM_HERE,
6678 syncer::SyncChange::ACTION_UPDATE,
6679 sync_data);
6680 syncer::SyncChangeList list(1);
6681 list[0] = sync_change;
6683 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6684 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6687 // Should kick off an update if extension version < sync version.
6689 ext_specifics->set_version("9.9.9.9");
6690 syncer::SyncData sync_data =
6691 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6692 syncer::SyncChange sync_change(FROM_HERE,
6693 syncer::SyncChange::ACTION_UPDATE,
6694 sync_data);
6695 syncer::SyncChangeList list(1);
6696 list[0] = sync_change;
6698 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6699 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6702 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6705 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
6706 InitializeExtensionServiceWithUpdater();
6707 InitializeExtensionSyncService();
6708 syncer::FakeSyncChangeProcessor processor;
6709 extension_sync_service()->MergeDataAndStartSyncing(
6710 syncer::EXTENSIONS,
6711 syncer::SyncDataList(),
6712 scoped_ptr<syncer::SyncChangeProcessor>(
6713 new syncer::FakeSyncChangeProcessor),
6714 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6716 sync_pb::EntitySpecifics specifics;
6717 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6718 ext_specifics->set_id(good_crx);
6719 ext_specifics->set_enabled(false);
6720 ext_specifics->set_incognito_enabled(true);
6721 ext_specifics->set_update_url("http://www.google.com/");
6722 ext_specifics->set_version("1.2.3.4");
6723 syncer::SyncData sync_data =
6724 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6725 syncer::SyncChange sync_change(FROM_HERE,
6726 syncer::SyncChange::ACTION_UPDATE,
6727 sync_data);
6728 syncer::SyncChangeList list(1);
6729 list[0] = sync_change;
6731 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6732 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6733 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6734 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6735 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6736 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6738 const extensions::PendingExtensionInfo* info;
6739 EXPECT_TRUE(
6740 (info = service()->pending_extension_manager()->GetById(good_crx)));
6741 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
6742 EXPECT_TRUE(info->is_from_sync());
6743 EXPECT_EQ(Manifest::INTERNAL, info->install_source());
6744 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
6747 TEST_F(ExtensionServiceTest, ProcessSyncDataEnableDisable) {
6748 InitializeEmptyExtensionService();
6749 InitializeExtensionSyncService();
6750 extension_sync_service()->MergeDataAndStartSyncing(
6751 syncer::EXTENSIONS,
6752 syncer::SyncDataList(),
6753 scoped_ptr<syncer::SyncChangeProcessor>(
6754 new syncer::FakeSyncChangeProcessor),
6755 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6757 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6759 struct TestCase {
6760 const char* name; // For failure output only.
6761 // Set of disable reasons before any Sync data comes in. If this is != 0,
6762 // the extension is disabled.
6763 int previous_disable_reasons;
6764 bool sync_enable; // The enabled flag coming in from Sync.
6765 // The disable reason(s) coming in from Sync, or -1 for "not set".
6766 int sync_disable_reasons;
6767 // The expected set of disable reasons after processing the Sync update. The
6768 // extension should be disabled iff this is != 0.
6769 int expect_disable_reasons;
6770 } test_cases[] = {
6771 { "NopEnable", 0, true, 0, 0 },
6772 { "NopDisable", Extension::DISABLE_USER_ACTION, false,
6773 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6774 { "Disable", 0, false, Extension::DISABLE_USER_ACTION,
6775 Extension::DISABLE_USER_ACTION },
6776 { "DisableLegacy", 0, false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC },
6777 { "AddDisableReason", Extension::DISABLE_REMOTE_INSTALL, false,
6778 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION,
6779 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION },
6780 { "AddDisableReasonLegacy", Extension::DISABLE_USER_ACTION, false, -1,
6781 Extension::DISABLE_USER_ACTION | Extension::DISABLE_UNKNOWN_FROM_SYNC},
6782 { "RemoveDisableReason",
6783 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION, false,
6784 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6785 { "Enable", Extension::DISABLE_USER_ACTION, true, 0, 0 },
6786 { "EnableLegacy", Extension::DISABLE_USER_ACTION, true, -1, 0 },
6789 for (const TestCase& test_case : test_cases) {
6790 SCOPED_TRACE(test_case.name);
6792 std::string id;
6793 std::string version;
6794 // Don't keep |extension| around longer than necessary.
6796 const Extension* extension =
6797 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6798 // The extension should now be installed and enabled.
6799 ASSERT_TRUE(extension);
6800 id = extension->id();
6801 version = extension->VersionString();
6803 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6805 // Disable it if the test case says so.
6806 if (test_case.previous_disable_reasons) {
6807 service()->DisableExtension(id, test_case.previous_disable_reasons);
6808 ASSERT_TRUE(registry()->disabled_extensions().Contains(id));
6811 // Now a sync update comes in.
6812 sync_pb::EntitySpecifics specifics;
6813 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6814 ext_specifics->set_id(id);
6815 ext_specifics->set_enabled(test_case.sync_enable);
6816 ext_specifics->set_version(version);
6817 if (test_case.sync_disable_reasons != -1)
6818 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6820 syncer::SyncData sync_data =
6821 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6822 syncer::SyncChange sync_change(FROM_HERE,
6823 syncer::SyncChange::ACTION_UPDATE,
6824 sync_data);
6825 syncer::SyncChangeList list(1, sync_change);
6826 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6828 // Check expectations.
6829 const bool expect_enabled = !test_case.expect_disable_reasons;
6830 EXPECT_EQ(expect_enabled, service()->IsExtensionEnabled(id));
6831 EXPECT_EQ(test_case.expect_disable_reasons, prefs->GetDisableReasons(id));
6833 // Remove the extension again, so we can install it again for the next case.
6834 UninstallExtension(id, false, expect_enabled ? Extension::ENABLED
6835 : Extension::DISABLED);
6839 TEST_F(ExtensionServiceTest, ProcessSyncDataPermissionApproval) {
6840 // This is the update URL specified in the test extension. Setting it here is
6841 // necessary to make it considered syncable.
6842 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6843 switches::kAppsGalleryUpdateURL,
6844 "http://localhost/autoupdate/updates.xml");
6846 InitializeEmptyExtensionService();
6847 InitializeExtensionSyncService();
6848 extension_sync_service()->MergeDataAndStartSyncing(
6849 syncer::EXTENSIONS,
6850 syncer::SyncDataList(),
6851 scoped_ptr<syncer::SyncChangeProcessor>(
6852 new syncer::FakeSyncChangeProcessor),
6853 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6855 const base::FilePath base_path =
6856 data_dir().AppendASCII("permissions_increase");
6857 const base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
6858 const base::FilePath path_v1 = base_path.AppendASCII("v1");
6859 const base::FilePath path_v2 = base_path.AppendASCII("v2");
6861 base::ScopedTempDir crx_dir;
6862 ASSERT_TRUE(crx_dir.CreateUniqueTempDir());
6863 const base::FilePath crx_path_v1 = crx_dir.path().AppendASCII("temp1.crx");
6864 PackCRX(path_v1, pem_path, crx_path_v1);
6865 const base::FilePath crx_path_v2 = crx_dir.path().AppendASCII("temp2.crx");
6866 PackCRX(path_v2, pem_path, crx_path_v2);
6868 const std::string v1("1");
6869 const std::string v2("2");
6871 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6873 struct TestCase {
6874 const char* name; // For failure output only.
6875 const std::string& sync_version; // The version coming in from Sync.
6876 // The disable reason(s) coming in from Sync, or -1 for "not set".
6877 int sync_disable_reasons;
6878 // Whether the extension's permissions should be auto-granted.
6879 bool expect_permissions_granted;
6880 } test_cases[] = {
6881 // Sync tells us to re-enable an older version. No permissions should be
6882 // granted, since we can't be sure if the user actually approved the right
6883 // set of permissions. Note that the extension will get disabled again the
6884 // next time ExtensionService::CheckPermissionsIncrease runs because of the
6885 // extra permissions.
6886 { "OldVersion", v1, 0, false },
6887 // Legacy case: Sync tells us to re-enable the extension, but doesn't
6888 // specify disable reasons. No permissions should be granted.
6889 { "Legacy", v2, -1, false },
6890 // Sync tells us to re-enable the extension and explicitly removes the
6891 // disable reasons. Now the extension should have its permissions granted.
6892 { "GrantPermissions", v2, 0, true },
6895 for (const TestCase& test_case : test_cases) {
6896 SCOPED_TRACE(test_case.name);
6898 std::string id;
6899 // Don't keep |extension| around longer than necessary (it'll be destroyed
6900 // during updating).
6902 const Extension* extension = InstallCRX(crx_path_v1, INSTALL_NEW);
6903 // The extension should now be installed and enabled.
6904 ASSERT_TRUE(extension);
6905 ASSERT_EQ(v1, extension->VersionString());
6906 id = extension->id();
6908 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6910 scoped_refptr<PermissionSet> granted_permissions_v1(
6911 prefs->GetGrantedPermissions(id));
6913 // Update to a new version with increased permissions.
6914 UpdateExtension(id, crx_path_v2, DISABLED);
6916 // Now the extension should be disabled due to a permissions increase.
6918 const Extension* extension =
6919 registry()->disabled_extensions().GetByID(id);
6920 ASSERT_TRUE(extension);
6921 ASSERT_EQ(v2, extension->VersionString());
6923 ASSERT_TRUE(prefs->HasDisableReason(
6924 id, Extension::DISABLE_PERMISSIONS_INCREASE));
6926 // No new permissions should have been granted.
6927 scoped_refptr<PermissionSet> granted_permissions_v2(
6928 prefs->GetGrantedPermissions(id));
6929 ASSERT_EQ(*granted_permissions_v1, *granted_permissions_v2);
6931 // Now a sync update comes in.
6932 sync_pb::EntitySpecifics specifics;
6933 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6934 ext_specifics->set_id(id);
6935 ext_specifics->set_enabled(true);
6936 ext_specifics->set_version(test_case.sync_version);
6937 if (test_case.sync_disable_reasons != -1)
6938 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6940 syncer::SyncData sync_data =
6941 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6942 syncer::SyncChange sync_change(FROM_HERE,
6943 syncer::SyncChange::ACTION_UPDATE,
6944 sync_data);
6945 syncer::SyncChangeList list(1, sync_change);
6946 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6948 // Check expectations.
6949 EXPECT_TRUE(registry()->GetExtensionById(id, ExtensionRegistry::ENABLED));
6950 scoped_refptr<PermissionSet> granted_permissions(
6951 prefs->GetGrantedPermissions(id));
6952 if (test_case.expect_permissions_granted) {
6953 scoped_refptr<PermissionSet> active_permissions(
6954 prefs->GetActivePermissions(id));
6955 EXPECT_EQ(*granted_permissions, *active_permissions);
6956 } else {
6957 EXPECT_EQ(*granted_permissions, *granted_permissions_v1);
6959 EXPECT_EQ(Extension::DISABLE_NONE, prefs->GetDisableReasons(id));
6961 // Remove the extension again, so we can install it again for the next case.
6962 UninstallExtension(id, false);
6966 #if defined(ENABLE_SUPERVISED_USERS)
6967 class ScopedSupervisedUserServiceDelegate
6968 : public SupervisedUserService::Delegate {
6969 public:
6970 explicit ScopedSupervisedUserServiceDelegate(SupervisedUserService* service)
6971 : service_(service) {
6972 service_->SetDelegate(this);
6974 ~ScopedSupervisedUserServiceDelegate() override {
6975 service_->SetDelegate(nullptr);
6978 // This prevents the legacy supervised user init code from running.
6979 bool SetActive(bool active) override { return true; }
6981 private:
6982 SupervisedUserService* service_;
6985 class MockPermissionRequestCreator : public PermissionRequestCreator {
6986 public:
6987 MockPermissionRequestCreator() {}
6988 ~MockPermissionRequestCreator() override {}
6990 bool IsEnabled() const override { return true; }
6992 void CreateURLAccessRequest(const GURL& url_requested,
6993 const SuccessCallback& callback) override {
6994 FAIL();
6997 MOCK_METHOD2(CreateExtensionUpdateRequest,
6998 void(const std::string& id,
6999 const SupervisedUserService::SuccessCallback& callback));
7001 private:
7002 DISALLOW_COPY_AND_ASSIGN(MockPermissionRequestCreator);
7005 TEST_F(ExtensionServiceTest, SupervisedUser_InstallOnlyAllowedByCustodian) {
7006 ExtensionServiceInitParams params = CreateDefaultInitParams();
7007 params.profile_is_supervised = true;
7008 InitializeExtensionService(params);
7010 SupervisedUserService* supervised_user_service =
7011 SupervisedUserServiceFactory::GetForProfile(profile());
7012 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7013 supervised_user_service->Init();
7015 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7016 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7017 const Extension* extensions[] = {
7018 InstallCRX(path1, INSTALL_FAILED),
7019 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7022 // Only the extension with the "installed by custodian" flag should have been
7023 // installed and enabled.
7024 EXPECT_FALSE(extensions[0]);
7025 ASSERT_TRUE(extensions[1]);
7026 EXPECT_TRUE(registry()->enabled_extensions().Contains(extensions[1]->id()));
7029 TEST_F(ExtensionServiceTest, SupervisedUser_PreinstalledExtension) {
7030 ExtensionServiceInitParams params = CreateDefaultInitParams();
7031 // Do *not* set the profile to supervised here!
7032 InitializeExtensionService(params);
7034 SupervisedUserService* supervised_user_service =
7035 SupervisedUserServiceFactory::GetForProfile(profile());
7036 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7037 supervised_user_service->Init();
7039 // Install an extension.
7040 base::FilePath path = data_dir().AppendASCII("good.crx");
7041 const Extension* extension = InstallCRX(path, INSTALL_NEW);
7042 std::string id = extension->id();
7044 // Now make the profile supervised.
7045 profile()->AsTestingProfile()->SetSupervisedUserId(
7046 supervised_users::kChildAccountSUID);
7048 // The extension should not be enabled anymore.
7049 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7052 TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithoutPermissionIncrease) {
7053 ExtensionServiceInitParams params = CreateDefaultInitParams();
7054 params.profile_is_supervised = true;
7055 InitializeExtensionService(params);
7057 SupervisedUserService* supervised_user_service =
7058 SupervisedUserServiceFactory::GetForProfile(profile());
7059 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7060 supervised_user_service->Init();
7062 base::FilePath base_path = data_dir().AppendASCII("autoupdate");
7063 base::FilePath pem_path = base_path.AppendASCII("key.pem");
7065 base::FilePath path = base_path.AppendASCII("v1");
7066 const Extension* extension =
7067 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
7068 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7069 // The extension must now be installed and enabled.
7070 ASSERT_TRUE(extension);
7071 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7073 // Save the id, as the extension object will be destroyed during updating.
7074 std::string id = extension->id();
7076 std::string old_version = extension->VersionString();
7078 // Update to a new version.
7079 path = base_path.AppendASCII("v2");
7080 PackCRXAndUpdateExtension(id, path, pem_path, ENABLED);
7082 // The extension should still be there and enabled.
7083 extension = registry()->enabled_extensions().GetByID(id);
7084 ASSERT_TRUE(extension);
7085 // The version should have changed.
7086 EXPECT_NE(extension->VersionString(), old_version);
7089 TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithPermissionIncrease) {
7090 ExtensionServiceInitParams params = CreateDefaultInitParams();
7091 params.profile_is_supervised = true;
7092 InitializeExtensionService(params);
7094 SupervisedUserService* supervised_user_service =
7095 SupervisedUserServiceFactory::GetForProfile(profile());
7096 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7097 supervised_user_service->Init();
7098 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
7099 supervised_user_service->AddPermissionRequestCreator(
7100 make_scoped_ptr(creator));
7102 base::FilePath base_path = data_dir().AppendASCII("permissions_increase");
7103 base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
7105 base::FilePath path = base_path.AppendASCII("v1");
7106 const Extension* extension =
7107 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
7108 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7109 // The extension must now be installed and enabled.
7110 ASSERT_TRUE(extension);
7111 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7113 // Save the id, as the extension object will be destroyed during updating.
7114 std::string id = extension->id();
7116 std::string old_version = extension->VersionString();
7118 // Update to a new version with increased permissions.
7119 EXPECT_CALL(*creator,
7120 CreateExtensionUpdateRequest(id + ":2", testing::_));
7121 path = base_path.AppendASCII("v2");
7122 PackCRXAndUpdateExtension(id, path, pem_path, DISABLED);
7124 // The extension should still be there, but disabled.
7125 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7126 extension = registry()->disabled_extensions().GetByID(id);
7127 ASSERT_TRUE(extension);
7128 // The version should have changed.
7129 EXPECT_NE(extension->VersionString(), old_version);
7132 TEST_F(ExtensionServiceTest,
7133 SupervisedUser_SyncUninstallByCustodianSkipsPolicy) {
7134 InitializeEmptyExtensionService();
7135 InitializeExtensionSyncService();
7136 extension_sync_service()->MergeDataAndStartSyncing(
7137 syncer::EXTENSIONS,
7138 syncer::SyncDataList(),
7139 scoped_ptr<syncer::SyncChangeProcessor>(
7140 new syncer::FakeSyncChangeProcessor),
7141 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
7143 // Install two extensions.
7144 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7145 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7146 const Extension* extensions[] = {
7147 InstallCRX(path1, INSTALL_NEW),
7148 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7151 // Add a policy provider that will disallow any changes.
7152 extensions::TestManagementPolicyProvider provider(
7153 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
7154 GetManagementPolicy()->RegisterProvider(&provider);
7156 // Create a sync deletion for each extension.
7157 syncer::SyncChangeList change_list;
7158 for (size_t i = 0; i < arraysize(extensions); i++) {
7159 const std::string& id = extensions[i]->id();
7160 sync_pb::EntitySpecifics specifics;
7161 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
7162 ext_specifics->set_id(id);
7163 ext_specifics->set_version("1.0");
7164 ext_specifics->set_installed_by_custodian(
7165 extensions[i]->was_installed_by_custodian());
7166 syncer::SyncData sync_data =
7167 syncer::SyncData::CreateLocalData(id, "Name", specifics);
7168 change_list.push_back(syncer::SyncChange(FROM_HERE,
7169 syncer::SyncChange::ACTION_DELETE,
7170 sync_data));
7173 // Save the extension ids, as uninstalling destroys the Extension instance.
7174 std::string extension_ids[] = {
7175 extensions[0]->id(),
7176 extensions[1]->id()
7179 // Now apply the uninstallations.
7180 extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
7182 // Uninstalling the extension without installed_by_custodian should have been
7183 // blocked by policy, so it should still be there.
7184 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_ids[0]));
7186 // But installed_by_custodian should result in bypassing the policy check.
7187 EXPECT_FALSE(
7188 registry()->GenerateInstalledExtensionsSet()->Contains(extension_ids[1]));
7190 #endif // defined(ENABLE_SUPERVISED_USERS)
7192 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
7193 InitializeEmptyExtensionService();
7195 base::FilePath path = data_dir().AppendASCII("good.crx");
7196 InstallCRX(path, INSTALL_NEW);
7197 ValidatePrefKeyCount(1u);
7198 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7199 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7201 extensions::PendingExtensionManager* pending =
7202 service()->pending_extension_manager();
7203 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7205 // Skip install when the location is the same.
7206 EXPECT_FALSE(
7207 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
7208 std::string(),
7209 GURL(kGoodUpdateURL),
7210 Manifest::INTERNAL,
7211 Extension::NO_FLAGS,
7212 false));
7213 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7215 // Install when the location has higher priority.
7216 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
7217 kGoodId,
7218 std::string(),
7219 GURL(kGoodUpdateURL),
7220 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7221 Extension::NO_FLAGS,
7222 false));
7223 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7225 // Try the low priority again. Should be rejected.
7226 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(
7227 kGoodId,
7228 std::string(),
7229 GURL(kGoodUpdateURL),
7230 Manifest::EXTERNAL_PREF_DOWNLOAD,
7231 Extension::NO_FLAGS,
7232 false));
7233 // The existing record should still be present in the pending extension
7234 // manager.
7235 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7237 pending->Remove(kGoodId);
7239 // Skip install when the location has the same priority as the installed
7240 // location.
7241 EXPECT_FALSE(
7242 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
7243 std::string(),
7244 GURL(kGoodUpdateURL),
7245 Manifest::INTERNAL,
7246 Extension::NO_FLAGS,
7247 false));
7249 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7252 TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
7253 Version older_version("0.1.0.0");
7254 Version newer_version("2.0.0.0");
7256 // We don't want the extension to be installed. A path that doesn't
7257 // point to a valid CRX ensures this.
7258 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
7260 const int kCreationFlags = 0;
7261 const bool kDontMarkAcknowledged = false;
7262 const bool kDontInstallImmediately = false;
7264 InitializeEmptyExtensionService();
7266 // The test below uses install source constants to test that
7267 // priority is enforced. It assumes a specific ranking of install
7268 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
7269 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
7270 // The following assertions verify these assumptions:
7271 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
7272 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
7273 Manifest::EXTERNAL_PREF));
7274 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
7275 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
7276 Manifest::INTERNAL));
7277 ASSERT_EQ(Manifest::EXTERNAL_PREF,
7278 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
7279 Manifest::INTERNAL));
7281 extensions::PendingExtensionManager* pending =
7282 service()->pending_extension_manager();
7283 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7286 // Simulate an external source adding the extension as INTERNAL.
7287 content::WindowedNotificationObserver observer(
7288 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7289 content::NotificationService::AllSources());
7290 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7291 kGoodId,
7292 &older_version,
7293 kInvalidPathToCrx,
7294 Manifest::INTERNAL,
7295 kCreationFlags,
7296 kDontMarkAcknowledged,
7297 kDontInstallImmediately));
7298 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7299 observer.Wait();
7300 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7304 // Simulate an external source adding the extension as EXTERNAL_PREF.
7305 content::WindowedNotificationObserver observer(
7306 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7307 content::NotificationService::AllSources());
7308 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7309 kGoodId,
7310 &older_version,
7311 kInvalidPathToCrx,
7312 Manifest::EXTERNAL_PREF,
7313 kCreationFlags,
7314 kDontMarkAcknowledged,
7315 kDontInstallImmediately));
7316 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7317 observer.Wait();
7318 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7321 // Simulate an external source adding as EXTERNAL_PREF again.
7322 // This is rejected because the version and the location are the same as
7323 // the previous installation, which is still pending.
7324 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7325 kGoodId,
7326 &older_version,
7327 kInvalidPathToCrx,
7328 Manifest::EXTERNAL_PREF,
7329 kCreationFlags,
7330 kDontMarkAcknowledged,
7331 kDontInstallImmediately));
7332 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7334 // Try INTERNAL again. Should fail.
7335 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7336 kGoodId,
7337 &older_version,
7338 kInvalidPathToCrx,
7339 Manifest::INTERNAL,
7340 kCreationFlags,
7341 kDontMarkAcknowledged,
7342 kDontInstallImmediately));
7343 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7346 // Now the registry adds the extension.
7347 content::WindowedNotificationObserver observer(
7348 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7349 content::NotificationService::AllSources());
7350 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7351 kGoodId,
7352 &older_version,
7353 kInvalidPathToCrx,
7354 Manifest::EXTERNAL_REGISTRY,
7355 kCreationFlags,
7356 kDontMarkAcknowledged,
7357 kDontInstallImmediately));
7358 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7359 observer.Wait();
7360 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7363 // Registry outranks both external pref and internal, so both fail.
7364 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7365 kGoodId,
7366 &older_version,
7367 kInvalidPathToCrx,
7368 Manifest::EXTERNAL_PREF,
7369 kCreationFlags,
7370 kDontMarkAcknowledged,
7371 kDontInstallImmediately));
7372 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7374 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7375 kGoodId,
7376 &older_version,
7377 kInvalidPathToCrx,
7378 Manifest::INTERNAL,
7379 kCreationFlags,
7380 kDontMarkAcknowledged,
7381 kDontInstallImmediately));
7382 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7384 pending->Remove(kGoodId);
7386 // Install the extension.
7387 base::FilePath path = data_dir().AppendASCII("good.crx");
7388 const Extension* ext = InstallCRX(path, INSTALL_NEW);
7389 ValidatePrefKeyCount(1u);
7390 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7391 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7393 // Now test the logic of OnExternalExtensionFileFound() when the extension
7394 // being added is already installed.
7396 // Tests assume |older_version| is less than the installed version, and
7397 // |newer_version| is greater. Verify this:
7398 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
7399 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
7401 // An external install for the same location should fail if the version is
7402 // older, or the same, and succeed if the version is newer.
7404 // Older than the installed version...
7405 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7406 kGoodId,
7407 &older_version,
7408 kInvalidPathToCrx,
7409 Manifest::INTERNAL,
7410 kCreationFlags,
7411 kDontMarkAcknowledged,
7412 kDontInstallImmediately));
7413 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7415 // Same version as the installed version...
7416 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7417 kGoodId,
7418 ext->version(),
7419 kInvalidPathToCrx,
7420 Manifest::INTERNAL,
7421 kCreationFlags,
7422 kDontMarkAcknowledged,
7423 kDontInstallImmediately));
7424 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7426 // Newer than the installed version...
7427 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7428 kGoodId,
7429 &newer_version,
7430 kInvalidPathToCrx,
7431 Manifest::INTERNAL,
7432 kCreationFlags,
7433 kDontMarkAcknowledged,
7434 kDontInstallImmediately));
7435 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7437 // An external install for a higher priority install source should succeed
7438 // if the version is greater. |older_version| is not...
7439 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7440 kGoodId,
7441 &older_version,
7442 kInvalidPathToCrx,
7443 Manifest::EXTERNAL_PREF,
7444 kCreationFlags,
7445 kDontMarkAcknowledged,
7446 kDontInstallImmediately));
7447 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7449 // |newer_version| is newer.
7450 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7451 kGoodId,
7452 &newer_version,
7453 kInvalidPathToCrx,
7454 Manifest::EXTERNAL_PREF,
7455 kCreationFlags,
7456 kDontMarkAcknowledged,
7457 kDontInstallImmediately));
7458 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7460 // An external install for an even higher priority install source should
7461 // succeed if the version is greater.
7462 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7463 kGoodId,
7464 &newer_version,
7465 kInvalidPathToCrx,
7466 Manifest::EXTERNAL_REGISTRY,
7467 kCreationFlags,
7468 kDontMarkAcknowledged,
7469 kDontInstallImmediately));
7470 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7472 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
7473 // adding from external pref will now fail.
7474 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7475 kGoodId,
7476 &newer_version,
7477 kInvalidPathToCrx,
7478 Manifest::EXTERNAL_PREF,
7479 kCreationFlags,
7480 kDontMarkAcknowledged,
7481 kDontInstallImmediately));
7482 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7485 TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
7486 Version kVersion123("1.2.3");
7487 Version kVersion124("1.2.4");
7488 Version kVersion125("1.2.5");
7489 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
7490 const int kCreationFlags = 0;
7491 const bool kDontMarkAcknowledged = false;
7492 const bool kDontInstallImmediately = false;
7494 InitializeEmptyExtensionService();
7496 extensions::PendingExtensionManager* pending =
7497 service()->pending_extension_manager();
7498 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7500 // An external provider starts installing from a local crx.
7501 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7502 kGoodId,
7503 &kVersion123,
7504 kInvalidPathToCrx,
7505 Manifest::EXTERNAL_PREF,
7506 kCreationFlags,
7507 kDontMarkAcknowledged,
7508 kDontInstallImmediately));
7509 const extensions::PendingExtensionInfo* info;
7510 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7511 EXPECT_TRUE(info->version().IsValid());
7512 EXPECT_TRUE(info->version().Equals(kVersion123));
7514 // Adding a newer version overrides the currently pending version.
7515 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7516 kGoodId,
7517 &kVersion124,
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.
7528 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7529 kGoodId,
7530 &kVersion123,
7531 kInvalidPathToCrx,
7532 Manifest::EXTERNAL_PREF,
7533 kCreationFlags,
7534 kDontMarkAcknowledged,
7535 kDontInstallImmediately));
7536 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7537 EXPECT_TRUE(info->version().IsValid());
7538 EXPECT_TRUE(info->version().Equals(kVersion124));
7540 // Adding an older version fails even when coming from a higher-priority
7541 // location.
7542 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7543 kGoodId,
7544 &kVersion123,
7545 kInvalidPathToCrx,
7546 Manifest::EXTERNAL_REGISTRY,
7547 kCreationFlags,
7548 kDontMarkAcknowledged,
7549 kDontInstallImmediately));
7550 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7551 EXPECT_TRUE(info->version().IsValid());
7552 EXPECT_TRUE(info->version().Equals(kVersion124));
7554 // Adding the latest version from the webstore overrides a specific version.
7555 GURL kUpdateUrl("http://example.com/update");
7556 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
7557 kGoodId,
7558 std::string(),
7559 kUpdateUrl,
7560 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7561 Extension::NO_FLAGS,
7562 false));
7563 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7564 EXPECT_FALSE(info->version().IsValid());
7567 // This makes sure we can package and install CRX files that use whitelisted
7568 // permissions.
7569 TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
7570 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
7571 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
7572 extensions::switches::kWhitelistedExtensionID, test_id);
7574 InitializeEmptyExtensionService();
7575 base::FilePath path = data_dir().AppendASCII("permissions");
7576 base::FilePath pem_path = path
7577 .AppendASCII("whitelist.pem");
7578 path = path
7579 .AppendASCII("whitelist");
7581 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
7582 EXPECT_EQ(0u, GetErrors().size());
7583 ASSERT_EQ(1u, registry()->enabled_extensions().size());
7584 EXPECT_EQ(test_id, extension->id());
7587 // Test that when multiple sources try to install an extension,
7588 // we consistently choose the right one. To make tests easy to read,
7589 // methods that fake requests to install crx files in several ways
7590 // are provided.
7591 class ExtensionSourcePriorityTest : public ExtensionServiceTest {
7592 public:
7593 void SetUp() override {
7594 ExtensionServiceTest::SetUp();
7596 // All tests use a single extension. Put the id and path in member vars
7597 // that all methods can read.
7598 crx_id_ = kGoodId;
7599 crx_path_ = data_dir().AppendASCII("good.crx");
7602 // Fake an external source adding a URL to fetch an extension from.
7603 bool AddPendingExternalPrefUrl() {
7604 return service()->pending_extension_manager()->AddFromExternalUpdateUrl(
7605 crx_id_,
7606 std::string(),
7607 GURL(),
7608 Manifest::EXTERNAL_PREF_DOWNLOAD,
7609 Extension::NO_FLAGS,
7610 false);
7613 // Fake an external file from external_extensions.json.
7614 bool AddPendingExternalPrefFileInstall() {
7615 Version version("1.0.0.0");
7617 return service()->OnExternalExtensionFileFound(crx_id_,
7618 &version,
7619 crx_path_,
7620 Manifest::EXTERNAL_PREF,
7621 Extension::NO_FLAGS,
7622 false,
7623 false);
7626 // Fake a request from sync to install an extension.
7627 bool AddPendingSyncInstall() {
7628 return service()->pending_extension_manager()->AddFromSync(
7629 crx_id_,
7630 GURL(kGoodUpdateURL),
7631 &IsExtension,
7632 kGoodRemoteInstall,
7633 kGoodInstalledByCustodian);
7636 // Fake a policy install.
7637 bool AddPendingPolicyInstall() {
7638 // Get path to the CRX with id |kGoodId|.
7639 return service()->OnExternalExtensionUpdateUrlFound(
7640 crx_id_,
7641 std::string(),
7642 GURL(),
7643 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7644 Extension::NO_FLAGS,
7645 false);
7648 // Get the install source of a pending extension.
7649 Manifest::Location GetPendingLocation() {
7650 const extensions::PendingExtensionInfo* info;
7651 EXPECT_TRUE(
7652 (info = service()->pending_extension_manager()->GetById(crx_id_)));
7653 return info->install_source();
7656 // Is an extension pending from a sync request?
7657 bool GetPendingIsFromSync() {
7658 const extensions::PendingExtensionInfo* info;
7659 EXPECT_TRUE(
7660 (info = service()->pending_extension_manager()->GetById(crx_id_)));
7661 return info->is_from_sync();
7664 // Is the CRX id these tests use pending?
7665 bool IsCrxPending() {
7666 return service()->pending_extension_manager()->IsIdPending(crx_id_);
7669 // Is an extension installed?
7670 bool IsCrxInstalled() {
7671 return (service()->GetExtensionById(crx_id_, true) != NULL);
7674 protected:
7675 // All tests use a single extension. Making the id and path member
7676 // vars avoids pasing the same argument to every method.
7677 std::string crx_id_;
7678 base::FilePath crx_path_;
7681 // Test that a pending request for installation of an external CRX from
7682 // an update URL overrides a pending request to install the same extension
7683 // from sync.
7684 TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
7685 InitializeEmptyExtensionService();
7687 ASSERT_FALSE(IsCrxInstalled());
7689 // Install pending extension from sync.
7690 content::WindowedNotificationObserver observer(
7691 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7692 content::NotificationService::AllSources());
7693 EXPECT_TRUE(AddPendingSyncInstall());
7694 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
7695 EXPECT_TRUE(GetPendingIsFromSync());
7696 ASSERT_FALSE(IsCrxInstalled());
7698 // Install pending as external prefs json would.
7699 AddPendingExternalPrefFileInstall();
7700 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
7701 ASSERT_FALSE(IsCrxInstalled());
7703 // Another request from sync should be ignored.
7704 EXPECT_FALSE(AddPendingSyncInstall());
7705 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
7706 ASSERT_FALSE(IsCrxInstalled());
7708 observer.Wait();
7709 VerifyCrxInstall(crx_path_, INSTALL_NEW);
7710 ASSERT_TRUE(IsCrxInstalled());
7713 // Test that an install of an external CRX from an update overrides
7714 // an install of the same extension from sync.
7715 TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
7716 InitializeEmptyExtensionService();
7717 ASSERT_FALSE(IsCrxInstalled());
7719 EXPECT_TRUE(AddPendingSyncInstall());
7720 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
7721 EXPECT_TRUE(GetPendingIsFromSync());
7722 ASSERT_FALSE(IsCrxInstalled());
7724 ASSERT_TRUE(AddPendingExternalPrefUrl());
7725 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
7726 EXPECT_FALSE(GetPendingIsFromSync());
7727 ASSERT_FALSE(IsCrxInstalled());
7729 EXPECT_FALSE(AddPendingSyncInstall());
7730 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
7731 EXPECT_FALSE(GetPendingIsFromSync());
7732 ASSERT_FALSE(IsCrxInstalled());
7735 // Test that an external install request stops sync from installing
7736 // the same extension.
7737 TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
7738 InitializeEmptyExtensionService();
7739 ASSERT_FALSE(IsCrxInstalled());
7741 // External prefs starts an install.
7742 AddPendingExternalPrefFileInstall();
7744 // Crx installer was made, but has not yet run.
7745 ASSERT_FALSE(IsCrxInstalled());
7747 // Before the CRX installer runs, Sync requests that the same extension
7748 // be installed. Should fail, because an external source is pending.
7749 content::WindowedNotificationObserver observer(
7750 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7751 content::NotificationService::AllSources());
7752 ASSERT_FALSE(AddPendingSyncInstall());
7754 // Wait for the external source to install.
7755 observer.Wait();
7756 VerifyCrxInstall(crx_path_, INSTALL_NEW);
7757 ASSERT_TRUE(IsCrxInstalled());
7759 // Now that the extension is installed, sync request should fail
7760 // because the extension is already installed.
7761 ASSERT_FALSE(AddPendingSyncInstall());
7764 // Test that installing an external extension displays a GlobalError.
7765 TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
7766 FeatureSwitch::ScopedOverride prompt(
7767 FeatureSwitch::prompt_for_external_extensions(), true);
7769 InitializeEmptyExtensionService();
7770 MockExtensionProvider* provider =
7771 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7772 AddMockExternalProvider(provider);
7774 service()->external_install_manager()->UpdateExternalExtensionAlert();
7775 // Should return false, meaning there aren't any extensions that the user
7776 // needs to know about.
7777 EXPECT_FALSE(
7778 service()->external_install_manager()->HasExternalInstallError());
7780 // This is a normal extension, installed normally.
7781 // This should NOT trigger an alert.
7782 service()->set_extensions_enabled(true);
7783 base::FilePath path = data_dir().AppendASCII("good.crx");
7784 InstallCRX(path, INSTALL_NEW);
7786 service()->CheckForExternalUpdates();
7787 base::RunLoop().RunUntilIdle();
7788 EXPECT_FALSE(
7789 service()->external_install_manager()->HasExternalInstallError());
7791 // A hosted app, installed externally.
7792 // This should NOT trigger an alert.
7793 provider->UpdateOrAddExtension(
7794 hosted_app, "1.0.0.0", data_dir().AppendASCII("hosted_app.crx"));
7796 content::WindowedNotificationObserver observer(
7797 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7798 content::NotificationService::AllSources());
7799 service()->CheckForExternalUpdates();
7800 observer.Wait();
7801 EXPECT_FALSE(
7802 service()->external_install_manager()->HasExternalInstallError());
7804 // Another normal extension, but installed externally.
7805 // This SHOULD trigger an alert.
7806 provider->UpdateOrAddExtension(
7807 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7809 content::WindowedNotificationObserver observer2(
7810 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7811 content::NotificationService::AllSources());
7812 service()->CheckForExternalUpdates();
7813 observer2.Wait();
7814 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7817 // Test that external extensions are initially disabled, and that enabling
7818 // them clears the prompt.
7819 TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
7820 FeatureSwitch::ScopedOverride prompt(
7821 FeatureSwitch::prompt_for_external_extensions(), true);
7823 InitializeEmptyExtensionService();
7824 MockExtensionProvider* provider =
7825 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7826 AddMockExternalProvider(provider);
7828 provider->UpdateOrAddExtension(
7829 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7831 content::WindowedNotificationObserver observer(
7832 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7833 content::NotificationService::AllSources());
7834 service()->CheckForExternalUpdates();
7835 observer.Wait();
7836 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7837 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
7839 const Extension* extension =
7840 registry()->disabled_extensions().GetByID(page_action);
7841 EXPECT_TRUE(extension);
7842 EXPECT_EQ(page_action, extension->id());
7844 service()->EnableExtension(page_action);
7845 EXPECT_FALSE(
7846 service()->external_install_manager()->HasExternalInstallError());
7847 EXPECT_TRUE(service()->IsExtensionEnabled(page_action));
7850 // Test that installing multiple external extensions works.
7851 // Flaky on windows; http://crbug.com/295757 .
7852 #if defined(OS_WIN)
7853 #define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
7854 #else
7855 #define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
7856 #endif
7857 TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
7858 FeatureSwitch::ScopedOverride prompt(
7859 FeatureSwitch::prompt_for_external_extensions(), true);
7861 InitializeEmptyExtensionService();
7862 MockExtensionProvider* provider =
7863 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7864 AddMockExternalProvider(provider);
7866 provider->UpdateOrAddExtension(
7867 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7868 provider->UpdateOrAddExtension(
7869 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
7870 provider->UpdateOrAddExtension(
7871 theme_crx, "2.0", data_dir().AppendASCII("theme.crx"));
7873 int count = 3;
7874 content::WindowedNotificationObserver observer(
7875 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7876 base::Bind(&WaitForCountNotificationsCallback, &count));
7877 service()->CheckForExternalUpdates();
7878 observer.Wait();
7879 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7880 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
7881 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
7882 EXPECT_FALSE(service()->IsExtensionEnabled(theme_crx));
7884 service()->EnableExtension(page_action);
7885 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7886 EXPECT_FALSE(service()
7887 ->external_install_manager()
7888 ->HasExternalInstallBubbleForTesting());
7890 service()->EnableExtension(theme_crx);
7891 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7892 EXPECT_FALSE(service()
7893 ->external_install_manager()
7894 ->HasExternalInstallBubbleForTesting());
7896 service()->EnableExtension(good_crx);
7897 EXPECT_FALSE(
7898 service()->external_install_manager()->HasExternalInstallError());
7899 EXPECT_FALSE(service()
7900 ->external_install_manager()
7901 ->HasExternalInstallBubbleForTesting());
7904 // Test that there is a bubble for external extensions that update
7905 // from the webstore if the profile is not new.
7906 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
7907 FeatureSwitch::ScopedOverride prompt(
7908 FeatureSwitch::prompt_for_external_extensions(), true);
7910 // This sets up the ExtensionPrefs used by our ExtensionService to be
7911 // post-first run.
7912 ExtensionServiceInitParams params = CreateDefaultInitParams();
7913 params.is_first_run = false;
7914 InitializeExtensionService(params);
7916 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7917 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7918 data_dir().AppendASCII("update_from_webstore.pem"),
7919 crx_path);
7921 MockExtensionProvider* provider =
7922 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7923 AddMockExternalProvider(provider);
7924 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7926 content::WindowedNotificationObserver observer(
7927 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7928 content::NotificationService::AllSources());
7929 service()->CheckForExternalUpdates();
7930 observer.Wait();
7931 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7932 EXPECT_TRUE(service()
7933 ->external_install_manager()
7934 ->HasExternalInstallBubbleForTesting());
7935 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7938 // Test that there is no bubble for external extensions if the profile is new.
7939 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
7940 FeatureSwitch::ScopedOverride prompt(
7941 FeatureSwitch::prompt_for_external_extensions(), true);
7943 InitializeEmptyExtensionService();
7945 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7946 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7947 data_dir().AppendASCII("update_from_webstore.pem"),
7948 crx_path);
7950 MockExtensionProvider* provider =
7951 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7952 AddMockExternalProvider(provider);
7953 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7955 content::WindowedNotificationObserver observer(
7956 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7957 content::NotificationService::AllSources());
7958 service()->CheckForExternalUpdates();
7959 observer.Wait();
7960 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7961 EXPECT_FALSE(service()
7962 ->external_install_manager()
7963 ->HasExternalInstallBubbleForTesting());
7964 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7967 // Test that clicking to remove the extension on an external install warning
7968 // uninstalls the extension.
7969 TEST_F(ExtensionServiceTest, ExternalInstallClickToRemove) {
7970 FeatureSwitch::ScopedOverride prompt(
7971 FeatureSwitch::prompt_for_external_extensions(), true);
7973 ExtensionServiceInitParams params = CreateDefaultInitParams();
7974 params.is_first_run = false;
7975 InitializeExtensionService(params);
7977 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7978 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7979 data_dir().AppendASCII("update_from_webstore.pem"),
7980 crx_path);
7982 MockExtensionProvider* provider =
7983 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
7984 AddMockExternalProvider(provider);
7985 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7987 content::WindowedNotificationObserver observer(
7988 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7989 content::NotificationService::AllSources());
7990 service_->CheckForExternalUpdates();
7991 observer.Wait();
7992 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
7994 // We check both enabled and disabled, since these are "eventually exclusive"
7995 // sets.
7996 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
7997 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7999 // Click the negative response.
8000 service_->external_install_manager()->error_for_testing()->InstallUIAbort(
8001 true);
8002 // The Extension should be uninstalled.
8003 EXPECT_FALSE(registry()->GetExtensionById(updates_from_webstore,
8004 ExtensionRegistry::EVERYTHING));
8005 // The error should be removed.
8006 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
8009 // Test that clicking to keep the extension on an external install warning
8010 // re-enables the extension.
8011 TEST_F(ExtensionServiceTest, ExternalInstallClickToKeep) {
8012 FeatureSwitch::ScopedOverride prompt(
8013 FeatureSwitch::prompt_for_external_extensions(), true);
8015 ExtensionServiceInitParams params = CreateDefaultInitParams();
8016 params.is_first_run = false;
8017 InitializeExtensionService(params);
8019 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
8020 PackCRX(data_dir().AppendASCII("update_from_webstore"),
8021 data_dir().AppendASCII("update_from_webstore.pem"),
8022 crx_path);
8024 MockExtensionProvider* provider =
8025 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
8026 AddMockExternalProvider(provider);
8027 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
8029 content::WindowedNotificationObserver observer(
8030 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
8031 content::NotificationService::AllSources());
8032 service_->CheckForExternalUpdates();
8033 observer.Wait();
8034 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
8036 // We check both enabled and disabled, since these are "eventually exclusive"
8037 // sets.
8038 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
8039 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8041 // Accept the extension.
8042 service_->external_install_manager()->error_for_testing()->InstallUIProceed();
8044 // It should be enabled again.
8045 EXPECT_TRUE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8046 EXPECT_FALSE(
8047 registry()->disabled_extensions().GetByID(updates_from_webstore));
8049 // The error should be removed.
8050 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
8053 TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) {
8054 InitializeEmptyExtensionService();
8056 scoped_refptr<Extension> extension = extensions::ExtensionBuilder()
8057 .SetManifest(extensions::DictionaryBuilder()
8058 .Set("name", "extension")
8059 .Set("version", "1.0")
8060 .Set("manifest_version", 2).Build())
8061 .Build();
8062 ASSERT_TRUE(extension.get());
8063 const std::string& id = extension->id();
8065 std::set<std::string> id_set;
8066 id_set.insert(id);
8067 extensions::ExtensionNotificationObserver notifications(
8068 content::NotificationService::AllSources(), id_set);
8070 // Installation should be allowed but the extension should never have been
8071 // loaded and it should be blacklisted in prefs.
8072 service()->OnExtensionInstalled(
8073 extension.get(),
8074 syncer::StringOrdinal(),
8075 (extensions::kInstallFlagIsBlacklistedForMalware |
8076 extensions::kInstallFlagInstallImmediately));
8077 base::RunLoop().RunUntilIdle();
8079 // Extension was installed but not loaded.
8080 EXPECT_TRUE(notifications.CheckNotifications(
8081 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED));
8082 EXPECT_TRUE(service()->GetInstalledExtension(id));
8084 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
8085 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(id));
8087 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlacklisted(id));
8088 EXPECT_TRUE(
8089 ExtensionPrefs::Get(profile())->IsBlacklistedExtensionAcknowledged(id));
8092 // Tests a profile being destroyed correctly disables extensions.
8093 TEST_F(ExtensionServiceTest, DestroyingProfileClearsExtensions) {
8094 InitializeEmptyExtensionService();
8096 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
8097 EXPECT_NE(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8098 EXPECT_EQ(1u, registry()->enabled_extensions().size());
8099 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8100 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8101 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
8103 service()->Observe(chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
8104 content::Source<Profile>(profile()),
8105 content::NotificationService::NoDetails());
8106 EXPECT_EQ(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8107 EXPECT_EQ(0u, registry()->enabled_extensions().size());
8108 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8109 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8110 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());