Cleanup ExtensionSyncService and SyncBundle.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_service_unittest.cc
blob0a4c7fa0d49631f886faaef9710f702817bf5ca1
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include <algorithm>
6 #include <set>
7 #include <vector>
9 #include "base/at_exit.h"
10 #include "base/basictypes.h"
11 #include "base/bind.h"
12 #include "base/command_line.h"
13 #include "base/files/file_enumerator.h"
14 #include "base/files/file_util.h"
15 #include "base/files/scoped_temp_dir.h"
16 #include "base/json/json_file_value_serializer.h"
17 #include "base/json/json_reader.h"
18 #include "base/json/json_string_value_serializer.h"
19 #include "base/location.h"
20 #include "base/memory/scoped_ptr.h"
21 #include "base/memory/weak_ptr.h"
22 #include "base/prefs/scoped_user_pref_update.h"
23 #include "base/single_thread_task_runner.h"
24 #include "base/stl_util.h"
25 #include "base/strings/pattern.h"
26 #include "base/strings/string16.h"
27 #include "base/strings/string_number_conversions.h"
28 #include "base/strings/string_util.h"
29 #include "base/strings/utf_string_conversions.h"
30 #include "base/thread_task_runner_handle.h"
31 #include "base/version.h"
32 #include "chrome/browser/browser_process.h"
33 #include "chrome/browser/chrome_notification_types.h"
34 #include "chrome/browser/extensions/blacklist.h"
35 #include "chrome/browser/extensions/chrome_app_sorting.h"
36 #include "chrome/browser/extensions/component_loader.h"
37 #include "chrome/browser/extensions/crx_installer.h"
38 #include "chrome/browser/extensions/default_apps.h"
39 #include "chrome/browser/extensions/extension_creator.h"
40 #include "chrome/browser/extensions/extension_error_reporter.h"
41 #include "chrome/browser/extensions/extension_error_ui.h"
42 #include "chrome/browser/extensions/extension_management_test_util.h"
43 #include "chrome/browser/extensions/extension_notification_observer.h"
44 #include "chrome/browser/extensions/extension_service.h"
45 #include "chrome/browser/extensions/extension_service_test_base.h"
46 #include "chrome/browser/extensions/extension_special_storage_policy.h"
47 #include "chrome/browser/extensions/extension_sync_data.h"
48 #include "chrome/browser/extensions/extension_sync_service.h"
49 #include "chrome/browser/extensions/extension_util.h"
50 #include "chrome/browser/extensions/external_install_error.h"
51 #include "chrome/browser/extensions/external_install_manager.h"
52 #include "chrome/browser/extensions/external_policy_loader.h"
53 #include "chrome/browser/extensions/external_pref_loader.h"
54 #include "chrome/browser/extensions/external_provider_impl.h"
55 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
56 #include "chrome/browser/extensions/installed_loader.h"
57 #include "chrome/browser/extensions/pack_extension_job.h"
58 #include "chrome/browser/extensions/pending_extension_info.h"
59 #include "chrome/browser/extensions/pending_extension_manager.h"
60 #include "chrome/browser/extensions/permissions_updater.h"
61 #include "chrome/browser/extensions/test_blacklist.h"
62 #include "chrome/browser/extensions/test_extension_system.h"
63 #include "chrome/browser/extensions/unpacked_installer.h"
64 #include "chrome/browser/extensions/updater/extension_updater.h"
65 #include "chrome/browser/policy/profile_policy_connector.h"
66 #include "chrome/browser/policy/profile_policy_connector_factory.h"
67 #include "chrome/browser/prefs/pref_service_syncable.h"
68 #include "chrome/browser/sync/profile_sync_service.h"
69 #include "chrome/browser/sync/profile_sync_service_factory.h"
70 #include "chrome/common/chrome_constants.h"
71 #include "chrome/common/chrome_switches.h"
72 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
73 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
74 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
75 #include "chrome/common/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::Blacklist;
172 using extensions::CrxInstaller;
173 using extensions::Extension;
174 using extensions::ExtensionCreator;
175 using extensions::ExtensionPrefs;
176 using extensions::ExtensionRegistry;
177 using extensions::ExtensionResource;
178 using extensions::ExtensionSyncData;
179 using extensions::ExtensionSystem;
180 using extensions::FakeSafeBrowsingDatabaseManager;
181 using extensions::FeatureSwitch;
182 using extensions::Manifest;
183 using extensions::PermissionSet;
184 using extensions::TestExtensionSystem;
185 using extensions::UnloadedExtensionInfo;
186 using extensions::URLPatternSet;
188 namespace keys = extensions::manifest_keys;
190 namespace {
192 // Extension ids used during testing.
193 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
194 const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
195 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
196 const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
197 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
198 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
199 const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
200 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
201 const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad";
202 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
203 const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
204 const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
205 const char permissions_blocklist[] = "noffkehfcaggllbcojjbopcmlhcnhcdn";
207 struct ExtensionsOrder {
208 bool operator()(const scoped_refptr<const Extension>& a,
209 const scoped_refptr<const Extension>& b) {
210 return a->name() < b->name();
214 static std::vector<base::string16> GetErrors() {
215 const std::vector<base::string16>* errors =
216 ExtensionErrorReporter::GetInstance()->GetErrors();
217 std::vector<base::string16> ret_val;
219 for (std::vector<base::string16>::const_iterator iter = errors->begin();
220 iter != errors->end(); ++iter) {
221 std::string utf8_error = base::UTF16ToUTF8(*iter);
222 if (utf8_error.find(".svn") == std::string::npos) {
223 ret_val.push_back(*iter);
227 // The tests rely on the errors being in a certain order, which can vary
228 // depending on how filesystem iteration works.
229 std::stable_sort(ret_val.begin(), ret_val.end());
231 return ret_val;
234 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
235 int schemes = URLPattern::SCHEME_ALL;
236 extent->AddPattern(URLPattern(schemes, pattern));
239 base::FilePath GetTemporaryFile() {
240 base::FilePath temp_file;
241 CHECK(base::CreateTemporaryFile(&temp_file));
242 return temp_file;
245 bool WaitForCountNotificationsCallback(int *count) {
246 return --(*count) == 0;
249 } // namespace
251 class MockExtensionProvider : public extensions::ExternalProviderInterface {
252 public:
253 MockExtensionProvider(
254 VisitorInterface* visitor,
255 Manifest::Location location)
256 : location_(location), visitor_(visitor), visit_count_(0) {
259 ~MockExtensionProvider() override {}
261 void UpdateOrAddExtension(const std::string& id,
262 const std::string& version,
263 const base::FilePath& path) {
264 extension_map_[id] = std::make_pair(version, path);
267 void RemoveExtension(const std::string& id) {
268 extension_map_.erase(id);
271 // ExternalProvider implementation:
272 void VisitRegisteredExtension() override {
273 visit_count_++;
274 for (DataMap::const_iterator i = extension_map_.begin();
275 i != extension_map_.end(); ++i) {
276 Version version(i->second.first);
278 visitor_->OnExternalExtensionFileFound(
279 i->first, &version, i->second.second, location_,
280 Extension::NO_FLAGS, false, false);
282 visitor_->OnExternalProviderReady(this);
285 bool HasExtension(const std::string& id) const override {
286 return extension_map_.find(id) != extension_map_.end();
289 bool GetExtensionDetails(const std::string& id,
290 Manifest::Location* location,
291 scoped_ptr<Version>* version) const override {
292 DataMap::const_iterator it = extension_map_.find(id);
293 if (it == extension_map_.end())
294 return false;
296 if (version)
297 version->reset(new Version(it->second.first));
299 if (location)
300 *location = location_;
302 return true;
305 bool IsReady() const override { return true; }
307 void ServiceShutdown() override {}
309 int visit_count() const { return visit_count_; }
310 void set_visit_count(int visit_count) {
311 visit_count_ = visit_count;
314 private:
315 typedef std::map< std::string, std::pair<std::string, base::FilePath> >
316 DataMap;
317 DataMap extension_map_;
318 Manifest::Location location_;
319 VisitorInterface* visitor_;
321 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
322 // Mutable because it must be incremented on each call to
323 // VisitRegisteredExtension(), which must be a const method to inherit
324 // from the class being mocked.
325 mutable int visit_count_;
327 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
330 class MockProviderVisitor
331 : public extensions::ExternalProviderInterface::VisitorInterface {
332 public:
333 // The provider will return |fake_base_path| from
334 // GetBaseCrxFilePath(). User can test the behavior with
335 // and without an empty path using this parameter.
336 explicit MockProviderVisitor(base::FilePath fake_base_path)
337 : ids_found_(0),
338 fake_base_path_(fake_base_path),
339 expected_creation_flags_(Extension::NO_FLAGS) {
340 profile_.reset(new TestingProfile);
343 MockProviderVisitor(base::FilePath fake_base_path,
344 int expected_creation_flags)
345 : ids_found_(0),
346 fake_base_path_(fake_base_path),
347 expected_creation_flags_(expected_creation_flags) {
348 profile_.reset(new TestingProfile);
351 int Visit(const std::string& json_data) {
352 // Give the test json file to the provider for parsing.
353 provider_.reset(new extensions::ExternalProviderImpl(
354 this,
355 new extensions::ExternalTestingLoader(json_data, fake_base_path_),
356 profile_.get(),
357 Manifest::EXTERNAL_PREF,
358 Manifest::EXTERNAL_PREF_DOWNLOAD,
359 Extension::NO_FLAGS));
361 // We also parse the file into a dictionary to compare what we get back
362 // from the provider.
363 JSONStringValueDeserializer deserializer(json_data);
364 base::Value* json_value = deserializer.Deserialize(NULL, NULL);
366 if (!json_value || !json_value->IsType(base::Value::TYPE_DICTIONARY)) {
367 NOTREACHED() << "Unable to deserialize json data";
368 return -1;
369 } else {
370 base::DictionaryValue* external_extensions =
371 static_cast<base::DictionaryValue*>(json_value);
372 prefs_.reset(external_extensions);
375 // Reset our counter.
376 ids_found_ = 0;
377 // Ask the provider to look up all extensions and return them.
378 provider_->VisitRegisteredExtension();
380 return ids_found_;
383 bool OnExternalExtensionFileFound(const std::string& id,
384 const Version* version,
385 const base::FilePath& path,
386 Manifest::Location unused,
387 int creation_flags,
388 bool mark_acknowledged,
389 bool install_immediately) override {
390 EXPECT_EQ(expected_creation_flags_, creation_flags);
392 ++ids_found_;
393 base::DictionaryValue* pref;
394 // This tests is to make sure that the provider only notifies us of the
395 // values we gave it. So if the id we doesn't exist in our internal
396 // dictionary then something is wrong.
397 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
398 << "Got back ID (" << id.c_str() << ") we weren't expecting";
400 EXPECT_TRUE(path.IsAbsolute());
401 if (!fake_base_path_.empty())
402 EXPECT_TRUE(fake_base_path_.IsParent(path));
404 if (pref) {
405 EXPECT_TRUE(provider_->HasExtension(id));
407 // Ask provider if the extension we got back is registered.
408 Manifest::Location location = Manifest::INVALID_LOCATION;
409 scoped_ptr<Version> v1;
410 base::FilePath crx_path;
412 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
413 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
415 scoped_ptr<Version> v2;
416 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
417 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
418 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
419 EXPECT_EQ(Manifest::EXTERNAL_PREF, location);
421 // Remove it so we won't count it ever again.
422 prefs_->Remove(id, NULL);
424 return true;
427 bool OnExternalExtensionUpdateUrlFound(const std::string& id,
428 const std::string& install_parameter,
429 const GURL& update_url,
430 Manifest::Location location,
431 int creation_flags,
432 bool mark_acknowledged) override {
433 ++ids_found_;
434 base::DictionaryValue* pref;
435 // This tests is to make sure that the provider only notifies us of the
436 // values we gave it. So if the id we doesn't exist in our internal
437 // dictionary then something is wrong.
438 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
439 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
440 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location);
442 if (pref) {
443 EXPECT_TRUE(provider_->HasExtension(id));
445 // External extensions with update URLs do not have versions.
446 scoped_ptr<Version> v1;
447 Manifest::Location location1 = Manifest::INVALID_LOCATION;
448 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
449 EXPECT_FALSE(v1.get());
450 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1);
452 std::string parsed_install_parameter;
453 pref->GetString("install_parameter", &parsed_install_parameter);
454 EXPECT_EQ(parsed_install_parameter, install_parameter);
456 // Remove it so we won't count it again.
457 prefs_->Remove(id, NULL);
459 return true;
462 void OnExternalProviderReady(
463 const extensions::ExternalProviderInterface* provider) override {
464 EXPECT_EQ(provider, provider_.get());
465 EXPECT_TRUE(provider->IsReady());
468 Profile* profile() { return profile_.get(); }
470 private:
471 int ids_found_;
472 base::FilePath fake_base_path_;
473 int expected_creation_flags_;
474 scoped_ptr<extensions::ExternalProviderImpl> provider_;
475 scoped_ptr<base::DictionaryValue> prefs_;
476 scoped_ptr<TestingProfile> profile_;
478 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
481 class ExtensionServiceTest : public extensions::ExtensionServiceTestBase,
482 public content::NotificationObserver {
483 public:
484 ExtensionServiceTest()
485 : unloaded_reason_(UnloadedExtensionInfo::REASON_UNDEFINED),
486 installed_(NULL),
487 was_update_(false),
488 override_external_install_prompt_(
489 FeatureSwitch::prompt_for_external_extensions(),
490 false),
491 expected_extensions_count_(0) {
492 registrar_.Add(this,
493 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
494 content::NotificationService::AllSources());
495 registrar_.Add(this,
496 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
497 content::NotificationService::AllSources());
498 registrar_.Add(
499 this,
500 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
501 content::NotificationService::AllSources());
504 void Observe(int type,
505 const content::NotificationSource& source,
506 const content::NotificationDetails& details) override {
507 switch (type) {
508 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
509 const Extension* extension =
510 content::Details<const Extension>(details).ptr();
511 loaded_.push_back(make_scoped_refptr(extension));
512 // The tests rely on the errors being in a certain order, which can vary
513 // depending on how filesystem iteration works.
514 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
515 break;
518 case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
519 UnloadedExtensionInfo* unloaded_info =
520 content::Details<UnloadedExtensionInfo>(details).ptr();
521 const Extension* e = unloaded_info->extension;
522 unloaded_id_ = e->id();
523 unloaded_reason_ = unloaded_info->reason;
524 extensions::ExtensionList::iterator i =
525 std::find(loaded_.begin(), loaded_.end(), e);
526 // TODO(erikkay) fix so this can be an assert. Right now the tests
527 // are manually calling clear() on loaded_, so this isn't doable.
528 if (i == loaded_.end())
529 return;
530 loaded_.erase(i);
531 break;
533 case extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED: {
534 const extensions::InstalledExtensionInfo* installed_info =
535 content::Details<const extensions::InstalledExtensionInfo>(details)
536 .ptr();
537 installed_ = installed_info->extension;
538 was_update_ = installed_info->is_update;
539 old_name_ = installed_info->old_name;
540 break;
543 default:
544 DCHECK(false);
548 void AddMockExternalProvider(
549 extensions::ExternalProviderInterface* provider) {
550 service()->AddProviderForTesting(provider);
553 void MockSyncStartFlare(bool* was_called,
554 syncer::ModelType* model_type_passed_in,
555 syncer::ModelType model_type) {
556 *was_called = true;
557 *model_type_passed_in = model_type;
560 protected:
561 // Paths to some of the fake extensions.
562 base::FilePath good0_path() {
563 return data_dir()
564 .AppendASCII("good")
565 .AppendASCII("Extensions")
566 .AppendASCII(good0)
567 .AppendASCII("1.0.0.0");
570 base::FilePath good1_path() {
571 return data_dir()
572 .AppendASCII("good")
573 .AppendASCII("Extensions")
574 .AppendASCII(good1)
575 .AppendASCII("2");
578 base::FilePath good2_path() {
579 return data_dir()
580 .AppendASCII("good")
581 .AppendASCII("Extensions")
582 .AppendASCII(good2)
583 .AppendASCII("1.0");
586 void TestExternalProvider(MockExtensionProvider* provider,
587 Manifest::Location location);
589 void PackCRX(const base::FilePath& dir_path,
590 const base::FilePath& pem_path,
591 const base::FilePath& crx_path) {
592 // Use the existing pem key, if provided.
593 base::FilePath pem_output_path;
594 if (pem_path.value().empty()) {
595 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
596 } else {
597 ASSERT_TRUE(base::PathExists(pem_path));
600 ASSERT_TRUE(base::DeleteFile(crx_path, false));
602 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
603 ASSERT_TRUE(creator->Run(dir_path,
604 crx_path,
605 pem_path,
606 pem_output_path,
607 ExtensionCreator::kOverwriteCRX));
609 ASSERT_TRUE(base::PathExists(crx_path));
612 enum InstallState {
613 INSTALL_FAILED,
614 INSTALL_UPDATED,
615 INSTALL_NEW,
616 INSTALL_WITHOUT_LOAD,
619 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
620 const base::FilePath& pem_path,
621 InstallState install_state,
622 int creation_flags) {
623 base::FilePath crx_path;
624 base::ScopedTempDir temp_dir;
625 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
626 crx_path = temp_dir.path().AppendASCII("temp.crx");
628 PackCRX(dir_path, pem_path, crx_path);
629 return InstallCRX(crx_path, install_state, creation_flags);
632 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
633 const base::FilePath& pem_path,
634 InstallState install_state) {
635 return PackAndInstallCRX(dir_path, pem_path, install_state,
636 Extension::NO_FLAGS);
639 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
640 InstallState install_state) {
641 return PackAndInstallCRX(dir_path, base::FilePath(), install_state,
642 Extension::NO_FLAGS);
645 // Attempts to install an extension. Use INSTALL_FAILED if the installation
646 // is expected to fail.
647 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
648 // non-empty, expects that the existing extension's title was
649 // |expected_old_name|.
650 const Extension* InstallCRX(const base::FilePath& path,
651 InstallState install_state,
652 int creation_flags,
653 const std::string& expected_old_name) {
654 InstallCRXInternal(path, creation_flags);
655 return VerifyCrxInstall(path, install_state, expected_old_name);
658 // Attempts to install an extension. Use INSTALL_FAILED if the installation
659 // is expected to fail.
660 const Extension* InstallCRX(const base::FilePath& path,
661 InstallState install_state,
662 int creation_flags) {
663 return InstallCRX(path, install_state, creation_flags, std::string());
666 // Attempts to install an extension. Use INSTALL_FAILED if the installation
667 // is expected to fail.
668 const Extension* InstallCRX(const base::FilePath& path,
669 InstallState install_state) {
670 return InstallCRX(path, install_state, Extension::NO_FLAGS);
673 const Extension* InstallCRXFromWebStore(const base::FilePath& path,
674 InstallState install_state) {
675 InstallCRXInternal(path, Extension::FROM_WEBSTORE);
676 return VerifyCrxInstall(path, install_state);
679 const Extension* InstallCRXWithLocation(const base::FilePath& crx_path,
680 Manifest::Location install_location,
681 InstallState install_state) {
682 EXPECT_TRUE(base::PathExists(crx_path))
683 << "Path does not exist: "<< crx_path.value().c_str();
684 // no client (silent install)
685 scoped_refptr<CrxInstaller> installer(
686 CrxInstaller::CreateSilent(service()));
687 installer->set_install_source(install_location);
689 content::WindowedNotificationObserver observer(
690 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
691 content::NotificationService::AllSources());
692 installer->InstallCrx(crx_path);
693 observer.Wait();
695 return VerifyCrxInstall(crx_path, install_state);
698 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
699 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
700 // Returns an Extension pointer if the install succeeded, NULL otherwise.
701 const Extension* VerifyCrxInstall(const base::FilePath& path,
702 InstallState install_state) {
703 return VerifyCrxInstall(path, install_state, std::string());
706 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
707 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
708 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
709 // non-empty, expects that the existing extension's title was
710 // |expected_old_name|.
711 // Returns an Extension pointer if the install succeeded, NULL otherwise.
712 const Extension* VerifyCrxInstall(const base::FilePath& path,
713 InstallState install_state,
714 const std::string& expected_old_name) {
715 std::vector<base::string16> errors = GetErrors();
716 const Extension* extension = NULL;
717 if (install_state != INSTALL_FAILED) {
718 if (install_state == INSTALL_NEW)
719 ++expected_extensions_count_;
721 EXPECT_TRUE(installed_) << path.value();
722 // If and only if INSTALL_UPDATED, it should have the is_update flag.
723 EXPECT_EQ(install_state == INSTALL_UPDATED, was_update_)
724 << path.value();
725 // If INSTALL_UPDATED, old_name_ should match the given string.
726 if (install_state == INSTALL_UPDATED && !expected_old_name.empty())
727 EXPECT_EQ(expected_old_name, old_name_);
728 EXPECT_EQ(0u, errors.size()) << path.value();
730 if (install_state == INSTALL_WITHOUT_LOAD) {
731 EXPECT_EQ(0u, loaded_.size()) << path.value();
732 } else {
733 EXPECT_EQ(1u, loaded_.size()) << path.value();
734 size_t actual_extension_count =
735 registry()->enabled_extensions().size() +
736 registry()->disabled_extensions().size();
737 EXPECT_EQ(expected_extensions_count_, actual_extension_count) <<
738 path.value();
739 extension = loaded_[0].get();
740 EXPECT_TRUE(service()->GetExtensionById(extension->id(), false))
741 << path.value();
744 for (std::vector<base::string16>::iterator err = errors.begin();
745 err != errors.end(); ++err) {
746 LOG(ERROR) << *err;
748 } else {
749 EXPECT_FALSE(installed_) << path.value();
750 EXPECT_EQ(0u, loaded_.size()) << path.value();
751 EXPECT_EQ(1u, errors.size()) << path.value();
754 installed_ = NULL;
755 was_update_ = false;
756 old_name_ = "";
757 loaded_.clear();
758 ExtensionErrorReporter::GetInstance()->ClearErrors();
759 return extension;
762 enum UpdateState {
763 FAILED_SILENTLY,
764 FAILED,
765 UPDATED,
766 INSTALLED,
767 DISABLED,
768 ENABLED
771 void BlackListWebGL() {
772 static const std::string json_blacklist =
773 "{\n"
774 " \"name\": \"gpu blacklist\",\n"
775 " \"version\": \"1.0\",\n"
776 " \"entries\": [\n"
777 " {\n"
778 " \"id\": 1,\n"
779 " \"features\": [\"webgl\"]\n"
780 " }\n"
781 " ]\n"
782 "}";
783 gpu::GPUInfo gpu_info;
784 content::GpuDataManager::GetInstance()->InitializeForTesting(
785 json_blacklist, gpu_info);
788 // Grants all optional permissions stated in manifest to active permission
789 // set for extension |id|.
790 void GrantAllOptionalPermissions(const std::string& id) {
791 const Extension* extension = service()->GetInstalledExtension(id);
792 scoped_refptr<const PermissionSet> all_optional_permissions =
793 extensions::PermissionsParser::GetOptionalPermissions(extension);
794 extensions::PermissionsUpdater perms_updater(profile());
795 perms_updater.AddPermissions(extension, all_optional_permissions.get());
798 // Helper method to set up a WindowedNotificationObserver to wait for a
799 // specific CrxInstaller to finish if we don't know the value of the
800 // |installer| yet.
801 static bool IsCrxInstallerDone(extensions::CrxInstaller** installer,
802 const content::NotificationSource& source,
803 const content::NotificationDetails& details) {
804 return content::Source<extensions::CrxInstaller>(source).ptr() ==
805 *installer;
808 void PackCRXAndUpdateExtension(const std::string& id,
809 const base::FilePath& dir_path,
810 const base::FilePath& pem_path,
811 UpdateState expected_state) {
812 base::ScopedTempDir temp_dir;
813 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
814 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
816 PackCRX(dir_path, pem_path, crx_path);
817 UpdateExtension(id, crx_path, expected_state);
820 void UpdateExtension(const std::string& id,
821 const base::FilePath& in_path,
822 UpdateState expected_state) {
823 ASSERT_TRUE(base::PathExists(in_path));
825 // We need to copy this to a temporary location because Update() will delete
826 // it.
827 base::FilePath path = temp_dir().path();
828 path = path.Append(in_path.BaseName());
829 ASSERT_TRUE(base::CopyFile(in_path, path));
831 int previous_enabled_extension_count =
832 registry()->enabled_extensions().size();
833 int previous_installed_extension_count =
834 previous_enabled_extension_count +
835 registry()->disabled_extensions().size();
837 extensions::CrxInstaller* installer = NULL;
838 content::WindowedNotificationObserver observer(
839 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
840 base::Bind(&IsCrxInstallerDone, &installer));
841 service()->UpdateExtension(extensions::CRXFileInfo(id, path), true,
842 &installer);
844 if (installer)
845 observer.Wait();
846 else
847 base::RunLoop().RunUntilIdle();
849 std::vector<base::string16> errors = GetErrors();
850 int error_count = errors.size();
851 int enabled_extension_count = registry()->enabled_extensions().size();
852 int installed_extension_count =
853 enabled_extension_count + registry()->disabled_extensions().size();
855 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
856 EXPECT_EQ(expected_error_count, error_count) << path.value();
858 if (expected_state <= FAILED) {
859 EXPECT_EQ(previous_enabled_extension_count,
860 enabled_extension_count);
861 EXPECT_EQ(previous_installed_extension_count,
862 installed_extension_count);
863 } else {
864 int expected_installed_extension_count =
865 (expected_state >= INSTALLED) ? 1 : 0;
866 int expected_enabled_extension_count =
867 (expected_state >= ENABLED) ? 1 : 0;
868 EXPECT_EQ(expected_installed_extension_count,
869 installed_extension_count);
870 EXPECT_EQ(expected_enabled_extension_count,
871 enabled_extension_count);
874 // Update() should the temporary input file.
875 EXPECT_FALSE(base::PathExists(path));
878 void TerminateExtension(const std::string& id) {
879 const Extension* extension = service()->GetInstalledExtension(id);
880 if (!extension) {
881 ADD_FAILURE();
882 return;
884 service()->TrackTerminatedExtensionForTest(extension);
887 testing::AssertionResult IsBlocked(const std::string& id) {
888 scoped_ptr<extensions::ExtensionSet> all_unblocked_extensions =
889 registry()->GenerateInstalledExtensionsSet(
890 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::BLOCKED);
891 if (all_unblocked_extensions.get()->Contains(id))
892 return testing::AssertionFailure() << id << " is still unblocked!";
893 if (!registry()->blocked_extensions().Contains(id))
894 return testing::AssertionFailure() << id << " is not blocked!";
895 return testing::AssertionSuccess();
898 // Helper method to test that an extension moves through being blocked and
899 // unblocked as appropriate for its type.
900 void AssertExtensionBlocksAndUnblocks(
901 bool should_block, const std::string extension_id) {
902 // Assume we start in an unblocked state.
903 EXPECT_FALSE(IsBlocked(extension_id));
905 // Block the extensions.
906 service()->BlockAllExtensions();
907 base::RunLoop().RunUntilIdle();
909 if (should_block)
910 ASSERT_TRUE(IsBlocked(extension_id));
911 else
912 ASSERT_FALSE(IsBlocked(extension_id));
914 service()->UnblockAllExtensions();
915 base::RunLoop().RunUntilIdle();
917 ASSERT_FALSE(IsBlocked(extension_id));
920 size_t GetPrefKeyCount() {
921 const base::DictionaryValue* dict =
922 profile()->GetPrefs()->GetDictionary("extensions.settings");
923 if (!dict) {
924 ADD_FAILURE();
925 return 0;
927 return dict->size();
930 void UninstallExtension(const std::string& id, bool use_helper) {
931 UninstallExtension(id, use_helper, Extension::ENABLED);
934 void UninstallExtension(const std::string& id, bool use_helper,
935 Extension::State expected_state) {
936 // Verify that the extension is installed.
937 base::FilePath extension_path = extensions_install_dir().AppendASCII(id);
938 EXPECT_TRUE(base::PathExists(extension_path));
939 size_t pref_key_count = GetPrefKeyCount();
940 EXPECT_GT(pref_key_count, 0u);
941 ValidateIntegerPref(id, "state", expected_state);
943 // Uninstall it.
944 if (use_helper) {
945 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(
946 service(), id, extensions::UNINSTALL_REASON_FOR_TESTING));
947 } else {
948 EXPECT_TRUE(service()->UninstallExtension(
950 extensions::UNINSTALL_REASON_FOR_TESTING,
951 base::Bind(&base::DoNothing),
952 NULL));
954 --expected_extensions_count_;
956 // We should get an unload notification.
957 EXPECT_FALSE(unloaded_id_.empty());
958 EXPECT_EQ(id, unloaded_id_);
960 // Verify uninstalled state.
961 size_t new_pref_key_count = GetPrefKeyCount();
962 if (new_pref_key_count == pref_key_count) {
963 ValidateIntegerPref(id, "state",
964 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
965 } else {
966 EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
969 // The extension should not be in the service anymore.
970 EXPECT_FALSE(service()->GetInstalledExtension(id));
971 base::RunLoop().RunUntilIdle();
973 // The directory should be gone.
974 EXPECT_FALSE(base::PathExists(extension_path));
977 void ValidatePrefKeyCount(size_t count) {
978 EXPECT_EQ(count, GetPrefKeyCount());
981 testing::AssertionResult ValidateBooleanPref(
982 const std::string& extension_id,
983 const std::string& pref_path,
984 bool expected_val) {
985 std::string msg = "while checking: ";
986 msg += extension_id;
987 msg += " ";
988 msg += pref_path;
989 msg += " == ";
990 msg += expected_val ? "true" : "false";
992 PrefService* prefs = profile()->GetPrefs();
993 const base::DictionaryValue* dict =
994 prefs->GetDictionary("extensions.settings");
995 if (!dict) {
996 return testing::AssertionFailure()
997 << "extension.settings does not exist " << msg;
1000 const base::DictionaryValue* pref = NULL;
1001 if (!dict->GetDictionary(extension_id, &pref)) {
1002 return testing::AssertionFailure()
1003 << "extension pref does not exist " << msg;
1006 bool val;
1007 if (!pref->GetBoolean(pref_path, &val)) {
1008 return testing::AssertionFailure()
1009 << pref_path << " pref not found " << msg;
1012 return expected_val == val
1013 ? testing::AssertionSuccess()
1014 : testing::AssertionFailure() << "base::Value is incorrect " << msg;
1017 bool IsPrefExist(const std::string& extension_id,
1018 const std::string& pref_path) {
1019 const base::DictionaryValue* dict =
1020 profile()->GetPrefs()->GetDictionary("extensions.settings");
1021 if (dict == NULL) return false;
1022 const base::DictionaryValue* pref = NULL;
1023 if (!dict->GetDictionary(extension_id, &pref)) {
1024 return false;
1026 if (pref == NULL) {
1027 return false;
1029 bool val;
1030 if (!pref->GetBoolean(pref_path, &val)) {
1031 return false;
1033 return true;
1036 void ValidateIntegerPref(const std::string& extension_id,
1037 const std::string& pref_path,
1038 int expected_val) {
1039 std::string msg = " while checking: ";
1040 msg += extension_id;
1041 msg += " ";
1042 msg += pref_path;
1043 msg += " == ";
1044 msg += base::IntToString(expected_val);
1046 PrefService* prefs = profile()->GetPrefs();
1047 const base::DictionaryValue* dict =
1048 prefs->GetDictionary("extensions.settings");
1049 ASSERT_TRUE(dict != NULL) << msg;
1050 const base::DictionaryValue* pref = NULL;
1051 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1052 EXPECT_TRUE(pref != NULL) << msg;
1053 int val;
1054 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
1055 EXPECT_EQ(expected_val, val) << msg;
1058 void ValidateStringPref(const std::string& extension_id,
1059 const std::string& pref_path,
1060 const std::string& expected_val) {
1061 std::string msg = " while checking: ";
1062 msg += extension_id;
1063 msg += ".manifest.";
1064 msg += pref_path;
1065 msg += " == ";
1066 msg += expected_val;
1068 const base::DictionaryValue* dict =
1069 profile()->GetPrefs()->GetDictionary("extensions.settings");
1070 ASSERT_TRUE(dict != NULL) << msg;
1071 const base::DictionaryValue* pref = NULL;
1072 std::string manifest_path = extension_id + ".manifest";
1073 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
1074 EXPECT_TRUE(pref != NULL) << msg;
1075 std::string val;
1076 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
1077 EXPECT_EQ(expected_val, val) << msg;
1080 void SetPref(const std::string& extension_id,
1081 const std::string& pref_path,
1082 base::Value* value,
1083 const std::string& msg) {
1084 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1085 base::DictionaryValue* dict = update.Get();
1086 ASSERT_TRUE(dict != NULL) << msg;
1087 base::DictionaryValue* pref = NULL;
1088 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1089 EXPECT_TRUE(pref != NULL) << msg;
1090 pref->Set(pref_path, value);
1093 void SetPrefInteg(const std::string& extension_id,
1094 const std::string& pref_path,
1095 int value) {
1096 std::string msg = " while setting: ";
1097 msg += extension_id;
1098 msg += " ";
1099 msg += pref_path;
1100 msg += " = ";
1101 msg += base::IntToString(value);
1103 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1106 void SetPrefBool(const std::string& extension_id,
1107 const std::string& pref_path,
1108 bool value) {
1109 std::string msg = " while setting: ";
1110 msg += extension_id + " " + pref_path;
1111 msg += " = ";
1112 msg += (value ? "true" : "false");
1114 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1117 void ClearPref(const std::string& extension_id,
1118 const std::string& pref_path) {
1119 std::string msg = " while clearing: ";
1120 msg += extension_id + " " + pref_path;
1122 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1123 base::DictionaryValue* dict = update.Get();
1124 ASSERT_TRUE(dict != NULL) << msg;
1125 base::DictionaryValue* pref = NULL;
1126 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1127 EXPECT_TRUE(pref != NULL) << msg;
1128 pref->Remove(pref_path, NULL);
1131 void SetPrefStringSet(const std::string& extension_id,
1132 const std::string& pref_path,
1133 const std::set<std::string>& value) {
1134 std::string msg = " while setting: ";
1135 msg += extension_id + " " + pref_path;
1137 base::ListValue* list_value = new base::ListValue();
1138 for (std::set<std::string>::const_iterator iter = value.begin();
1139 iter != value.end(); ++iter)
1140 list_value->Append(new base::StringValue(*iter));
1142 SetPref(extension_id, pref_path, list_value, msg);
1145 void InitPluginService() {
1146 #if defined(ENABLE_PLUGINS)
1147 PluginService::GetInstance()->Init();
1148 #endif
1151 void InitializeExtensionSyncService() {
1152 extension_sync_service_.reset(new ExtensionSyncService(
1153 profile(), ExtensionPrefs::Get(browser_context()), service()));
1156 void InitializeEmptyExtensionServiceWithTestingPrefs() {
1157 ExtensionServiceTestBase::ExtensionServiceInitParams params =
1158 CreateDefaultInitParams();
1159 params.pref_file = base::FilePath();
1160 InitializeExtensionService(params);
1163 extensions::ManagementPolicy* GetManagementPolicy() {
1164 return ExtensionSystem::Get(browser_context())->management_policy();
1167 ExtensionSyncService* extension_sync_service() {
1168 return extension_sync_service_.get();
1171 protected:
1172 typedef extensions::ExtensionManagementPrefUpdater<TestingPrefServiceSyncable>
1173 ManagementPrefUpdater;
1174 scoped_ptr<ExtensionSyncService> extension_sync_service_;
1175 extensions::ExtensionList loaded_;
1176 std::string unloaded_id_;
1177 UnloadedExtensionInfo::Reason unloaded_reason_;
1178 const Extension* installed_;
1179 bool was_update_;
1180 std::string old_name_;
1181 FeatureSwitch::ScopedOverride override_external_install_prompt_;
1183 private:
1184 // Create a CrxInstaller and install the CRX file.
1185 // Instead of calling this method yourself, use InstallCRX(), which does extra
1186 // error checking.
1187 void InstallCRXInternal(const base::FilePath& crx_path) {
1188 InstallCRXInternal(crx_path, Extension::NO_FLAGS);
1191 void InstallCRXInternal(const base::FilePath& crx_path, int creation_flags) {
1192 ASSERT_TRUE(base::PathExists(crx_path))
1193 << "Path does not exist: "<< crx_path.value().c_str();
1194 scoped_refptr<CrxInstaller> installer(
1195 CrxInstaller::CreateSilent(service()));
1196 installer->set_creation_flags(creation_flags);
1197 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT))
1198 installer->set_allow_silent_install(true);
1200 content::WindowedNotificationObserver observer(
1201 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1202 content::Source<extensions::CrxInstaller>(installer.get()));
1204 installer->InstallCrx(crx_path);
1206 observer.Wait();
1209 size_t expected_extensions_count_;
1210 content::NotificationRegistrar registrar_;
1213 // Receives notifications from a PackExtensionJob, indicating either that
1214 // packing succeeded or that there was some error.
1215 class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
1216 public:
1217 PackExtensionTestClient(const base::FilePath& expected_crx_path,
1218 const base::FilePath& expected_private_key_path);
1219 void OnPackSuccess(const base::FilePath& crx_path,
1220 const base::FilePath& private_key_path) override;
1221 void OnPackFailure(const std::string& error_message,
1222 ExtensionCreator::ErrorType type) override;
1224 private:
1225 const base::FilePath expected_crx_path_;
1226 const base::FilePath expected_private_key_path_;
1227 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
1230 PackExtensionTestClient::PackExtensionTestClient(
1231 const base::FilePath& expected_crx_path,
1232 const base::FilePath& expected_private_key_path)
1233 : expected_crx_path_(expected_crx_path),
1234 expected_private_key_path_(expected_private_key_path) {}
1236 // If packing succeeded, we make sure that the package names match our
1237 // expectations.
1238 void PackExtensionTestClient::OnPackSuccess(
1239 const base::FilePath& crx_path,
1240 const base::FilePath& private_key_path) {
1241 // We got the notification and processed it; we don't expect any further tasks
1242 // to be posted to the current thread, so we should stop blocking and continue
1243 // on with the rest of the test.
1244 // This call to |Quit()| matches the call to |Run()| in the
1245 // |PackPunctuatedExtension| test.
1246 base::MessageLoop::current()->Quit();
1247 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
1248 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
1249 ASSERT_TRUE(base::PathExists(private_key_path));
1252 // The tests are designed so that we never expect to see a packing error.
1253 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1254 ExtensionCreator::ErrorType type) {
1255 if (type == ExtensionCreator::kCRXExists)
1256 FAIL() << "Packing should not fail.";
1257 else
1258 FAIL() << "Existing CRX should have been overwritten.";
1261 // Test loading good extensions from the profile directory.
1262 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1263 InitPluginService();
1264 InitializeGoodInstalledExtensionService();
1265 service()->Init();
1267 uint32 expected_num_extensions = 3u;
1268 ASSERT_EQ(expected_num_extensions, loaded_.size());
1270 EXPECT_EQ(std::string(good0), loaded_[0]->id());
1271 EXPECT_EQ(std::string("My extension 1"),
1272 loaded_[0]->name());
1273 EXPECT_EQ(std::string("The first extension that I made."),
1274 loaded_[0]->description());
1275 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
1276 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false));
1277 EXPECT_EQ(expected_num_extensions, registry()->enabled_extensions().size());
1279 ValidatePrefKeyCount(3);
1280 ValidateIntegerPref(good0, "state", Extension::ENABLED);
1281 ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
1282 ValidateIntegerPref(good1, "state", Extension::ENABLED);
1283 ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
1284 ValidateIntegerPref(good2, "state", Extension::ENABLED);
1285 ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
1287 URLPatternSet expected_patterns;
1288 AddPattern(&expected_patterns, "file:///*");
1289 AddPattern(&expected_patterns, "http://*.google.com/*");
1290 AddPattern(&expected_patterns, "https://*.google.com/*");
1291 const Extension* extension = loaded_[0].get();
1292 const extensions::UserScriptList& scripts =
1293 extensions::ContentScriptsInfo::GetContentScripts(extension);
1294 ASSERT_EQ(2u, scripts.size());
1295 EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
1296 EXPECT_EQ(2u, scripts[0].js_scripts().size());
1297 ExtensionResource resource00(extension->id(),
1298 scripts[0].js_scripts()[0].extension_root(),
1299 scripts[0].js_scripts()[0].relative_path());
1300 base::FilePath expected_path =
1301 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
1302 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
1303 ExtensionResource resource01(extension->id(),
1304 scripts[0].js_scripts()[1].extension_root(),
1305 scripts[0].js_scripts()[1].relative_path());
1306 expected_path =
1307 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
1308 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
1309 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension));
1310 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
1311 EXPECT_EQ("http://*.news.com/*",
1312 scripts[1].url_patterns().begin()->GetAsString());
1313 ExtensionResource resource10(extension->id(),
1314 scripts[1].js_scripts()[0].extension_root(),
1315 scripts[1].js_scripts()[0].relative_path());
1316 expected_path =
1317 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
1318 expected_path = base::MakeAbsoluteFilePath(expected_path);
1319 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
1321 expected_patterns.ClearPatterns();
1322 AddPattern(&expected_patterns, "http://*.google.com/*");
1323 AddPattern(&expected_patterns, "https://*.google.com/*");
1324 EXPECT_EQ(
1325 expected_patterns,
1326 extension->permissions_data()->active_permissions()->explicit_hosts());
1328 EXPECT_EQ(std::string(good1), loaded_[1]->id());
1329 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
1330 EXPECT_EQ(std::string(), loaded_[1]->description());
1331 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
1332 extensions::BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
1333 EXPECT_EQ(0u,
1334 extensions::ContentScriptsInfo::GetContentScripts(loaded_[1].get())
1335 .size());
1337 // We don't parse the plugins section on Chrome OS.
1338 #if defined(OS_CHROMEOS)
1339 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1340 #else
1341 ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1342 const std::vector<extensions::PluginInfo>* plugins =
1343 extensions::PluginInfo::GetPlugins(loaded_[1].get());
1344 ASSERT_TRUE(plugins);
1345 ASSERT_EQ(2u, plugins->size());
1346 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
1347 plugins->at(0).path.value());
1348 EXPECT_TRUE(plugins->at(0).is_public);
1349 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1350 plugins->at(1).path.value());
1351 EXPECT_FALSE(plugins->at(1).is_public);
1352 #endif
1354 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
1356 int index = expected_num_extensions - 1;
1357 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1358 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1359 EXPECT_EQ(std::string(), loaded_[index]->description());
1360 EXPECT_EQ(0u,
1361 extensions::ContentScriptsInfo::GetContentScripts(
1362 loaded_[index].get()).size());
1363 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
1366 // Test loading bad extensions from the profile directory.
1367 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
1368 // Initialize the test dir with a bad Preferences/extensions.
1369 base::FilePath source_install_dir =
1370 data_dir().AppendASCII("bad").AppendASCII("Extensions");
1371 base::FilePath pref_path =
1372 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1374 InitializeInstalledExtensionService(pref_path, source_install_dir);
1376 service()->Init();
1378 ASSERT_EQ(4u, GetErrors().size());
1379 ASSERT_EQ(0u, loaded_.size());
1381 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[0]),
1382 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1383 extensions::manifest_errors::kManifestUnreadable)) <<
1384 base::UTF16ToUTF8(GetErrors()[0]);
1386 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[1]),
1387 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1388 extensions::manifest_errors::kManifestUnreadable)) <<
1389 base::UTF16ToUTF8(GetErrors()[1]);
1391 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[2]),
1392 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1393 extensions::manifest_errors::kMissingFile)) <<
1394 base::UTF16ToUTF8(GetErrors()[2]);
1396 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[3]),
1397 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1398 extensions::manifest_errors::kManifestUnreadable)) <<
1399 base::UTF16ToUTF8(GetErrors()[3]);
1402 // Test various cases for delayed install because of missing imports.
1403 TEST_F(ExtensionServiceTest, PendingImports) {
1404 InitPluginService();
1406 base::FilePath source_install_dir =
1407 data_dir().AppendASCII("pending_updates_with_imports").AppendASCII(
1408 "Extensions");
1409 base::FilePath pref_path =
1410 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1412 InitializeInstalledExtensionService(pref_path, source_install_dir);
1414 // Verify there are no pending extensions initially.
1415 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions());
1417 service()->Init();
1418 // Wait for GarbageCollectExtensions task to complete.
1419 base::RunLoop().RunUntilIdle();
1421 // These extensions are used by the extensions we test below, they must be
1422 // installed.
1423 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1424 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1425 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1426 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1428 // Each of these extensions should have been rejected because of dependencies
1429 // that cannot be satisfied.
1430 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1431 EXPECT_FALSE(
1432 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1433 EXPECT_FALSE(
1434 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1435 EXPECT_FALSE(
1436 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1437 EXPECT_FALSE(
1438 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1439 EXPECT_FALSE(
1440 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
1441 EXPECT_FALSE(
1442 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
1444 // Make sure the import started for the extension with a dependency.
1445 EXPECT_TRUE(
1446 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1447 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1448 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1450 EXPECT_FALSE(base::PathExists(extensions_install_dir().AppendASCII(
1451 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
1453 EXPECT_TRUE(service()->pending_extension_manager()->HasPendingExtensions());
1454 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
1455 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
1456 // Remove it because we are not testing the pending extension manager's
1457 // ability to download and install extensions.
1458 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id));
1461 // Test installing extensions. This test tries to install few extensions using
1462 // crx files. If you need to change those crx files, feel free to repackage
1463 // them, throw away the key used and change the id's above.
1464 TEST_F(ExtensionServiceTest, InstallExtension) {
1465 InitializeEmptyExtensionService();
1467 // Extensions not enabled.
1468 service()->set_extensions_enabled(false);
1469 base::FilePath path = data_dir().AppendASCII("good.crx");
1470 InstallCRX(path, INSTALL_FAILED);
1471 service()->set_extensions_enabled(true);
1473 ValidatePrefKeyCount(0);
1475 // A simple extension that should install without error.
1476 path = data_dir().AppendASCII("good.crx");
1477 InstallCRX(path, INSTALL_NEW);
1478 // TODO(erikkay): verify the contents of the installed extension.
1480 int pref_count = 0;
1481 ValidatePrefKeyCount(++pref_count);
1482 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1483 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
1485 // An extension with page actions.
1486 path = data_dir().AppendASCII("page_action.crx");
1487 InstallCRX(path, INSTALL_NEW);
1488 ValidatePrefKeyCount(++pref_count);
1489 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1490 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
1492 // Bad signature.
1493 path = data_dir().AppendASCII("bad_signature.crx");
1494 InstallCRX(path, INSTALL_FAILED);
1495 ValidatePrefKeyCount(pref_count);
1497 // 0-length extension file.
1498 path = data_dir().AppendASCII("not_an_extension.crx");
1499 InstallCRX(path, INSTALL_FAILED);
1500 ValidatePrefKeyCount(pref_count);
1502 // Bad magic number.
1503 path = data_dir().AppendASCII("bad_magic.crx");
1504 InstallCRX(path, INSTALL_FAILED);
1505 ValidatePrefKeyCount(pref_count);
1507 // Packed extensions may have folders or files that have underscores.
1508 // This will only cause a warning, rather than a fatal error.
1509 path = data_dir().AppendASCII("bad_underscore.crx");
1510 InstallCRX(path, INSTALL_NEW);
1511 ValidatePrefKeyCount(++pref_count);
1513 // A test for an extension with a 2048-bit public key.
1514 path = data_dir().AppendASCII("good2048.crx");
1515 InstallCRX(path, INSTALL_NEW);
1516 ValidatePrefKeyCount(++pref_count);
1517 ValidateIntegerPref(good2048, "state", Extension::ENABLED);
1518 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
1520 // TODO(erikkay): add more tests for many of the failure cases.
1521 // TODO(erikkay): add tests for upgrade cases.
1524 struct MockExtensionRegistryObserver
1525 : public extensions::ExtensionRegistryObserver {
1526 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
1527 const Extension* extension,
1528 bool is_update,
1529 bool from_ephemeral,
1530 const std::string& old_name) override {
1531 last_extension_installed = extension->id();
1534 void OnExtensionUninstalled(content::BrowserContext* browser_context,
1535 const Extension* extension,
1536 extensions::UninstallReason reason) override {
1537 last_extension_uninstalled = extension->id();
1540 std::string last_extension_installed;
1541 std::string last_extension_uninstalled;
1544 // Test that correct notifications are sent to ExtensionRegistryObserver on
1545 // extension install and uninstall.
1546 TEST_F(ExtensionServiceTest, InstallObserverNotified) {
1547 InitializeEmptyExtensionService();
1549 extensions::ExtensionRegistry* registry(
1550 extensions::ExtensionRegistry::Get(profile()));
1551 MockExtensionRegistryObserver observer;
1552 registry->AddObserver(&observer);
1554 // A simple extension that should install without error.
1555 ASSERT_TRUE(observer.last_extension_installed.empty());
1556 base::FilePath path = data_dir().AppendASCII("good.crx");
1557 InstallCRX(path, INSTALL_NEW);
1558 ASSERT_EQ(good_crx, observer.last_extension_installed);
1560 // Uninstall the extension.
1561 ASSERT_TRUE(observer.last_extension_uninstalled.empty());
1562 UninstallExtension(good_crx, false);
1563 ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
1565 registry->RemoveObserver(&observer);
1568 // Tests that flags passed to OnExternalExtensionFileFound() make it to the
1569 // extension object.
1570 TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
1571 const char kPrefFromBookmark[] = "from_bookmark";
1573 InitializeEmptyExtensionService();
1575 base::FilePath path = data_dir().AppendASCII("good.crx");
1576 service()->set_extensions_enabled(true);
1578 // Register and install an external extension.
1579 Version version("1.0.0.0");
1580 content::WindowedNotificationObserver observer(
1581 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1582 content::NotificationService::AllSources());
1583 if (service()->OnExternalExtensionFileFound(
1584 good_crx,
1585 &version,
1586 path,
1587 Manifest::EXTERNAL_PREF,
1588 Extension::FROM_BOOKMARK,
1589 false /* mark_acknowledged */,
1590 false /* install_immediately */)) {
1591 observer.Wait();
1594 const Extension* extension = service()->GetExtensionById(good_crx, false);
1595 ASSERT_TRUE(extension);
1596 ASSERT_TRUE(extension->from_bookmark());
1597 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1599 // Upgrade to version 2.0, the flag should be preserved.
1600 path = data_dir().AppendASCII("good2.crx");
1601 UpdateExtension(good_crx, path, ENABLED);
1602 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1603 extension = service()->GetExtensionById(good_crx, false);
1604 ASSERT_TRUE(extension);
1605 ASSERT_TRUE(extension->from_bookmark());
1608 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1609 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
1610 InitializeEmptyExtensionService();
1612 base::FilePath path = data_dir().AppendASCII("good.crx");
1613 service()->set_extensions_enabled(true);
1615 // Install an external extension.
1616 Version version("1.0.0.0");
1617 content::WindowedNotificationObserver observer(
1618 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1619 content::NotificationService::AllSources());
1620 if (service()->OnExternalExtensionFileFound(good_crx,
1621 &version,
1622 path,
1623 Manifest::EXTERNAL_PREF,
1624 Extension::NO_FLAGS,
1625 false,
1626 false)) {
1627 observer.Wait();
1630 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1632 // Uninstall it and check that its killbit gets set.
1633 UninstallExtension(good_crx, false);
1634 ValidateIntegerPref(good_crx, "state",
1635 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1637 // Try to re-install it externally. This should fail because of the killbit.
1638 service()->OnExternalExtensionFileFound(good_crx,
1639 &version,
1640 path,
1641 Manifest::EXTERNAL_PREF,
1642 Extension::NO_FLAGS,
1643 false,
1644 false);
1645 base::RunLoop().RunUntilIdle();
1646 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1647 ValidateIntegerPref(good_crx, "state",
1648 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1650 version = Version("1.0.0.1");
1651 // Repeat the same thing with a newer version of the extension.
1652 path = data_dir().AppendASCII("good2.crx");
1653 service()->OnExternalExtensionFileFound(good_crx,
1654 &version,
1655 path,
1656 Manifest::EXTERNAL_PREF,
1657 Extension::NO_FLAGS,
1658 false,
1659 false);
1660 base::RunLoop().RunUntilIdle();
1661 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1662 ValidateIntegerPref(good_crx, "state",
1663 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1665 // Try adding the same extension from an external update URL.
1666 ASSERT_FALSE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
1667 good_crx,
1668 std::string(),
1669 GURL("http:://fake.update/url"),
1670 Manifest::EXTERNAL_PREF_DOWNLOAD,
1671 Extension::NO_FLAGS,
1672 false));
1674 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
1677 // Test that uninstalling an external extension does not crash when
1678 // the extension could not be loaded.
1679 // This extension shown in preferences file requires an experimental permission.
1680 // It could not be loaded without such permission.
1681 TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
1682 base::FilePath source_install_dir =
1683 data_dir().AppendASCII("good").AppendASCII("Extensions");
1684 // The preference contains an external extension
1685 // that requires 'experimental' permission.
1686 base::FilePath pref_path = source_install_dir
1687 .DirName()
1688 .AppendASCII("PreferencesExperimental");
1690 // Aforementioned extension will not be loaded if
1691 // there is no '--enable-experimental-extension-apis' command line flag.
1692 InitializeInstalledExtensionService(pref_path, source_install_dir);
1694 service()->Init();
1696 // Check and try to uninstall it.
1697 // If we don't check whether the extension is loaded before we uninstall it
1698 // in CheckExternalUninstall, a crash will happen here because we will get or
1699 // dereference a NULL pointer (extension) inside UninstallExtension.
1700 MockExtensionProvider provider(NULL, Manifest::EXTERNAL_REGISTRY);
1701 service()->OnExternalProviderReady(&provider);
1704 // Test that external extensions with incorrect IDs are not installed.
1705 TEST_F(ExtensionServiceTest, FailOnWrongId) {
1706 InitializeEmptyExtensionService();
1707 base::FilePath path = data_dir().AppendASCII("good.crx");
1708 service()->set_extensions_enabled(true);
1710 Version version("1.0.0.0");
1712 const std::string wrong_id = all_zero;
1713 const std::string correct_id = good_crx;
1714 ASSERT_NE(correct_id, wrong_id);
1716 // Install an external extension with an ID from the external
1717 // source that is not equal to the ID in the extension manifest.
1718 content::WindowedNotificationObserver observer(
1719 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1720 content::NotificationService::AllSources());
1721 service()->OnExternalExtensionFileFound(wrong_id,
1722 &version,
1723 path,
1724 Manifest::EXTERNAL_PREF,
1725 Extension::NO_FLAGS,
1726 false,
1727 false);
1729 observer.Wait();
1730 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1732 // Try again with the right ID. Expect success.
1733 content::WindowedNotificationObserver observer2(
1734 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1735 content::NotificationService::AllSources());
1736 if (service()->OnExternalExtensionFileFound(correct_id,
1737 &version,
1738 path,
1739 Manifest::EXTERNAL_PREF,
1740 Extension::NO_FLAGS,
1741 false,
1742 false)) {
1743 observer2.Wait();
1745 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1748 // Test that external extensions with incorrect versions are not installed.
1749 TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1750 InitializeEmptyExtensionService();
1751 base::FilePath path = data_dir().AppendASCII("good.crx");
1752 service()->set_extensions_enabled(true);
1754 // Install an external extension with a version from the external
1755 // source that is not equal to the version in the extension manifest.
1756 Version wrong_version("1.2.3.4");
1757 content::WindowedNotificationObserver observer(
1758 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1759 content::NotificationService::AllSources());
1760 service()->OnExternalExtensionFileFound(good_crx,
1761 &wrong_version,
1762 path,
1763 Manifest::EXTERNAL_PREF,
1764 Extension::NO_FLAGS,
1765 false,
1766 false);
1768 observer.Wait();
1769 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1771 // Try again with the right version. Expect success.
1772 service()->pending_extension_manager()->Remove(good_crx);
1773 Version correct_version("1.0.0.0");
1774 content::WindowedNotificationObserver observer2(
1775 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1776 content::NotificationService::AllSources());
1777 if (service()->OnExternalExtensionFileFound(good_crx,
1778 &correct_version,
1779 path,
1780 Manifest::EXTERNAL_PREF,
1781 Extension::NO_FLAGS,
1782 false,
1783 false)) {
1784 observer2.Wait();
1786 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1789 // Install a user script (they get converted automatically to an extension)
1790 TEST_F(ExtensionServiceTest, InstallUserScript) {
1791 // The details of script conversion are tested elsewhere, this just tests
1792 // integration with ExtensionService.
1793 InitializeEmptyExtensionService();
1795 base::FilePath path = data_dir().AppendASCII("user_script_basic.user.js");
1797 ASSERT_TRUE(base::PathExists(path));
1798 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1799 installer->set_allow_silent_install(true);
1800 installer->InstallUserScript(
1801 path,
1802 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1804 base::RunLoop().RunUntilIdle();
1805 std::vector<base::string16> errors = GetErrors();
1806 EXPECT_TRUE(installed_) << "Nothing was installed.";
1807 EXPECT_FALSE(was_update_) << path.value();
1808 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1809 EXPECT_EQ(0u, errors.size()) << "There were errors: "
1810 << JoinString(errors, ',');
1811 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false))
1812 << path.value();
1814 installed_ = NULL;
1815 was_update_ = false;
1816 loaded_.clear();
1817 ExtensionErrorReporter::GetInstance()->ClearErrors();
1820 // Extensions don't install during shutdown.
1821 TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
1822 InitializeEmptyExtensionService();
1824 // Simulate shutdown.
1825 service()->set_browser_terminating_for_test(true);
1827 base::FilePath path = data_dir().AppendASCII("good.crx");
1828 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1829 installer->set_allow_silent_install(true);
1830 installer->InstallCrx(path);
1831 base::RunLoop().RunUntilIdle();
1833 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
1834 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
1837 // This tests that the granted permissions preferences are correctly set when
1838 // installing an extension.
1839 TEST_F(ExtensionServiceTest, GrantedPermissions) {
1840 InitializeEmptyExtensionService();
1841 base::FilePath path = data_dir().AppendASCII("permissions");
1843 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1844 path = path.AppendASCII("unknown");
1846 ASSERT_TRUE(base::PathExists(pem_path));
1847 ASSERT_TRUE(base::PathExists(path));
1849 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1851 APIPermissionSet expected_api_perms;
1852 URLPatternSet expected_host_perms;
1854 // Make sure there aren't any granted permissions before the
1855 // extension is installed.
1856 scoped_refptr<PermissionSet> known_perms(
1857 prefs->GetGrantedPermissions(permissions_crx));
1858 EXPECT_FALSE(known_perms.get());
1860 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
1862 EXPECT_EQ(0u, GetErrors().size());
1863 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1864 EXPECT_EQ(permissions_crx, extension->id());
1866 // Verify that the valid API permissions have been recognized.
1867 expected_api_perms.insert(APIPermission::kTab);
1869 AddPattern(&expected_host_perms, "http://*.google.com/*");
1870 AddPattern(&expected_host_perms, "https://*.google.com/*");
1871 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
1872 AddPattern(&expected_host_perms, "http://www.example.com/*");
1874 known_perms = prefs->GetGrantedPermissions(extension->id());
1875 EXPECT_TRUE(known_perms.get());
1876 EXPECT_FALSE(known_perms->IsEmpty());
1877 EXPECT_EQ(expected_api_perms, known_perms->apis());
1878 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1879 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
1883 #if !defined(OS_CHROMEOS)
1884 // This tests that the granted permissions preferences are correctly set for
1885 // default apps.
1886 TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
1887 InitializeEmptyExtensionService();
1888 base::FilePath path = data_dir().AppendASCII("permissions");
1890 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1891 path = path.AppendASCII("unknown");
1893 ASSERT_TRUE(base::PathExists(pem_path));
1894 ASSERT_TRUE(base::PathExists(path));
1896 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1898 APIPermissionSet expected_api_perms;
1899 URLPatternSet expected_host_perms;
1901 // Make sure there aren't any granted permissions before the
1902 // extension is installed.
1903 scoped_refptr<PermissionSet> known_perms(
1904 prefs->GetGrantedPermissions(permissions_crx));
1905 EXPECT_FALSE(known_perms.get());
1907 const Extension* extension = PackAndInstallCRX(
1908 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
1910 EXPECT_EQ(0u, GetErrors().size());
1911 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1912 EXPECT_EQ(permissions_crx, extension->id());
1914 // Verify that the valid API permissions have been recognized.
1915 expected_api_perms.insert(APIPermission::kTab);
1917 known_perms = prefs->GetGrantedPermissions(extension->id());
1918 EXPECT_TRUE(known_perms.get());
1919 EXPECT_FALSE(known_perms->IsEmpty());
1920 EXPECT_EQ(expected_api_perms, known_perms->apis());
1921 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1923 #endif
1925 #if !defined(OS_POSIX) || defined(OS_MACOSX)
1926 // Tests that the granted permissions full_access bit gets set correctly when
1927 // an extension contains an NPAPI plugin.
1928 // Only run this on platforms that support NPAPI plugins.
1929 TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
1930 InitPluginService();
1932 InitializeEmptyExtensionService();
1934 ASSERT_TRUE(base::PathExists(good1_path()));
1935 const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW);
1936 EXPECT_EQ(0u, GetErrors().size());
1937 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1938 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1940 scoped_refptr<PermissionSet> permissions(
1941 prefs->GetGrantedPermissions(extension->id()));
1942 EXPECT_FALSE(permissions->IsEmpty());
1943 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
1944 EXPECT_FALSE(permissions->apis().empty());
1945 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
1947 // Full access implies full host access too...
1948 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
1950 #endif
1952 // Tests that the extension is disabled when permissions are missing from
1953 // the extension's granted permissions preferences. (This simulates updating
1954 // the browser to a version which recognizes more permissions).
1955 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
1956 InitializeEmptyExtensionService();
1958 base::FilePath path =
1959 data_dir().AppendASCII("permissions").AppendASCII("unknown");
1961 ASSERT_TRUE(base::PathExists(path));
1963 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
1965 EXPECT_EQ(0u, GetErrors().size());
1966 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1967 std::string extension_id = extension->id();
1969 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1971 APIPermissionSet expected_api_permissions;
1972 URLPatternSet expected_host_permissions;
1974 expected_api_permissions.insert(APIPermission::kTab);
1975 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1976 AddPattern(&expected_host_permissions, "https://*.google.com/*");
1977 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
1978 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1980 std::set<std::string> host_permissions;
1982 // Test that the extension is disabled when an API permission is missing from
1983 // the extension's granted api permissions preference. (This simulates
1984 // updating the browser to a version which recognizes a new API permission).
1985 SetPref(extension_id, "granted_permissions.api",
1986 new base::ListValue(), "granted_permissions.api");
1987 service()->ReloadExtensionsForTest();
1989 EXPECT_EQ(1u, registry()->disabled_extensions().size());
1990 extension = registry()->disabled_extensions().begin()->get();
1992 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
1993 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
1994 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1996 // Now grant and re-enable the extension, making sure the prefs are updated.
1997 service()->GrantPermissionsAndEnableExtension(extension);
1999 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
2000 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
2001 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2003 scoped_refptr<PermissionSet> current_perms(
2004 prefs->GetGrantedPermissions(extension_id));
2005 ASSERT_TRUE(current_perms.get());
2006 ASSERT_FALSE(current_perms->IsEmpty());
2007 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2008 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2009 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2011 // Tests that the extension is disabled when a host permission is missing from
2012 // the extension's granted host permissions preference. (This simulates
2013 // updating the browser to a version which recognizes additional host
2014 // permissions).
2015 host_permissions.clear();
2016 current_perms = NULL;
2018 host_permissions.insert("http://*.google.com/*");
2019 host_permissions.insert("https://*.google.com/*");
2020 host_permissions.insert("http://*.google.com.hk/*");
2022 base::ListValue* api_permissions = new base::ListValue();
2023 api_permissions->Append(
2024 new base::StringValue("tabs"));
2025 SetPref(extension_id, "granted_permissions.api",
2026 api_permissions, "granted_permissions.api");
2027 SetPrefStringSet(
2028 extension_id, "granted_permissions.scriptable_host", host_permissions);
2030 service()->ReloadExtensionsForTest();
2032 EXPECT_EQ(1u, registry()->disabled_extensions().size());
2033 extension = registry()->disabled_extensions().begin()->get();
2035 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2036 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
2037 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2039 // Now grant and re-enable the extension, making sure the prefs are updated.
2040 service()->GrantPermissionsAndEnableExtension(extension);
2042 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
2043 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2045 current_perms = prefs->GetGrantedPermissions(extension_id);
2046 ASSERT_TRUE(current_perms.get());
2047 ASSERT_FALSE(current_perms->IsEmpty());
2048 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2049 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2050 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2053 // Test Packaging and installing an extension.
2054 TEST_F(ExtensionServiceTest, PackExtension) {
2055 InitializeEmptyExtensionService();
2056 base::FilePath input_directory =
2057 data_dir()
2058 .AppendASCII("good")
2059 .AppendASCII("Extensions")
2060 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2061 .AppendASCII("1.0.0.0");
2063 base::ScopedTempDir temp_dir;
2064 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2065 base::FilePath output_directory = temp_dir.path();
2067 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2068 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2070 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2071 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2072 privkey_path, ExtensionCreator::kNoRunFlags));
2073 ASSERT_TRUE(base::PathExists(crx_path));
2074 ASSERT_TRUE(base::PathExists(privkey_path));
2076 // Repeat the run with the pem file gone, and no special flags
2077 // Should refuse to overwrite the existing crx.
2078 base::DeleteFile(privkey_path, false);
2079 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2080 privkey_path, ExtensionCreator::kNoRunFlags));
2082 // OK, now try it with a flag to overwrite existing crx. Should work.
2083 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2084 privkey_path, ExtensionCreator::kOverwriteCRX));
2086 // Repeat the run allowing existing crx, but the existing pem is still
2087 // an error. Should fail.
2088 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2089 privkey_path, ExtensionCreator::kOverwriteCRX));
2091 ASSERT_TRUE(base::PathExists(privkey_path));
2092 InstallCRX(crx_path, INSTALL_NEW);
2094 // Try packing with invalid paths.
2095 creator.reset(new ExtensionCreator());
2096 ASSERT_FALSE(
2097 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
2098 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2100 // Try packing an empty directory. Should fail because an empty directory is
2101 // not a valid extension.
2102 base::ScopedTempDir temp_dir2;
2103 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
2104 creator.reset(new ExtensionCreator());
2105 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2106 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2108 // Try packing with an invalid manifest.
2109 std::string invalid_manifest_content = "I am not a manifest.";
2110 ASSERT_TRUE(base::WriteFile(
2111 temp_dir2.path().Append(extensions::kManifestFilename),
2112 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
2113 creator.reset(new ExtensionCreator());
2114 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2115 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2117 // Try packing with a private key that is a valid key, but invalid for the
2118 // extension.
2119 base::FilePath bad_private_key_dir =
2120 data_dir().AppendASCII("bad_private_key");
2121 crx_path = output_directory.AppendASCII("bad_private_key.crx");
2122 privkey_path = data_dir().AppendASCII("bad_private_key.pem");
2123 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
2124 privkey_path, ExtensionCreator::kOverwriteCRX));
2127 // Test Packaging and installing an extension whose name contains punctuation.
2128 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
2129 InitializeEmptyExtensionService();
2130 base::FilePath input_directory = data_dir()
2131 .AppendASCII("good")
2132 .AppendASCII("Extensions")
2133 .AppendASCII(good0)
2134 .AppendASCII("1.0.0.0");
2136 base::ScopedTempDir temp_dir;
2137 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2139 // Extension names containing punctuation, and the expected names for the
2140 // packed extensions.
2141 const base::FilePath punctuated_names[] = {
2142 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2143 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2144 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
2145 NormalizePathSeparators(),
2147 const base::FilePath expected_crx_names[] = {
2148 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2149 base::FilePath(
2150 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2151 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
2153 const base::FilePath expected_private_key_names[] = {
2154 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2155 base::FilePath(
2156 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2157 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
2160 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
2161 SCOPED_TRACE(punctuated_names[i].value().c_str());
2162 base::FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
2164 // Copy the extension into the output directory, as PackExtensionJob doesn't
2165 // let us choose where to output the packed extension.
2166 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
2168 base::FilePath expected_crx_path =
2169 temp_dir.path().Append(expected_crx_names[i]);
2170 base::FilePath expected_private_key_path =
2171 temp_dir.path().Append(expected_private_key_names[i]);
2172 PackExtensionTestClient pack_client(expected_crx_path,
2173 expected_private_key_path);
2174 scoped_refptr<extensions::PackExtensionJob> packer(
2175 new extensions::PackExtensionJob(&pack_client, output_dir,
2176 base::FilePath(),
2177 ExtensionCreator::kOverwriteCRX));
2178 packer->Start();
2180 // The packer will post a notification task to the current thread's message
2181 // loop when it is finished. We manually run the loop here so that we
2182 // block and catch the notification; otherwise, the process would exit.
2183 // This call to |Run()| is matched by a call to |Quit()| in the
2184 // |PackExtensionTestClient|'s notification handling code.
2185 base::MessageLoop::current()->Run();
2187 if (HasFatalFailure())
2188 return;
2190 InstallCRX(expected_crx_path, INSTALL_NEW);
2194 TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
2195 InitializeEmptyExtensionService();
2197 base::ScopedTempDir extension_temp_dir;
2198 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
2199 base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
2200 ASSERT_TRUE(
2201 base::CopyDirectory(data_dir()
2202 .AppendASCII("good")
2203 .AppendASCII("Extensions")
2204 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2205 .AppendASCII("1.0.0.0"),
2206 input_directory,
2207 /*recursive=*/true));
2209 base::ScopedTempDir output_temp_dir;
2210 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
2211 base::FilePath output_directory = output_temp_dir.path();
2213 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2214 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2216 // Pack the extension once to get a private key.
2217 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2218 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2219 privkey_path, ExtensionCreator::kNoRunFlags))
2220 << creator->error_message();
2221 ASSERT_TRUE(base::PathExists(crx_path));
2222 ASSERT_TRUE(base::PathExists(privkey_path));
2224 base::DeleteFile(crx_path, false);
2225 // Move the pem file into the extension.
2226 base::Move(privkey_path,
2227 input_directory.AppendASCII("privkey.pem"));
2229 // This pack should fail because of the contained private key.
2230 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2231 privkey_path, ExtensionCreator::kNoRunFlags));
2232 EXPECT_THAT(creator->error_message(),
2233 testing::ContainsRegex(
2234 "extension includes the key file.*privkey.pem"));
2237 // Test Packaging and installing an extension using an openssl generated key.
2238 // The openssl is generated with the following:
2239 // > openssl genrsa -out privkey.pem 1024
2240 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
2241 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
2242 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
2243 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
2244 InitializeEmptyExtensionService();
2245 base::FilePath input_directory =
2246 data_dir()
2247 .AppendASCII("good")
2248 .AppendASCII("Extensions")
2249 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2250 .AppendASCII("1.0.0.0");
2251 base::FilePath privkey_path(
2252 data_dir().AppendASCII("openssl_privkey_asn1.pem"));
2253 ASSERT_TRUE(base::PathExists(privkey_path));
2255 base::ScopedTempDir temp_dir;
2256 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2257 base::FilePath output_directory = temp_dir.path();
2259 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2261 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2262 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
2263 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2265 InstallCRX(crx_path, INSTALL_NEW);
2268 #if defined(THREAD_SANITIZER)
2269 // Flaky under Tsan. http://crbug.com/377702
2270 #define MAYBE_InstallTheme DISABLED_InstallTheme
2271 #else
2272 #define MAYBE_InstallTheme InstallTheme
2273 #endif
2275 TEST_F(ExtensionServiceTest, MAYBE_InstallTheme) {
2276 InitializeEmptyExtensionService();
2277 service()->Init();
2279 // A theme.
2280 base::FilePath path = data_dir().AppendASCII("theme.crx");
2281 InstallCRX(path, INSTALL_NEW);
2282 int pref_count = 0;
2283 ValidatePrefKeyCount(++pref_count);
2284 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2285 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2287 // A theme when extensions are disabled. Themes can be installed, even when
2288 // extensions are disabled.
2289 service()->set_extensions_enabled(false);
2290 path = data_dir().AppendASCII("theme2.crx");
2291 InstallCRX(path, INSTALL_NEW);
2292 ValidatePrefKeyCount(++pref_count);
2293 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
2294 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
2296 // A theme with extension elements. Themes cannot have extension elements,
2297 // so any such elements (like content scripts) should be ignored.
2298 service()->set_extensions_enabled(true);
2300 path = data_dir().AppendASCII("theme_with_extension.crx");
2301 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2302 ValidatePrefKeyCount(++pref_count);
2303 ASSERT_TRUE(extension);
2304 EXPECT_TRUE(extension->is_theme());
2305 EXPECT_EQ(
2307 extensions::ContentScriptsInfo::GetContentScripts(extension).size());
2310 // A theme with image resources missing (misspelt path).
2311 path = data_dir().AppendASCII("theme_missing_image.crx");
2312 InstallCRX(path, INSTALL_FAILED);
2313 ValidatePrefKeyCount(pref_count);
2316 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
2317 // Load.
2318 InitializeEmptyExtensionService();
2319 service()->Init();
2321 base::FilePath extension_path = data_dir().AppendASCII("theme_i18n");
2323 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2324 base::RunLoop().RunUntilIdle();
2325 EXPECT_EQ(0u, GetErrors().size());
2326 ASSERT_EQ(1u, loaded_.size());
2327 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2328 const Extension* theme = registry()->enabled_extensions().begin()->get();
2329 EXPECT_EQ("name", theme->name());
2330 EXPECT_EQ("description", theme->description());
2332 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a
2333 // temporary directory, but it automatically installs to the extension's
2334 // directory, and we don't want to copy the whole extension for a unittest.
2335 base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
2336 ASSERT_TRUE(base::PathExists(theme_file));
2337 ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive.
2340 #if defined(OS_POSIX)
2341 TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
2342 base::FilePath source_data_dir =
2343 data_dir().AppendASCII("unpacked").AppendASCII("symlinks_allowed");
2345 // Paths to test data files.
2346 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2347 ASSERT_TRUE(base::PathExists(source_manifest));
2348 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2349 ASSERT_TRUE(base::PathExists(source_icon));
2351 // Set up the temporary extension directory.
2352 base::ScopedTempDir temp;
2353 ASSERT_TRUE(temp.CreateUniqueTempDir());
2354 base::FilePath extension_path = temp.path();
2355 base::FilePath manifest = extension_path.Append(
2356 extensions::kManifestFilename);
2357 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2358 base::CopyFile(source_manifest, manifest);
2359 base::CreateSymbolicLink(source_icon, icon_symlink);
2361 // Load extension.
2362 InitializeEmptyExtensionService();
2363 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2364 base::RunLoop().RunUntilIdle();
2366 EXPECT_TRUE(GetErrors().empty());
2367 ASSERT_EQ(1u, loaded_.size());
2368 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2370 #endif
2372 TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
2373 InitializeEmptyExtensionService();
2374 base::FilePath extension_path = data_dir().AppendASCII("underscore_name");
2375 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2376 base::RunLoop().RunUntilIdle();
2377 EXPECT_EQ(1u, GetErrors().size());
2378 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2381 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
2382 InitializeEmptyExtensionService();
2383 service()->Init();
2385 base::FilePath theme_path = data_dir().AppendASCII("theme_i18n");
2387 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
2389 EXPECT_EQ(0u, GetErrors().size());
2390 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2391 EXPECT_EQ("name", theme->name());
2392 EXPECT_EQ("description", theme->description());
2395 TEST_F(ExtensionServiceTest, InstallApps) {
2396 InitializeEmptyExtensionService();
2398 // An empty app.
2399 const Extension* app =
2400 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2401 int pref_count = 0;
2402 ValidatePrefKeyCount(++pref_count);
2403 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2404 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2405 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
2407 // Another app with non-overlapping extent. Should succeed.
2408 PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2409 ValidatePrefKeyCount(++pref_count);
2411 // A third app whose extent overlaps the first. Should fail.
2412 PackAndInstallCRX(data_dir().AppendASCII("app3"), INSTALL_FAILED);
2413 ValidatePrefKeyCount(pref_count);
2416 // Tests that file access is OFF by default.
2417 TEST_F(ExtensionServiceTest, DefaultFileAccess) {
2418 InitializeEmptyExtensionService();
2419 const Extension* extension = PackAndInstallCRX(
2420 data_dir().AppendASCII("permissions").AppendASCII("files"), INSTALL_NEW);
2421 EXPECT_EQ(0u, GetErrors().size());
2422 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2423 EXPECT_FALSE(
2424 ExtensionPrefs::Get(profile())->AllowFileAccess(extension->id()));
2427 TEST_F(ExtensionServiceTest, UpdateApps) {
2428 InitializeEmptyExtensionService();
2429 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2431 // First install v1 of a hosted app.
2432 const Extension* extension =
2433 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2434 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2435 std::string id = extension->id();
2436 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2438 // Now try updating to v2.
2439 UpdateExtension(id,
2440 extensions_path.AppendASCII("v2.crx"),
2441 ENABLED);
2442 ASSERT_EQ(std::string("2"),
2443 service()->GetExtensionById(id, false)->version()->GetString());
2446 // Verifies that the NTP page and launch ordinals are kept when updating apps.
2447 TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
2448 InitializeEmptyExtensionService();
2449 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2450 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2452 // First install v1 of a hosted app.
2453 const Extension* extension =
2454 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2455 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2456 std::string id = extension->id();
2457 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2459 // Modify the ordinals so we can distinguish them from the defaults.
2460 syncer::StringOrdinal new_page_ordinal =
2461 sorting->GetPageOrdinal(id).CreateAfter();
2462 syncer::StringOrdinal new_launch_ordinal =
2463 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2465 sorting->SetPageOrdinal(id, new_page_ordinal);
2466 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2468 // Now try updating to v2.
2469 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2470 ASSERT_EQ(std::string("2"),
2471 service()->GetExtensionById(id, false)->version()->GetString());
2473 // Verify that the ordinals match.
2474 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2475 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
2478 // Ensures that the CWS has properly initialized ordinals.
2479 TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
2480 InitializeEmptyExtensionService();
2481 service()->component_loader()->Add(
2482 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
2483 service()->Init();
2485 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2486 EXPECT_TRUE(
2487 sorting->GetPageOrdinal(extensions::kWebStoreAppId).IsValid());
2488 EXPECT_TRUE(
2489 sorting->GetAppLaunchOrdinal(extensions::kWebStoreAppId).IsValid());
2492 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
2493 InitializeEmptyExtensionService();
2494 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2496 int pref_count = 0;
2498 // Install app1 with unlimited storage.
2499 const Extension* extension =
2500 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2501 ValidatePrefKeyCount(++pref_count);
2502 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2503 const std::string id1 = extension->id();
2504 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2505 APIPermission::kUnlimitedStorage));
2506 EXPECT_TRUE(extension->web_extent().MatchesURL(
2507 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2508 const GURL origin1(
2509 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2510 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2511 origin1));
2513 // Install app2 from the same origin with unlimited storage.
2514 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2515 ValidatePrefKeyCount(++pref_count);
2516 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2517 const std::string id2 = extension->id();
2518 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2519 APIPermission::kUnlimitedStorage));
2520 EXPECT_TRUE(extension->web_extent().MatchesURL(
2521 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2522 const GURL origin2(
2523 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2524 EXPECT_EQ(origin1, origin2);
2525 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2526 origin2));
2528 // Uninstall one of them, unlimited storage should still be granted
2529 // to the origin.
2530 UninstallExtension(id1, false);
2531 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2532 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2533 origin1));
2535 // Uninstall the other, unlimited storage should be revoked.
2536 UninstallExtension(id2, false);
2537 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2538 EXPECT_FALSE(
2539 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2540 origin2));
2543 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
2544 InitializeEmptyExtensionService();
2545 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2547 int pref_count = 0;
2549 const Extension* extension =
2550 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2551 ValidatePrefKeyCount(++pref_count);
2552 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2553 EXPECT_TRUE(extension->is_app());
2554 const std::string id1 = extension->id();
2555 const GURL origin1(
2556 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2557 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2558 origin1));
2560 // App 4 has a different origin (maps.google.com).
2561 extension = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
2562 ValidatePrefKeyCount(++pref_count);
2563 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2564 const std::string id2 = extension->id();
2565 const GURL origin2(
2566 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2567 ASSERT_NE(origin1, origin2);
2568 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2569 origin2));
2571 UninstallExtension(id1, false);
2572 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2574 UninstallExtension(id2, false);
2576 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2577 EXPECT_FALSE(
2578 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2579 origin1));
2580 EXPECT_FALSE(
2581 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2582 origin2));
2585 // Test that when an extension version is reinstalled, nothing happens.
2586 TEST_F(ExtensionServiceTest, Reinstall) {
2587 InitializeEmptyExtensionService();
2589 // A simple extension that should install without error.
2590 base::FilePath path = data_dir().AppendASCII("good.crx");
2591 InstallCRX(path, INSTALL_NEW);
2593 ValidatePrefKeyCount(1);
2594 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2595 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2597 // Reinstall the same version, it should overwrite the previous one.
2598 InstallCRX(path, INSTALL_UPDATED);
2600 ValidatePrefKeyCount(1);
2601 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2602 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2605 // Test that we can determine if extensions came from the
2606 // Chrome web store.
2607 TEST_F(ExtensionServiceTest, FromWebStore) {
2608 InitializeEmptyExtensionService();
2610 // A simple extension that should install without error.
2611 base::FilePath path = data_dir().AppendASCII("good.crx");
2612 // Not from web store.
2613 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2614 std::string id = extension->id();
2616 ValidatePrefKeyCount(1);
2617 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
2618 ASSERT_FALSE(extension->from_webstore());
2620 // Test install from web store.
2621 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
2623 ValidatePrefKeyCount(1);
2624 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2626 // Reload so extension gets reinitialized with new value.
2627 service()->ReloadExtensionsForTest();
2628 extension = service()->GetExtensionById(id, false);
2629 ASSERT_TRUE(extension->from_webstore());
2631 // Upgrade to version 2.0
2632 path = data_dir().AppendASCII("good2.crx");
2633 UpdateExtension(good_crx, path, ENABLED);
2634 ValidatePrefKeyCount(1);
2635 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2638 // Test upgrading a signed extension.
2639 TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
2640 InitializeEmptyExtensionService();
2642 base::FilePath path = data_dir().AppendASCII("good.crx");
2643 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2644 std::string id = extension->id();
2646 ASSERT_EQ("1.0.0.0", extension->version()->GetString());
2647 ASSERT_EQ(0u, GetErrors().size());
2649 // Upgrade to version 1.0.0.1.
2650 // Also test that the extension's old and new title are correctly retrieved.
2651 path = data_dir().AppendASCII("good2.crx");
2652 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
2653 extension = service()->GetExtensionById(id, false);
2655 ASSERT_EQ("1.0.0.1", extension->version()->GetString());
2656 ASSERT_EQ("My updated extension 1", extension->name());
2657 ASSERT_EQ(0u, GetErrors().size());
2660 // Test upgrading a signed extension with a bad signature.
2661 TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
2662 InitializeEmptyExtensionService();
2664 base::FilePath path = data_dir().AppendASCII("good.crx");
2665 InstallCRX(path, INSTALL_NEW);
2667 // Try upgrading with a bad signature. This should fail during the unpack,
2668 // because the key will not match the signature.
2669 path = data_dir().AppendASCII("bad_signature.crx");
2670 InstallCRX(path, INSTALL_FAILED);
2673 // Test a normal update via the UpdateExtension API
2674 TEST_F(ExtensionServiceTest, UpdateExtension) {
2675 InitializeEmptyExtensionService();
2677 base::FilePath path = data_dir().AppendASCII("good.crx");
2679 const Extension* good = InstallCRX(path, INSTALL_NEW);
2680 ASSERT_EQ("1.0.0.0", good->VersionString());
2681 ASSERT_EQ(good_crx, good->id());
2683 path = data_dir().AppendASCII("good2.crx");
2684 UpdateExtension(good_crx, path, ENABLED);
2685 ASSERT_EQ(
2686 "1.0.0.1",
2687 service()->GetExtensionById(good_crx, false)->version()->GetString());
2690 // Extensions should not be updated during browser shutdown.
2691 TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
2692 InitializeEmptyExtensionService();
2694 // Install an extension.
2695 base::FilePath path = data_dir().AppendASCII("good.crx");
2696 const Extension* good = InstallCRX(path, INSTALL_NEW);
2697 ASSERT_EQ(good_crx, good->id());
2699 // Simulate shutdown.
2700 service()->set_browser_terminating_for_test(true);
2702 // Update should fail and extension should not be updated.
2703 path = data_dir().AppendASCII("good2.crx");
2704 bool updated = service()->UpdateExtension(
2705 extensions::CRXFileInfo(good_crx, path), true, NULL);
2706 ASSERT_FALSE(updated);
2707 ASSERT_EQ(
2708 "1.0.0.0",
2709 service()->GetExtensionById(good_crx, false)->version()->GetString());
2712 // Test updating a not-already-installed extension - this should fail
2713 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
2714 InitializeEmptyExtensionService();
2716 base::FilePath path = data_dir().AppendASCII("good.crx");
2717 UpdateExtension(good_crx, path, UPDATED);
2718 base::RunLoop().RunUntilIdle();
2720 ASSERT_EQ(0u, registry()->enabled_extensions().size());
2721 ASSERT_FALSE(installed_);
2722 ASSERT_EQ(0u, loaded_.size());
2725 // Makes sure you can't downgrade an extension via UpdateExtension
2726 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
2727 InitializeEmptyExtensionService();
2729 base::FilePath path = data_dir().AppendASCII("good2.crx");
2731 const Extension* good = InstallCRX(path, INSTALL_NEW);
2732 ASSERT_EQ("1.0.0.1", good->VersionString());
2733 ASSERT_EQ(good_crx, good->id());
2735 // Change path from good2.crx -> good.crx
2736 path = data_dir().AppendASCII("good.crx");
2737 UpdateExtension(good_crx, path, FAILED);
2738 ASSERT_EQ(
2739 "1.0.0.1",
2740 service()->GetExtensionById(good_crx, false)->version()->GetString());
2743 // Make sure calling update with an identical version does nothing
2744 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
2745 InitializeEmptyExtensionService();
2747 base::FilePath path = data_dir().AppendASCII("good.crx");
2749 const Extension* good = InstallCRX(path, INSTALL_NEW);
2750 ASSERT_EQ(good_crx, good->id());
2751 UpdateExtension(good_crx, path, FAILED_SILENTLY);
2754 // Tests that updating an extension does not clobber old state.
2755 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
2756 InitializeEmptyExtensionService();
2758 base::FilePath path = data_dir().AppendASCII("good.crx");
2760 const Extension* good = InstallCRX(path, INSTALL_NEW);
2761 ASSERT_EQ("1.0.0.0", good->VersionString());
2762 ASSERT_EQ(good_crx, good->id());
2764 // Disable it and allow it to run in incognito. These settings should carry
2765 // over to the updated version.
2766 service()->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
2767 extensions::util::SetIsIncognitoEnabled(good->id(), profile(), true);
2769 path = data_dir().AppendASCII("good2.crx");
2770 UpdateExtension(good_crx, path, INSTALLED);
2771 ASSERT_EQ(1u, registry()->disabled_extensions().size());
2772 const Extension* good2 = service()->GetExtensionById(good_crx, true);
2773 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2774 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good2->id(), profile()));
2775 EXPECT_EQ(Extension::DISABLE_USER_ACTION,
2776 ExtensionPrefs::Get(profile())->GetDisableReasons(good2->id()));
2779 // Tests that updating preserves extension location.
2780 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
2781 InitializeEmptyExtensionService();
2783 base::FilePath path = data_dir().AppendASCII("good.crx");
2785 const Extension* good =
2786 InstallCRXWithLocation(path, Manifest::EXTERNAL_PREF, INSTALL_NEW);
2788 ASSERT_EQ("1.0.0.0", good->VersionString());
2789 ASSERT_EQ(good_crx, good->id());
2791 path = data_dir().AppendASCII("good2.crx");
2792 UpdateExtension(good_crx, path, ENABLED);
2793 const Extension* good2 = service()->GetExtensionById(good_crx, false);
2794 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2795 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
2798 // Makes sure that LOAD extension types can downgrade.
2799 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
2800 InitializeEmptyExtensionService();
2802 base::ScopedTempDir temp;
2803 ASSERT_TRUE(temp.CreateUniqueTempDir());
2805 // We'll write the extension manifest dynamically to a temporary path
2806 // to make it easier to change the version number.
2807 base::FilePath extension_path = temp.path();
2808 base::FilePath manifest_path =
2809 extension_path.Append(extensions::kManifestFilename);
2810 ASSERT_FALSE(base::PathExists(manifest_path));
2812 // Start with version 2.0.
2813 base::DictionaryValue manifest;
2814 manifest.SetString("version", "2.0");
2815 manifest.SetString("name", "LOAD Downgrade Test");
2816 manifest.SetInteger("manifest_version", 2);
2818 JSONFileValueSerializer serializer(manifest_path);
2819 ASSERT_TRUE(serializer.Serialize(manifest));
2821 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2822 base::RunLoop().RunUntilIdle();
2824 EXPECT_EQ(0u, GetErrors().size());
2825 ASSERT_EQ(1u, loaded_.size());
2826 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2827 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2828 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2830 // Now set the version number to 1.0, reload the extensions and verify that
2831 // the downgrade was accepted.
2832 manifest.SetString("version", "1.0");
2833 ASSERT_TRUE(serializer.Serialize(manifest));
2835 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2836 base::RunLoop().RunUntilIdle();
2838 EXPECT_EQ(0u, GetErrors().size());
2839 ASSERT_EQ(1u, loaded_.size());
2840 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2841 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2842 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2845 #if !defined(OS_POSIX) || defined(OS_MACOSX)
2846 // LOAD extensions with plugins require approval.
2847 // Only run this on platforms that support NPAPI plugins.
2848 TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
2849 base::FilePath extension_with_plugin_path = good1_path();
2850 base::FilePath extension_no_plugin_path = good2_path();
2852 InitPluginService();
2853 InitializeEmptyExtensionService();
2854 service()->set_show_extensions_prompts(true);
2856 // Start by canceling any install prompts.
2857 scoped_ptr<extensions::ScopedTestDialogAutoConfirm> auto_confirm(
2858 new extensions::ScopedTestDialogAutoConfirm(
2859 extensions::ScopedTestDialogAutoConfirm::CANCEL));
2861 // The extension that has a plugin should not install.
2862 extensions::UnpackedInstaller::Create(service())
2863 ->Load(extension_with_plugin_path);
2864 base::RunLoop().RunUntilIdle();
2865 EXPECT_EQ(0u, GetErrors().size());
2866 EXPECT_EQ(0u, loaded_.size());
2867 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2868 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2870 // But the extension with no plugin should since there's no prompt.
2871 ExtensionErrorReporter::GetInstance()->ClearErrors();
2872 extensions::UnpackedInstaller::Create(service())
2873 ->Load(extension_no_plugin_path);
2874 base::RunLoop().RunUntilIdle();
2875 EXPECT_EQ(0u, GetErrors().size());
2876 EXPECT_EQ(1u, loaded_.size());
2877 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2878 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2879 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2881 // The plugin extension should install if we accept the dialog.
2882 auto_confirm.reset();
2883 auto_confirm.reset(new extensions::ScopedTestDialogAutoConfirm(
2884 extensions::ScopedTestDialogAutoConfirm::ACCEPT));
2886 ExtensionErrorReporter::GetInstance()->ClearErrors();
2887 extensions::UnpackedInstaller::Create(service())
2888 ->Load(extension_with_plugin_path);
2889 base::RunLoop().RunUntilIdle();
2890 EXPECT_EQ(0u, GetErrors().size());
2891 EXPECT_EQ(2u, loaded_.size());
2892 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2893 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2894 EXPECT_TRUE(registry()->enabled_extensions().Contains(good1));
2895 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2897 // Make sure the granted permissions have been setup.
2898 scoped_refptr<PermissionSet> permissions(
2899 ExtensionPrefs::Get(profile())->GetGrantedPermissions(good1));
2900 EXPECT_FALSE(permissions->IsEmpty());
2901 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
2902 EXPECT_FALSE(permissions->apis().empty());
2903 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
2905 // We should be able to reload the extension without getting another prompt.
2906 loaded_.clear();
2907 auto_confirm.reset();
2908 auto_confirm.reset(new extensions::ScopedTestDialogAutoConfirm(
2909 extensions::ScopedTestDialogAutoConfirm::CANCEL));
2911 service()->ReloadExtension(good1);
2912 base::RunLoop().RunUntilIdle();
2913 EXPECT_EQ(1u, loaded_.size());
2914 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2915 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2917 #endif // !defined(OS_POSIX) || defined(OS_MACOSX)
2919 namespace {
2921 bool IsExtension(const Extension* extension) {
2922 return extension->GetType() == Manifest::TYPE_EXTENSION;
2925 #if defined(ENABLE_BLACKLIST_TESTS)
2926 std::set<std::string> StringSet(const std::string& s) {
2927 std::set<std::string> set;
2928 set.insert(s);
2929 return set;
2931 std::set<std::string> StringSet(const std::string& s1, const std::string& s2) {
2932 std::set<std::string> set = StringSet(s1);
2933 set.insert(s2);
2934 return set;
2936 #endif // defined(ENABLE_BLACKLIST_TESTS)
2938 } // namespace
2940 // Test adding a pending extension.
2941 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
2942 InitializeEmptyExtensionService();
2944 const std::string kFakeId(all_zero);
2945 const GURL kFakeUpdateURL("http:://fake.update/url");
2946 const bool kFakeRemoteInstall(false);
2947 const bool kFakeInstalledByCustodian(false);
2949 EXPECT_TRUE(
2950 service()->pending_extension_manager()->AddFromSync(
2951 kFakeId,
2952 kFakeUpdateURL,
2953 &IsExtension,
2954 kFakeRemoteInstall,
2955 kFakeInstalledByCustodian));
2957 const extensions::PendingExtensionInfo* pending_extension_info;
2958 ASSERT_TRUE((pending_extension_info =
2959 service()->pending_extension_manager()->GetById(kFakeId)));
2960 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
2961 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
2962 // Use
2963 // EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install())
2964 // instead of
2965 // EXPECT_EQ(kFakeRemoteInstall, pending_extension_info->remote_install())
2966 // as gcc 4.7 issues the following warning on EXPECT_EQ(false, x), which is
2967 // turned into an error with -Werror=conversion-null:
2968 // converting 'false' to pointer type for argument 1 of
2969 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)'
2970 // https://code.google.com/p/googletest/issues/detail?id=458
2971 EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install());
2974 namespace {
2975 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2976 const char kGoodUpdateURL[] = "http://good.update/url";
2977 const bool kGoodIsFromSync = true;
2978 const bool kGoodRemoteInstall = false;
2979 const bool kGoodInstalledByCustodian = false;
2980 } // namespace
2982 // Test updating a pending extension.
2983 TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
2984 InitializeEmptyExtensionService();
2985 EXPECT_TRUE(
2986 service()->pending_extension_manager()->AddFromSync(
2987 kGoodId,
2988 GURL(kGoodUpdateURL),
2989 &IsExtension,
2990 kGoodRemoteInstall,
2991 kGoodInstalledByCustodian));
2992 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2994 base::FilePath path = data_dir().AppendASCII("good.crx");
2995 UpdateExtension(kGoodId, path, ENABLED);
2997 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2999 const Extension* extension = service()->GetExtensionById(kGoodId, true);
3000 ASSERT_TRUE(extension);
3003 namespace {
3005 bool IsTheme(const Extension* extension) {
3006 return extension->is_theme();
3009 } // namespace
3011 // Test updating a pending theme.
3012 // Disabled due to ASAN failure. http://crbug.com/108320
3013 TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
3014 InitializeEmptyExtensionService();
3015 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3016 theme_crx, GURL(), &IsTheme, false, false));
3017 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3019 base::FilePath path = data_dir().AppendASCII("theme.crx");
3020 UpdateExtension(theme_crx, path, ENABLED);
3022 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3024 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3025 ASSERT_TRUE(extension);
3027 EXPECT_FALSE(
3028 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3029 EXPECT_TRUE(service()->IsExtensionEnabled(theme_crx));
3032 #if defined(OS_CHROMEOS)
3033 // Always fails on ChromeOS: http://crbug.com/79737
3034 #define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
3035 #else
3036 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
3037 #endif
3038 // Test updating a pending CRX as if the source is an external extension
3039 // with an update URL. In this case we don't know if the CRX is a theme
3040 // or not.
3041 TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
3042 InitializeEmptyExtensionService();
3043 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3044 theme_crx,
3045 std::string(),
3046 GURL(),
3047 Manifest::EXTERNAL_PREF_DOWNLOAD,
3048 Extension::NO_FLAGS,
3049 false));
3051 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3053 base::FilePath path = data_dir().AppendASCII("theme.crx");
3054 UpdateExtension(theme_crx, path, ENABLED);
3056 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3058 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3059 ASSERT_TRUE(extension);
3061 EXPECT_FALSE(
3062 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3063 EXPECT_TRUE(service()->IsExtensionEnabled(extension->id()));
3064 EXPECT_FALSE(
3065 extensions::util::IsIncognitoEnabled(extension->id(), profile()));
3068 // Test updating a pending CRX as if the source is an external extension
3069 // with an update URL. The external update should overwrite a sync update,
3070 // but a sync update should not overwrite a non-sync update.
3071 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
3072 InitializeEmptyExtensionService();
3074 // Add a crx to be installed from the update mechanism.
3075 EXPECT_TRUE(
3076 service()->pending_extension_manager()->AddFromSync(
3077 kGoodId,
3078 GURL(kGoodUpdateURL),
3079 &IsExtension,
3080 kGoodRemoteInstall,
3081 kGoodInstalledByCustodian));
3083 // Check that there is a pending crx, with is_from_sync set to true.
3084 const extensions::PendingExtensionInfo* pending_extension_info;
3085 ASSERT_TRUE((pending_extension_info =
3086 service()->pending_extension_manager()->GetById(kGoodId)));
3087 EXPECT_TRUE(pending_extension_info->is_from_sync());
3089 // Add a crx to be updated, with the same ID, from a non-sync source.
3090 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3091 kGoodId,
3092 std::string(),
3093 GURL(kGoodUpdateURL),
3094 Manifest::EXTERNAL_PREF_DOWNLOAD,
3095 Extension::NO_FLAGS,
3096 false));
3098 // Check that there is a pending crx, with is_from_sync set to false.
3099 ASSERT_TRUE((pending_extension_info =
3100 service()->pending_extension_manager()->GetById(kGoodId)));
3101 EXPECT_FALSE(pending_extension_info->is_from_sync());
3102 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3103 pending_extension_info->install_source());
3105 // Add a crx to be installed from the update mechanism.
3106 EXPECT_FALSE(
3107 service()->pending_extension_manager()->AddFromSync(
3108 kGoodId,
3109 GURL(kGoodUpdateURL),
3110 &IsExtension,
3111 kGoodRemoteInstall,
3112 kGoodInstalledByCustodian));
3114 // Check that the external, non-sync update was not overridden.
3115 ASSERT_TRUE((pending_extension_info =
3116 service()->pending_extension_manager()->GetById(kGoodId)));
3117 EXPECT_FALSE(pending_extension_info->is_from_sync());
3118 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3119 pending_extension_info->install_source());
3122 // Updating a theme should fail if the updater is explicitly told that
3123 // the CRX is not a theme.
3124 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
3125 InitializeEmptyExtensionService();
3126 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3127 theme_crx, GURL(), &IsExtension, false, false));
3129 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3131 base::FilePath path = data_dir().AppendASCII("theme.crx");
3132 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
3134 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3136 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3137 ASSERT_FALSE(extension);
3140 // TODO(akalin): Test updating a pending extension non-silently once
3141 // we can mock out ExtensionInstallUI and inject our version into
3142 // UpdateExtension().
3144 // Test updating a pending extension which fails the should-install test.
3145 TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
3146 InitializeEmptyExtensionService();
3147 // Add pending extension with a flipped is_theme.
3148 EXPECT_TRUE(
3149 service()->pending_extension_manager()->AddFromSync(
3150 kGoodId,
3151 GURL(kGoodUpdateURL),
3152 &IsTheme,
3153 kGoodRemoteInstall,
3154 kGoodInstalledByCustodian));
3155 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3157 base::FilePath path = data_dir().AppendASCII("good.crx");
3158 UpdateExtension(kGoodId, path, UPDATED);
3160 // TODO(akalin): Figure out how to check that the extensions
3161 // directory is cleaned up properly in OnExtensionInstalled().
3163 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3166 // TODO(akalin): Figure out how to test that installs of pending
3167 // unsyncable extensions are blocked.
3169 // Test updating a pending extension for one that is not pending.
3170 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
3171 InitializeEmptyExtensionService();
3173 base::FilePath path = data_dir().AppendASCII("good.crx");
3174 UpdateExtension(kGoodId, path, UPDATED);
3176 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3179 // Test updating a pending extension for one that is already
3180 // installed.
3181 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
3182 InitializeEmptyExtensionService();
3184 base::FilePath path = data_dir().AppendASCII("good.crx");
3185 const Extension* good = InstallCRX(path, INSTALL_NEW);
3186 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3188 EXPECT_FALSE(good->is_theme());
3190 // Use AddExtensionImpl() as AddFrom*() would balk.
3191 service()->pending_extension_manager()->AddExtensionImpl(
3192 good->id(),
3193 std::string(),
3194 extensions::ManifestURL::GetUpdateURL(good),
3195 Version(),
3196 &IsExtension,
3197 kGoodIsFromSync,
3198 Manifest::INTERNAL,
3199 Extension::NO_FLAGS,
3200 false,
3201 kGoodRemoteInstall);
3202 UpdateExtension(good->id(), path, ENABLED);
3204 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3207 #if defined(ENABLE_BLACKLIST_TESTS)
3208 // Tests blacklisting then unblacklisting extensions after the service has been
3209 // initialized.
3210 TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
3211 extensions::TestBlacklist test_blacklist;
3212 // A profile with 3 extensions installed: good0, good1, and good2.
3213 InitializeGoodInstalledExtensionService();
3214 test_blacklist.Attach(service()->blacklist_);
3215 service()->Init();
3217 const extensions::ExtensionSet& enabled_extensions =
3218 registry()->enabled_extensions();
3219 const extensions::ExtensionSet& blacklisted_extensions =
3220 registry()->blacklisted_extensions();
3222 EXPECT_TRUE(enabled_extensions.Contains(good0) &&
3223 !blacklisted_extensions.Contains(good0));
3224 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3225 !blacklisted_extensions.Contains(good1));
3226 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3227 !blacklisted_extensions.Contains(good2));
3229 EXPECT_FALSE(IsPrefExist(good0, "blacklist"));
3230 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3231 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3232 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3234 // Blacklist good0 and good1 (and an invalid extension ID).
3235 test_blacklist.SetBlacklistState(
3236 good0, extensions::BLACKLISTED_MALWARE, true);
3237 test_blacklist.SetBlacklistState(
3238 good1, extensions::BLACKLISTED_MALWARE, true);
3239 test_blacklist.SetBlacklistState(
3240 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3241 base::RunLoop().RunUntilIdle();
3243 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3244 blacklisted_extensions.Contains(good0));
3245 EXPECT_TRUE(!enabled_extensions.Contains(good1) &&
3246 blacklisted_extensions.Contains(good1));
3247 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3248 !blacklisted_extensions.Contains(good2));
3250 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3251 EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true));
3252 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3253 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3255 // Un-blacklist good1 and blacklist good2.
3256 test_blacklist.Clear(false);
3257 test_blacklist.SetBlacklistState(
3258 good0, extensions::BLACKLISTED_MALWARE, true);
3259 test_blacklist.SetBlacklistState(
3260 good2, extensions::BLACKLISTED_MALWARE, true);
3261 test_blacklist.SetBlacklistState(
3262 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3263 base::RunLoop().RunUntilIdle();
3265 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3266 blacklisted_extensions.Contains(good0));
3267 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3268 !blacklisted_extensions.Contains(good1));
3269 EXPECT_TRUE(!enabled_extensions.Contains(good2) &&
3270 blacklisted_extensions.Contains(good2));
3272 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3273 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3274 EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true));
3275 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3277 #endif // defined(ENABLE_BLACKLIST_TESTS)
3279 #if defined(ENABLE_BLACKLIST_TESTS)
3280 // Tests trying to install a blacklisted extension.
3281 TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
3282 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3283 new FakeSafeBrowsingDatabaseManager(true));
3284 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3286 InitializeEmptyExtensionService();
3287 service()->Init();
3289 // After blacklisting good_crx, we cannot install it.
3290 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
3291 base::RunLoop().RunUntilIdle();
3293 base::FilePath path = data_dir().AppendASCII("good.crx");
3294 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3295 // decide to install this silently. Somebody should fix these tests, all
3296 // 6,000 lines of them. Hah!
3297 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
3298 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3300 #endif // defined(ENABLE_BLACKLIST_TESTS)
3302 #if defined(ENABLE_BLACKLIST_TESTS)
3303 // Unload blacklisted extension on policy change.
3304 TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
3305 extensions::TestBlacklist test_blacklist;
3307 // A profile with no extensions installed.
3308 InitializeEmptyExtensionServiceWithTestingPrefs();
3309 test_blacklist.Attach(service()->blacklist_);
3311 base::FilePath path = data_dir().AppendASCII("good.crx");
3313 const Extension* good = InstallCRX(path, INSTALL_NEW);
3314 EXPECT_EQ(good_crx, good->id());
3315 UpdateExtension(good_crx, path, FAILED_SILENTLY);
3316 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3319 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3320 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3323 test_blacklist.SetBlacklistState(
3324 good_crx, extensions::BLACKLISTED_MALWARE, true);
3325 base::RunLoop().RunUntilIdle();
3327 // The good_crx is blacklisted and the whitelist doesn't negate it.
3328 ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true));
3329 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3331 #endif // defined(ENABLE_BLACKLIST_TESTS)
3333 #if defined(ENABLE_BLACKLIST_TESTS)
3334 // Tests that a blacklisted extension is eventually unloaded on startup, if it
3335 // wasn't already.
3336 TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
3337 extensions::TestBlacklist test_blacklist;
3339 // A profile with 3 extensions installed: good0, good1, and good2.
3340 InitializeGoodInstalledExtensionService();
3341 test_blacklist.Attach(service()->blacklist_);
3343 // Blacklist good1 before the service initializes.
3344 test_blacklist.SetBlacklistState(
3345 good1, extensions::BLACKLISTED_MALWARE, false);
3347 // Load extensions.
3348 service()->Init();
3349 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet
3351 base::RunLoop().RunUntilIdle();
3353 ASSERT_EQ(1u, registry()->blacklisted_extensions().size());
3354 ASSERT_EQ(2u, registry()->enabled_extensions().size());
3356 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
3357 ASSERT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3358 ASSERT_TRUE(registry()->enabled_extensions().Contains(good2));
3360 #endif // defined(ENABLE_BLACKLIST_TESTS)
3362 #if defined(ENABLE_BLACKLIST_TESTS)
3363 // Tests extensions blacklisted in prefs on startup; one still blacklisted by
3364 // safe browsing, the other not. The not-blacklisted one should recover.
3365 TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) {
3366 extensions::TestBlacklist test_blacklist;
3368 InitializeGoodInstalledExtensionService();
3369 test_blacklist.Attach(service()->blacklist_);
3370 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good0, true);
3371 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good1, true);
3373 test_blacklist.SetBlacklistState(
3374 good1, extensions::BLACKLISTED_MALWARE, false);
3376 // Extension service hasn't loaded yet, but IsExtensionEnabled reads out of
3377 // prefs. Ensure it takes into account the blacklist state (crbug.com/373842).
3378 EXPECT_FALSE(service()->IsExtensionEnabled(good0));
3379 EXPECT_FALSE(service()->IsExtensionEnabled(good1));
3380 EXPECT_TRUE(service()->IsExtensionEnabled(good2));
3382 service()->Init();
3384 EXPECT_EQ(2u, registry()->blacklisted_extensions().size());
3385 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3387 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good0));
3388 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3389 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3391 // Give time for the blacklist to update.
3392 base::RunLoop().RunUntilIdle();
3394 EXPECT_EQ(1u, registry()->blacklisted_extensions().size());
3395 EXPECT_EQ(2u, registry()->enabled_extensions().size());
3397 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3398 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3399 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3401 #endif // defined(ENABLE_BLACKLIST_TESTS)
3403 #if defined(ENABLE_BLACKLIST_TESTS)
3404 // Extension is added to blacklist with BLACKLISTED_POTENTIALLY_UNWANTED state
3405 // after it is installed. It is then successfully re-enabled by the user.
3406 TEST_F(ExtensionServiceTest, GreylistedExtensionDisabled) {
3407 extensions::TestBlacklist test_blacklist;
3408 // A profile with 3 extensions installed: good0, good1, and good2.
3409 InitializeGoodInstalledExtensionService();
3410 test_blacklist.Attach(service()->blacklist_);
3411 service()->Init();
3413 const extensions::ExtensionSet& enabled_extensions =
3414 registry()->enabled_extensions();
3415 const extensions::ExtensionSet& disabled_extensions =
3416 registry()->disabled_extensions();
3418 EXPECT_TRUE(enabled_extensions.Contains(good0));
3419 EXPECT_TRUE(enabled_extensions.Contains(good1));
3420 EXPECT_TRUE(enabled_extensions.Contains(good2));
3422 // Blacklist good0 and good1 (and an invalid extension ID).
3423 test_blacklist.SetBlacklistState(
3424 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3425 test_blacklist.SetBlacklistState(
3426 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3427 test_blacklist.SetBlacklistState(
3428 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3429 base::RunLoop().RunUntilIdle();
3431 EXPECT_FALSE(enabled_extensions.Contains(good0));
3432 EXPECT_TRUE(disabled_extensions.Contains(good0));
3433 EXPECT_FALSE(enabled_extensions.Contains(good1));
3434 EXPECT_TRUE(disabled_extensions.Contains(good1));
3435 EXPECT_TRUE(enabled_extensions.Contains(good2));
3436 EXPECT_FALSE(disabled_extensions.Contains(good2));
3438 ValidateIntegerPref(
3439 good0, "blacklist_state", extensions::BLACKLISTED_CWS_POLICY_VIOLATION);
3440 ValidateIntegerPref(
3441 good1, "blacklist_state", extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
3443 // Now user enables good0.
3444 service()->EnableExtension(good0);
3446 EXPECT_TRUE(enabled_extensions.Contains(good0));
3447 EXPECT_FALSE(disabled_extensions.Contains(good0));
3448 EXPECT_FALSE(enabled_extensions.Contains(good1));
3449 EXPECT_TRUE(disabled_extensions.Contains(good1));
3451 // Remove extensions from blacklist.
3452 test_blacklist.SetBlacklistState(
3453 good0, extensions::NOT_BLACKLISTED, true);
3454 test_blacklist.SetBlacklistState(
3455 good1, extensions::NOT_BLACKLISTED, true);
3456 base::RunLoop().RunUntilIdle();
3458 // All extensions are enabled.
3459 EXPECT_TRUE(enabled_extensions.Contains(good0));
3460 EXPECT_FALSE(disabled_extensions.Contains(good0));
3461 EXPECT_TRUE(enabled_extensions.Contains(good1));
3462 EXPECT_FALSE(disabled_extensions.Contains(good1));
3463 EXPECT_TRUE(enabled_extensions.Contains(good2));
3464 EXPECT_FALSE(disabled_extensions.Contains(good2));
3466 #endif // defined(ENABLE_BLACKLIST_TESTS)
3468 #if defined(ENABLE_BLACKLIST_TESTS)
3469 // When extension is removed from greylist, do not re-enable it if it is
3470 // disabled by user.
3471 TEST_F(ExtensionServiceTest, GreylistDontEnableManuallyDisabled) {
3472 extensions::TestBlacklist test_blacklist;
3473 // A profile with 3 extensions installed: good0, good1, and good2.
3474 InitializeGoodInstalledExtensionService();
3475 test_blacklist.Attach(service()->blacklist_);
3476 service()->Init();
3478 const extensions::ExtensionSet& enabled_extensions =
3479 registry()->enabled_extensions();
3480 const extensions::ExtensionSet& disabled_extensions =
3481 registry()->disabled_extensions();
3483 // Manually disable.
3484 service()->DisableExtension(good0,
3485 extensions::Extension::DISABLE_USER_ACTION);
3487 test_blacklist.SetBlacklistState(
3488 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3489 test_blacklist.SetBlacklistState(
3490 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3491 test_blacklist.SetBlacklistState(
3492 good2, extensions::BLACKLISTED_SECURITY_VULNERABILITY, true);
3493 base::RunLoop().RunUntilIdle();
3495 // All extensions disabled.
3496 EXPECT_FALSE(enabled_extensions.Contains(good0));
3497 EXPECT_TRUE(disabled_extensions.Contains(good0));
3498 EXPECT_FALSE(enabled_extensions.Contains(good1));
3499 EXPECT_TRUE(disabled_extensions.Contains(good1));
3500 EXPECT_FALSE(enabled_extensions.Contains(good2));
3501 EXPECT_TRUE(disabled_extensions.Contains(good2));
3503 // Greylisted extension can be enabled.
3504 service()->EnableExtension(good1);
3505 EXPECT_TRUE(enabled_extensions.Contains(good1));
3506 EXPECT_FALSE(disabled_extensions.Contains(good1));
3508 // good1 is now manually disabled.
3509 service()->DisableExtension(good1,
3510 extensions::Extension::DISABLE_USER_ACTION);
3511 EXPECT_FALSE(enabled_extensions.Contains(good1));
3512 EXPECT_TRUE(disabled_extensions.Contains(good1));
3514 // Remove extensions from blacklist.
3515 test_blacklist.SetBlacklistState(
3516 good0, extensions::NOT_BLACKLISTED, true);
3517 test_blacklist.SetBlacklistState(
3518 good1, extensions::NOT_BLACKLISTED, true);
3519 test_blacklist.SetBlacklistState(
3520 good2, extensions::NOT_BLACKLISTED, true);
3521 base::RunLoop().RunUntilIdle();
3523 // good0 and good1 remain disabled.
3524 EXPECT_FALSE(enabled_extensions.Contains(good0));
3525 EXPECT_TRUE(disabled_extensions.Contains(good0));
3526 EXPECT_FALSE(enabled_extensions.Contains(good1));
3527 EXPECT_TRUE(disabled_extensions.Contains(good1));
3528 EXPECT_TRUE(enabled_extensions.Contains(good2));
3529 EXPECT_FALSE(disabled_extensions.Contains(good2));
3531 #endif // defined(ENABLE_BLACKLIST_TESTS)
3533 #if defined(ENABLE_BLACKLIST_TESTS)
3534 // Blacklisted extension with unknown state are not enabled/disabled.
3535 TEST_F(ExtensionServiceTest, GreylistUnknownDontChange) {
3536 extensions::TestBlacklist test_blacklist;
3537 // A profile with 3 extensions installed: good0, good1, and good2.
3538 InitializeGoodInstalledExtensionService();
3539 test_blacklist.Attach(service()->blacklist_);
3540 service()->Init();
3542 const extensions::ExtensionSet& enabled_extensions =
3543 registry()->enabled_extensions();
3544 const extensions::ExtensionSet& disabled_extensions =
3545 registry()->disabled_extensions();
3547 test_blacklist.SetBlacklistState(
3548 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3549 test_blacklist.SetBlacklistState(
3550 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3551 base::RunLoop().RunUntilIdle();
3553 EXPECT_FALSE(enabled_extensions.Contains(good0));
3554 EXPECT_TRUE(disabled_extensions.Contains(good0));
3555 EXPECT_FALSE(enabled_extensions.Contains(good1));
3556 EXPECT_TRUE(disabled_extensions.Contains(good1));
3557 EXPECT_TRUE(enabled_extensions.Contains(good2));
3558 EXPECT_FALSE(disabled_extensions.Contains(good2));
3560 test_blacklist.SetBlacklistState(
3561 good0, extensions::NOT_BLACKLISTED, true);
3562 test_blacklist.SetBlacklistState(
3563 good1, extensions::BLACKLISTED_UNKNOWN, true);
3564 test_blacklist.SetBlacklistState(
3565 good2, extensions::BLACKLISTED_UNKNOWN, true);
3566 base::RunLoop().RunUntilIdle();
3568 // good0 re-enabled, other remain as they were.
3569 EXPECT_TRUE(enabled_extensions.Contains(good0));
3570 EXPECT_FALSE(disabled_extensions.Contains(good0));
3571 EXPECT_FALSE(enabled_extensions.Contains(good1));
3572 EXPECT_TRUE(disabled_extensions.Contains(good1));
3573 EXPECT_TRUE(enabled_extensions.Contains(good2));
3574 EXPECT_FALSE(disabled_extensions.Contains(good2));
3577 // Tests that blacklisted extensions cannot be reloaded, both those loaded
3578 // before and after extension service startup.
3579 TEST_F(ExtensionServiceTest, ReloadBlacklistedExtension) {
3580 extensions::TestBlacklist test_blacklist;
3582 InitializeGoodInstalledExtensionService();
3583 test_blacklist.Attach(service()->blacklist_);
3585 test_blacklist.SetBlacklistState(
3586 good1, extensions::BLACKLISTED_MALWARE, false);
3587 service()->Init();
3588 test_blacklist.SetBlacklistState(
3589 good2, extensions::BLACKLISTED_MALWARE, false);
3590 base::RunLoop().RunUntilIdle();
3592 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3593 EXPECT_EQ(StringSet(good1, good2),
3594 registry()->blacklisted_extensions().GetIDs());
3596 service()->ReloadExtension(good1);
3597 service()->ReloadExtension(good2);
3598 base::RunLoop().RunUntilIdle();
3600 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3601 EXPECT_EQ(StringSet(good1, good2),
3602 registry()->blacklisted_extensions().GetIDs());
3604 #endif // defined(ENABLE_BLACKLIST_TESTS)
3606 // Tests blocking then unblocking enabled extensions after the service has been
3607 // initialized.
3608 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledExtension) {
3609 InitializeGoodInstalledExtensionService();
3610 service()->Init();
3612 AssertExtensionBlocksAndUnblocks(true, good0);
3615 // Tests blocking then unblocking disabled extensions after the service has been
3616 // initialized.
3617 TEST_F(ExtensionServiceTest, BlockAndUnblockDisabledExtension) {
3618 InitializeGoodInstalledExtensionService();
3619 service()->Init();
3621 service()->DisableExtension(good0, Extension::DISABLE_RELOAD);
3623 AssertExtensionBlocksAndUnblocks(true, good0);
3626 // Tests blocking then unblocking terminated extensions after the service has
3627 // been initialized.
3628 TEST_F(ExtensionServiceTest, BlockAndUnblockTerminatedExtension) {
3629 InitializeGoodInstalledExtensionService();
3630 service()->Init();
3632 TerminateExtension(good0);
3634 AssertExtensionBlocksAndUnblocks(true, good0);
3637 // Tests blocking then unblocking policy-forced extensions after the service has
3638 // been initialized.
3639 TEST_F(ExtensionServiceTest, BlockAndUnblockPolicyExtension) {
3640 InitializeEmptyExtensionServiceWithTestingPrefs();
3643 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3644 // // Blacklist everything.
3645 // pref.SetBlacklistedByDefault(true);
3646 // Mark good.crx for force-installation.
3647 pref.SetIndividualExtensionAutoInstalled(
3648 good_crx, "http://example.com/update_url", true);
3651 // Have policy force-install an extension.
3652 MockExtensionProvider* provider =
3653 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3654 AddMockExternalProvider(provider);
3655 provider->UpdateOrAddExtension(
3656 good_crx, "1.0.0.0", data_dir().AppendASCII("good_crx"));
3658 // Reloading extensions should find our externally registered extension
3659 // and install it.
3660 content::WindowedNotificationObserver observer(
3661 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3662 content::NotificationService::AllSources());
3663 service()->CheckForExternalUpdates();
3664 observer.Wait();
3666 AssertExtensionBlocksAndUnblocks(false, good_crx);
3670 #if defined(ENABLE_BLACKLIST_TESTS)
3671 // Tests blocking then unblocking extensions that are blacklisted both before
3672 // and after Init().
3673 TEST_F(ExtensionServiceTest, BlockAndUnblockBlacklistedExtension) {
3674 extensions::TestBlacklist test_blacklist;
3676 InitializeGoodInstalledExtensionService();
3677 test_blacklist.Attach(service()->blacklist_);
3679 test_blacklist.SetBlacklistState(
3680 good0, extensions::BLACKLISTED_MALWARE, true);
3681 base::RunLoop().RunUntilIdle();
3683 service()->Init();
3685 test_blacklist.SetBlacklistState(
3686 good1, extensions::BLACKLISTED_MALWARE, true);
3687 base::RunLoop().RunUntilIdle();
3689 // Blacklisted extensions stay blacklisted.
3690 AssertExtensionBlocksAndUnblocks(false, good0);
3691 AssertExtensionBlocksAndUnblocks(false, good1);
3693 service()->BlockAllExtensions();
3695 // Remove an extension from the blacklist while the service is blocked.
3696 test_blacklist.SetBlacklistState(
3697 good0, extensions::NOT_BLACKLISTED, true);
3698 // Add an extension to the blacklist while the service is blocked.
3699 test_blacklist.SetBlacklistState(
3700 good2, extensions::BLACKLISTED_MALWARE, true);
3701 base::RunLoop().RunUntilIdle();
3703 // Go directly to blocked, do not pass go, do not collect $200.
3704 ASSERT_TRUE(IsBlocked(good0));
3705 // Get on the blacklist - even if you were blocked!
3706 ASSERT_FALSE(IsBlocked(good2));
3708 #endif // defined(ENABLE_BLACKLIST_TESTS)
3710 // Tests blocking then unblocking enabled component extensions after the service
3711 // has been initialized.
3712 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledComponentExtension) {
3713 InitializeEmptyExtensionServiceWithTestingPrefs();
3715 // Install a component extension.
3716 base::FilePath path = data_dir()
3717 .AppendASCII("good")
3718 .AppendASCII("Extensions")
3719 .AppendASCII(good0)
3720 .AppendASCII("1.0.0.0");
3721 std::string manifest;
3722 ASSERT_TRUE(base::ReadFileToString(
3723 path.Append(extensions::kManifestFilename), &manifest));
3724 service()->component_loader()->Add(manifest, path);
3725 service()->Init();
3727 // Component extension should never block.
3728 AssertExtensionBlocksAndUnblocks(false, good0);
3731 // Tests blocking then unblocking a theme after the service has been
3732 // initialized.
3733 TEST_F(ExtensionServiceTest, BlockAndUnblockTheme) {
3734 InitializeEmptyExtensionService();
3735 service()->Init();
3737 base::FilePath path = data_dir().AppendASCII("theme.crx");
3738 InstallCRX(path, INSTALL_NEW);
3740 AssertExtensionBlocksAndUnblocks(true, theme_crx);
3743 // Tests that blocking extensions before Init() results in loading blocked
3744 // extensions.
3745 TEST_F(ExtensionServiceTest, WillNotLoadExtensionsWhenBlocked) {
3746 InitializeGoodInstalledExtensionService();
3748 service()->BlockAllExtensions();
3750 service()->Init();
3752 ASSERT_TRUE(IsBlocked(good0));
3753 ASSERT_TRUE(IsBlocked(good0));
3754 ASSERT_TRUE(IsBlocked(good0));
3757 // Tests that IsEnabledExtension won't crash on an uninstalled extension.
3758 TEST_F(ExtensionServiceTest, IsEnabledExtensionBlockedAndNotInstalled) {
3759 InitializeEmptyExtensionService();
3761 service()->BlockAllExtensions();
3763 service()->IsExtensionEnabled(theme_crx);
3766 // Will not install extension blacklisted by policy.
3767 TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
3768 InitializeEmptyExtensionServiceWithTestingPrefs();
3770 // Blacklist everything.
3772 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3773 pref.SetBlacklistedByDefault(true);
3776 // Blacklist prevents us from installing good_crx.
3777 base::FilePath path = data_dir().AppendASCII("good.crx");
3778 InstallCRX(path, INSTALL_FAILED);
3779 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3781 // Now whitelist this particular extension.
3783 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3784 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3787 // Ensure we can now install good_crx.
3788 InstallCRX(path, INSTALL_NEW);
3789 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3792 // Extension blacklisted by policy get unloaded after installing.
3793 TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
3794 InitializeEmptyExtensionServiceWithTestingPrefs();
3796 // Install good_crx.
3797 base::FilePath path = data_dir().AppendASCII("good.crx");
3798 InstallCRX(path, INSTALL_NEW);
3799 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3802 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3803 // Blacklist this extension.
3804 pref.SetIndividualExtensionInstallationAllowed(good_crx, false);
3807 // Extension should not be running now.
3808 base::RunLoop().RunUntilIdle();
3809 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3812 // Tests that component extensions are not blacklisted by policy.
3813 TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
3814 InitializeEmptyExtensionServiceWithTestingPrefs();
3816 // Blacklist everything.
3818 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3819 pref.SetBlacklistedByDefault(true);
3822 // Install a component extension.
3823 base::FilePath path = data_dir()
3824 .AppendASCII("good")
3825 .AppendASCII("Extensions")
3826 .AppendASCII(good0)
3827 .AppendASCII("1.0.0.0");
3828 std::string manifest;
3829 ASSERT_TRUE(base::ReadFileToString(
3830 path.Append(extensions::kManifestFilename), &manifest));
3831 service()->component_loader()->Add(manifest, path);
3832 service()->Init();
3834 // Extension should be installed despite blacklist.
3835 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3836 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3838 // Poke external providers and make sure the extension is still present.
3839 service()->CheckForExternalUpdates();
3840 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3841 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3843 // Extension should not be uninstalled on blacklist changes.
3845 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3846 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3848 base::RunLoop().RunUntilIdle();
3849 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3850 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3853 // Tests that policy-installed extensions are not blacklisted by policy.
3854 TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
3855 InitializeEmptyExtensionServiceWithTestingPrefs();
3858 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3859 // Blacklist everything.
3860 pref.SetBlacklistedByDefault(true);
3861 // Mark good.crx for force-installation.
3862 pref.SetIndividualExtensionAutoInstalled(
3863 good_crx, "http://example.com/update_url", true);
3866 // Have policy force-install an extension.
3867 MockExtensionProvider* provider =
3868 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3869 AddMockExternalProvider(provider);
3870 provider->UpdateOrAddExtension(
3871 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
3873 // Reloading extensions should find our externally registered extension
3874 // and install it.
3875 content::WindowedNotificationObserver observer(
3876 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3877 content::NotificationService::AllSources());
3878 service()->CheckForExternalUpdates();
3879 observer.Wait();
3881 // Extension should be installed despite blacklist.
3882 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3883 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3885 // Blacklist update should not uninstall the extension.
3887 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3888 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3890 base::RunLoop().RunUntilIdle();
3891 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3892 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3895 // Tests that extensions cannot be installed if the policy provider prohibits
3896 // it. This functionality is implemented in CrxInstaller::ConfirmInstall().
3897 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
3898 InitializeEmptyExtensionService();
3900 GetManagementPolicy()->UnregisterAllProviders();
3901 extensions::TestManagementPolicyProvider provider_(
3902 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3903 GetManagementPolicy()->RegisterProvider(&provider_);
3905 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_FAILED);
3906 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3909 // Tests that extensions cannot be loaded from prefs if the policy provider
3910 // prohibits it. This functionality is implemented in InstalledLoader::Load().
3911 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
3912 InitializeEmptyExtensionService();
3914 // Create a fake extension to be loaded as though it were read from prefs.
3915 base::FilePath path =
3916 data_dir().AppendASCII("management").AppendASCII("simple_extension");
3917 base::DictionaryValue manifest;
3918 manifest.SetString(keys::kName, "simple_extension");
3919 manifest.SetString(keys::kVersion, "1");
3920 // UNPACKED is for extensions loaded from a directory. We use it here, even
3921 // though we're testing loading from prefs, so that we don't need to provide
3922 // an extension key.
3923 extensions::ExtensionInfo extension_info(
3924 &manifest, std::string(), path, Manifest::UNPACKED);
3926 // Ensure we can load it with no management policy in place.
3927 GetManagementPolicy()->UnregisterAllProviders();
3928 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3929 extensions::InstalledLoader(service()).Load(extension_info, false);
3930 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3932 const Extension* extension =
3933 (registry()->enabled_extensions().begin())->get();
3934 EXPECT_TRUE(
3935 service()->UninstallExtension(extension->id(),
3936 extensions::UNINSTALL_REASON_FOR_TESTING,
3937 base::Bind(&base::DoNothing),
3938 NULL));
3939 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3941 // Ensure we cannot load it if management policy prohibits installation.
3942 extensions::TestManagementPolicyProvider provider_(
3943 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3944 GetManagementPolicy()->RegisterProvider(&provider_);
3946 extensions::InstalledLoader(service()).Load(extension_info, false);
3947 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3950 // Tests disabling an extension when prohibited by the ManagementPolicy.
3951 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
3952 InitializeEmptyExtensionService();
3954 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3955 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3956 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3958 GetManagementPolicy()->UnregisterAllProviders();
3959 extensions::TestManagementPolicyProvider provider(
3960 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3961 GetManagementPolicy()->RegisterProvider(&provider);
3963 // Attempt to disable it.
3964 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3966 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3967 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3968 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3971 // Tests uninstalling an extension when prohibited by the ManagementPolicy.
3972 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
3973 InitializeEmptyExtensionService();
3975 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3976 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3977 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3979 GetManagementPolicy()->UnregisterAllProviders();
3980 extensions::TestManagementPolicyProvider provider(
3981 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3982 GetManagementPolicy()->RegisterProvider(&provider);
3984 // Attempt to uninstall it.
3985 EXPECT_FALSE(
3986 service()->UninstallExtension(good_crx,
3987 extensions::UNINSTALL_REASON_FOR_TESTING,
3988 base::Bind(&base::DoNothing),
3989 NULL));
3991 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3992 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3995 // Tests that previously installed extensions that are now prohibited from
3996 // being installed are removed.
3997 TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
3998 InitializeEmptyExtensionService();
4000 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4001 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
4002 EXPECT_EQ(2u, registry()->enabled_extensions().size());
4003 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4005 GetManagementPolicy()->UnregisterAllProviders();
4006 extensions::TestManagementPolicyProvider provider(
4007 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
4008 GetManagementPolicy()->RegisterProvider(&provider);
4010 // Run the policy check.
4011 service()->CheckManagementPolicy();
4012 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4013 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4016 // Tests that previously disabled extensions that are now required to be
4017 // enabled are re-enabled on reinstall.
4018 TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
4019 InitializeEmptyExtensionService();
4021 // Install, then disable, an extension.
4022 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4023 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4024 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4025 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4027 // Register an ExtensionManagementPolicy that requires the extension to remain
4028 // enabled.
4029 GetManagementPolicy()->UnregisterAllProviders();
4030 extensions::TestManagementPolicyProvider provider(
4031 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
4032 GetManagementPolicy()->RegisterProvider(&provider);
4034 // Reinstall the extension.
4035 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_UPDATED);
4036 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4037 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4040 // Tests that extensions disabled by management policy can be installed but
4041 // will get disabled after installing.
4042 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsEnableOnInstalled) {
4043 InitializeEmptyExtensionService();
4045 // Register an ExtensionManagementPolicy that disables all extensions, with
4046 // a specified Extension::DisableReason.
4047 GetManagementPolicy()->UnregisterAllProviders();
4048 extensions::TestManagementPolicyProvider provider(
4049 extensions::TestManagementPolicyProvider::MUST_REMAIN_DISABLED);
4050 provider.SetDisableReason(Extension::DISABLE_NOT_VERIFIED);
4051 GetManagementPolicy()->RegisterProvider(&provider);
4053 // Attempts to install an extensions, it should be installed but disabled.
4054 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4055 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4056 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_WITHOUT_LOAD);
4057 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4058 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4060 // Verifies that the disable reason is set properly.
4061 EXPECT_EQ(Extension::DISABLE_NOT_VERIFIED,
4062 service()->extension_prefs_->GetDisableReasons(kGoodId));
4065 // Tests that extensions with conflicting required permissions by enterprise
4066 // policy cannot be installed.
4067 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionNewExtensionInstall) {
4068 InitializeEmptyExtensionServiceWithTestingPrefs();
4069 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4072 // Update policy to block one of the required permissions of target.
4073 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4074 pref.AddBlockedPermission("*", "tabs");
4077 // The extension should be failed to install.
4078 PackAndInstallCRX(path, INSTALL_FAILED);
4081 // Update policy to block one of the optional permissions instead.
4082 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4083 pref.ClearBlockedPermissions("*");
4084 pref.AddBlockedPermission("*", "history");
4087 // The extension should succeed to install this time.
4088 std::string id = PackAndInstallCRX(path, INSTALL_NEW)->id();
4090 // Uninstall the extension and update policy to block some arbitrary
4091 // unknown permission.
4092 UninstallExtension(id, false);
4094 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4095 pref.ClearBlockedPermissions("*");
4096 pref.AddBlockedPermission("*", "unknown.permission.for.testing");
4099 // The extension should succeed to install as well.
4100 PackAndInstallCRX(path, INSTALL_NEW);
4103 // Tests that extension supposed to be force installed but with conflicting
4104 // required permissions cannot be installed.
4105 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionConflictsWithForceInstall) {
4106 InitializeEmptyExtensionServiceWithTestingPrefs();
4108 // Pack the crx file.
4109 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4110 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4111 base::ScopedTempDir temp_dir;
4112 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4113 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
4115 PackCRX(path, pem_path, crx_path);
4118 // Block one of the required permissions.
4119 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4120 pref.AddBlockedPermission("*", "tabs");
4123 // Use MockExtensionProvider to simulate force installing extension.
4124 MockExtensionProvider* provider =
4125 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4126 AddMockExternalProvider(provider);
4127 provider->UpdateOrAddExtension(permissions_blocklist, "1.0", crx_path);
4130 // Attempts to force install this extension.
4131 content::WindowedNotificationObserver observer(
4132 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4133 content::NotificationService::AllSources());
4134 service()->CheckForExternalUpdates();
4135 observer.Wait();
4138 // The extension should not be installed.
4139 ASSERT_FALSE(service()->GetInstalledExtension(permissions_blocklist));
4141 // Remove this extension from pending extension manager as we would like to
4142 // give another attempt later.
4143 service()->pending_extension_manager()->Remove(permissions_blocklist);
4146 // Clears the permission block list.
4147 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4148 pref.ClearBlockedPermissions("*");
4152 // Attempts to force install this extension again.
4153 content::WindowedNotificationObserver observer(
4154 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4155 content::NotificationService::AllSources());
4156 service()->CheckForExternalUpdates();
4157 observer.Wait();
4160 const Extension* installed =
4161 service()->GetInstalledExtension(permissions_blocklist);
4162 ASSERT_TRUE(installed);
4163 EXPECT_EQ(installed->location(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4166 // Tests that newer versions of an extension with conflicting required
4167 // permissions by enterprise policy cannot be updated to.
4168 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionExtensionUpdate) {
4169 InitializeEmptyExtensionServiceWithTestingPrefs();
4171 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4172 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4173 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4175 // Install 'permissions_blocklist'.
4176 const Extension* installed = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
4177 EXPECT_EQ(installed->id(), permissions_blocklist);
4180 // Block one of the required permissions of 'permissions_blocklist2'.
4181 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4182 pref.AddBlockedPermission("*", "downloads");
4185 // Install 'permissions_blocklist' again, should be updated.
4186 const Extension* updated = PackAndInstallCRX(path, pem_path, INSTALL_UPDATED);
4187 EXPECT_EQ(updated->id(), permissions_blocklist);
4189 std::string old_version = updated->VersionString();
4191 // Attempts to update to 'permissions_blocklist2' should fail.
4192 PackAndInstallCRX(path2, pem_path, INSTALL_FAILED);
4194 // Verify that the old version is still enabled.
4195 updated = service()->GetExtensionById(permissions_blocklist, false);
4196 ASSERT_TRUE(updated);
4197 EXPECT_EQ(old_version, updated->VersionString());
4200 // Tests that policy update with additional permissions blocked revoke
4201 // conflicting granted optional permissions and unload extensions with
4202 // conflicting required permissions, including the force installed ones.
4203 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionPolicyUpdate) {
4204 InitializeEmptyExtensionServiceWithTestingPrefs();
4206 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4207 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4208 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4210 // Pack the crx file.
4211 base::ScopedTempDir temp_dir;
4212 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4213 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
4215 PackCRX(path2, pem_path, crx_path);
4217 // Install two arbitary extensions with specified manifest.
4218 std::string ext1 = PackAndInstallCRX(path, INSTALL_NEW)->id();
4219 std::string ext2 = PackAndInstallCRX(path2, INSTALL_NEW)->id();
4220 ASSERT_NE(ext1, permissions_blocklist);
4221 ASSERT_NE(ext2, permissions_blocklist);
4222 ASSERT_NE(ext1, ext2);
4224 // Force install another extension with known id and same manifest as 'ext2'.
4225 std::string ext2_forced = permissions_blocklist;
4226 MockExtensionProvider* provider =
4227 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4228 AddMockExternalProvider(provider);
4229 provider->UpdateOrAddExtension(ext2_forced, "2.0", crx_path);
4231 content::WindowedNotificationObserver observer(
4232 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4233 content::NotificationService::AllSources());
4234 service()->CheckForExternalUpdates();
4235 observer.Wait();
4237 extensions::ExtensionRegistry* registry =
4238 extensions::ExtensionRegistry::Get(profile());
4240 // Verify all three extensions are installed and enabled.
4241 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext1));
4242 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2));
4243 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2_forced));
4245 // Grant all optional permissions to each extension.
4246 GrantAllOptionalPermissions(ext1);
4247 GrantAllOptionalPermissions(ext2);
4248 GrantAllOptionalPermissions(ext2_forced);
4250 scoped_refptr<const PermissionSet> active_permissions(
4251 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1));
4252 EXPECT_TRUE(active_permissions->HasAPIPermission(
4253 extensions::APIPermission::kDownloads));
4255 // Set policy to block 'downloads' permission.
4257 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4258 pref.AddBlockedPermission("*", "downloads");
4261 base::RunLoop().RunUntilIdle();
4263 // 'ext1' should still be enabled, but with 'downloads' permission revoked.
4264 EXPECT_TRUE(registry->enabled_extensions().GetByID(ext1));
4265 active_permissions =
4266 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1);
4267 EXPECT_FALSE(active_permissions->HasAPIPermission(
4268 extensions::APIPermission::kDownloads));
4270 // 'ext2' should be disabled because one of its required permissions is
4271 // blocked.
4272 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2));
4274 // 'ext2_forced' should be handled the same as 'ext2'
4275 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2_forced));
4278 // Flaky on windows; http://crbug.com/309833
4279 #if defined(OS_WIN)
4280 #define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
4281 #else
4282 #define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
4283 #endif
4284 TEST_F(ExtensionServiceTest, MAYBE_ExternalExtensionAutoAcknowledgement) {
4285 InitializeEmptyExtensionService();
4286 service()->set_extensions_enabled(true);
4289 // Register and install an external extension.
4290 MockExtensionProvider* provider =
4291 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
4292 AddMockExternalProvider(provider);
4293 provider->UpdateOrAddExtension(
4294 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
4297 // Have policy force-install an extension.
4298 MockExtensionProvider* provider = new MockExtensionProvider(
4299 service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4300 AddMockExternalProvider(provider);
4301 provider->UpdateOrAddExtension(
4302 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
4305 // Providers are set up. Let them run.
4306 int count = 2;
4307 content::WindowedNotificationObserver observer(
4308 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4309 base::Bind(&WaitForCountNotificationsCallback, &count));
4310 service()->CheckForExternalUpdates();
4312 observer.Wait();
4314 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4315 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4316 EXPECT_TRUE(service()->GetExtensionById(page_action, false));
4317 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4318 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
4319 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
4322 #if !defined(OS_CHROMEOS)
4323 // This tests if default apps are installed correctly.
4324 TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
4325 InitializeEmptyExtensionService();
4326 service()->set_extensions_enabled(true);
4329 std::string json_data =
4331 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
4332 " \"external_crx\": \"good.crx\","
4333 " \"external_version\": \"1.0.0.0\","
4334 " \"is_bookmark_app\": false"
4335 " }"
4336 "}";
4337 default_apps::Provider* provider = new default_apps::Provider(
4338 profile(),
4339 service(),
4340 new extensions::ExternalTestingLoader(json_data, data_dir()),
4341 Manifest::INTERNAL,
4342 Manifest::INVALID_LOCATION,
4343 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4345 AddMockExternalProvider(provider);
4348 ASSERT_EQ(0u, registry()->enabled_extensions().size());
4349 content::WindowedNotificationObserver observer(
4350 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4351 content::NotificationService::AllSources());
4352 service()->CheckForExternalUpdates();
4353 observer.Wait();
4355 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4356 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4357 const Extension* extension = service()->GetExtensionById(good_crx, false);
4358 EXPECT_TRUE(extension->from_webstore());
4359 EXPECT_TRUE(extension->was_installed_by_default());
4361 #endif
4363 // Tests disabling extensions
4364 TEST_F(ExtensionServiceTest, DisableExtension) {
4365 InitializeEmptyExtensionService();
4367 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4368 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4369 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4371 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4372 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4373 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4374 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4376 // Disable it.
4377 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4379 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4380 EXPECT_FALSE(service()->GetExtensionById(good_crx, false));
4381 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4382 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4383 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4384 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4387 TEST_F(ExtensionServiceTest, TerminateExtension) {
4388 InitializeEmptyExtensionService();
4390 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4391 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4392 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4393 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4394 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4396 TerminateExtension(good_crx);
4398 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4399 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4400 EXPECT_EQ(1u, registry()->terminated_extensions().size());
4401 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4404 TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
4405 InitializeEmptyExtensionService();
4407 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4408 TerminateExtension(good_crx);
4409 EXPECT_TRUE(registry()->GetExtensionById(
4410 good_crx, extensions::ExtensionRegistry::TERMINATED));
4412 // Disable it.
4413 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4415 EXPECT_FALSE(registry()->GetExtensionById(
4416 good_crx, extensions::ExtensionRegistry::TERMINATED));
4417 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4419 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4420 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4421 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4422 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4425 // Tests disabling all extensions (simulating --disable-extensions flag).
4426 TEST_F(ExtensionServiceTest, DisableAllExtensions) {
4427 InitializeEmptyExtensionService();
4429 base::FilePath path = data_dir().AppendASCII("good.crx");
4430 InstallCRX(path, INSTALL_NEW);
4432 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4433 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4435 // Disable extensions.
4436 service()->set_extensions_enabled(false);
4437 service()->ReloadExtensionsForTest();
4439 // There shouldn't be extensions in either list.
4440 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4441 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4443 // This shouldn't do anything when all extensions are disabled.
4444 service()->EnableExtension(good_crx);
4445 service()->ReloadExtensionsForTest();
4447 // There still shouldn't be extensions in either list.
4448 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4449 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4451 // And then re-enable the extensions.
4452 service()->set_extensions_enabled(true);
4453 service()->ReloadExtensionsForTest();
4455 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4456 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4459 // Tests reloading extensions.
4460 TEST_F(ExtensionServiceTest, ReloadExtensions) {
4461 InitializeEmptyExtensionService();
4463 // Simple extension that should install without error.
4464 base::FilePath path = data_dir().AppendASCII("good.crx");
4465 InstallCRX(path, INSTALL_NEW,
4466 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4467 const char* const extension_id = good_crx;
4468 service()->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
4470 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4471 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4473 service()->ReloadExtensionsForTest();
4475 // The creation flags should not change when reloading the extension.
4476 const Extension* extension = service()->GetExtensionById(good_crx, true);
4477 EXPECT_TRUE(extension->from_webstore());
4478 EXPECT_TRUE(extension->was_installed_by_default());
4479 EXPECT_FALSE(extension->from_bookmark());
4481 // Extension counts shouldn't change.
4482 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4483 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4485 service()->EnableExtension(extension_id);
4487 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4488 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4490 // Need to clear |loaded_| manually before reloading as the
4491 // EnableExtension() call above inserted into it and
4492 // UnloadAllExtensions() doesn't send out notifications.
4493 loaded_.clear();
4494 service()->ReloadExtensionsForTest();
4496 // Extension counts shouldn't change.
4497 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4498 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4501 // Tests reloading an extension.
4502 TEST_F(ExtensionServiceTest, ReloadExtension) {
4503 InitializeEmptyExtensionService();
4505 // Simple extension that should install without error.
4506 const char extension_id[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
4507 base::FilePath ext = data_dir()
4508 .AppendASCII("good")
4509 .AppendASCII("Extensions")
4510 .AppendASCII(extension_id)
4511 .AppendASCII("1.0.0.0");
4512 extensions::UnpackedInstaller::Create(service())->Load(ext);
4513 base::RunLoop().RunUntilIdle();
4515 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4516 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4518 service()->ReloadExtension(extension_id);
4520 // Extension should be disabled now, waiting to be reloaded.
4521 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4522 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4523 EXPECT_EQ(Extension::DISABLE_RELOAD,
4524 ExtensionPrefs::Get(profile())->GetDisableReasons(extension_id));
4526 // Reloading again should not crash.
4527 service()->ReloadExtension(extension_id);
4529 // Finish reloading
4530 base::RunLoop().RunUntilIdle();
4532 // Extension should be enabled again.
4533 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4534 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4537 TEST_F(ExtensionServiceTest, UninstallExtension) {
4538 InitializeEmptyExtensionService();
4539 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4540 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4541 UninstallExtension(good_crx, false);
4542 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4543 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4546 TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
4547 InitializeEmptyExtensionService();
4548 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4549 TerminateExtension(good_crx);
4550 UninstallExtension(good_crx, false);
4551 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4554 // Tests the uninstaller helper.
4555 TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
4556 InitializeEmptyExtensionService();
4557 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4558 UninstallExtension(good_crx, true);
4559 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4562 TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
4563 InitializeEmptyExtensionService();
4564 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4565 TerminateExtension(good_crx);
4566 UninstallExtension(good_crx, true);
4567 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4570 // An extension disabled because of unsupported requirements should re-enabled
4571 // if updated to a version with supported requirements as long as there are no
4572 // other disable reasons.
4573 TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
4574 InitializeEmptyExtensionService();
4575 BlackListWebGL();
4577 base::FilePath path = data_dir().AppendASCII("requirements");
4578 base::FilePath pem_path =
4579 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4580 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4581 pem_path,
4582 INSTALL_NEW);
4583 std::string id = extension_v1->id();
4584 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4586 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4588 PackCRX(path.AppendASCII("v2_bad_requirements"),
4589 pem_path,
4590 v2_bad_requirements_crx);
4591 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4592 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4594 base::FilePath v3_good_crx = GetTemporaryFile();
4596 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4597 UpdateExtension(id, v3_good_crx, ENABLED);
4598 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4601 // Extensions disabled through user action should stay disabled.
4602 TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
4603 InitializeEmptyExtensionService();
4604 BlackListWebGL();
4606 base::FilePath path = data_dir().AppendASCII("requirements");
4607 base::FilePath pem_path =
4608 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4609 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4610 pem_path,
4611 INSTALL_NEW);
4612 std::string id = extension_v1->id();
4613 service()->DisableExtension(id, Extension::DISABLE_USER_ACTION);
4614 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4616 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4618 PackCRX(path.AppendASCII("v2_bad_requirements"),
4619 pem_path,
4620 v2_bad_requirements_crx);
4621 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4622 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4624 base::FilePath v3_good_crx = GetTemporaryFile();
4626 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4627 UpdateExtension(id, v3_good_crx, INSTALLED);
4628 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4631 // The extension should not re-enabled because it was disabled from a
4632 // permission increase.
4633 TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
4634 InitializeEmptyExtensionService();
4635 BlackListWebGL();
4637 base::FilePath path = data_dir().AppendASCII("requirements");
4638 base::FilePath pem_path =
4639 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4640 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4641 pem_path,
4642 INSTALL_NEW);
4643 std::string id = extension_v1->id();
4644 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4646 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
4648 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
4649 pem_path,
4650 v2_bad_requirements_and_permissions_crx);
4651 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
4652 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4654 base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
4656 PackCRX(path.AppendASCII("v3_bad_permissions"),
4657 pem_path,
4658 v3_bad_permissions_crx);
4659 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
4660 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4663 // Unpacked extensions are not allowed to be installed if they have unsupported
4664 // requirements.
4665 TEST_F(ExtensionServiceTest, UnpackedRequirements) {
4666 InitializeEmptyExtensionService();
4667 BlackListWebGL();
4669 base::FilePath path =
4670 data_dir().AppendASCII("requirements").AppendASCII("v2_bad_requirements");
4671 extensions::UnpackedInstaller::Create(service())->Load(path);
4672 base::RunLoop().RunUntilIdle();
4673 EXPECT_EQ(1u, GetErrors().size());
4674 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4677 class ExtensionCookieCallback {
4678 public:
4679 ExtensionCookieCallback()
4680 : result_(false),
4681 weak_factory_(base::MessageLoop::current()) {}
4683 void SetCookieCallback(bool result) {
4684 base::ThreadTaskRunnerHandle::Get()->PostTask(
4685 FROM_HERE,
4686 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4687 result_ = result;
4690 void GetAllCookiesCallback(const net::CookieList& list) {
4691 base::ThreadTaskRunnerHandle::Get()->PostTask(
4692 FROM_HERE,
4693 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4694 list_ = list;
4696 net::CookieList list_;
4697 bool result_;
4698 base::WeakPtrFactory<base::MessageLoop> weak_factory_;
4701 // Verifies extension state is removed upon uninstall.
4702 TEST_F(ExtensionServiceTest, ClearExtensionData) {
4703 InitializeEmptyExtensionService();
4704 ExtensionCookieCallback callback;
4706 // Load a test extension.
4707 base::FilePath path = data_dir();
4708 path = path.AppendASCII("good.crx");
4709 const Extension* extension = InstallCRX(path, INSTALL_NEW);
4710 ASSERT_TRUE(extension);
4711 GURL ext_url(extension->url());
4712 std::string origin_id = storage::GetIdentifierFromOrigin(ext_url);
4714 // Set a cookie for the extension.
4715 net::CookieMonster* cookie_monster = profile()
4716 ->GetRequestContextForExtensions()
4717 ->GetURLRequestContext()
4718 ->cookie_store()
4719 ->GetCookieMonster();
4720 ASSERT_TRUE(cookie_monster);
4721 net::CookieOptions options;
4722 cookie_monster->SetCookieWithOptionsAsync(
4723 ext_url, "dummy=value", options,
4724 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4725 base::Unretained(&callback)));
4726 base::RunLoop().RunUntilIdle();
4727 EXPECT_TRUE(callback.result_);
4729 cookie_monster->GetAllCookiesForURLAsync(
4730 ext_url,
4731 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4732 base::Unretained(&callback)));
4733 base::RunLoop().RunUntilIdle();
4734 EXPECT_EQ(1U, callback.list_.size());
4736 // Open a database.
4737 storage::DatabaseTracker* db_tracker =
4738 BrowserContext::GetDefaultStoragePartition(profile())
4739 ->GetDatabaseTracker();
4740 base::string16 db_name = base::UTF8ToUTF16("db");
4741 base::string16 description = base::UTF8ToUTF16("db_description");
4742 int64 size;
4743 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4744 db_tracker->DatabaseClosed(origin_id, db_name);
4745 std::vector<storage::OriginInfo> origins;
4746 db_tracker->GetAllOriginsInfo(&origins);
4747 EXPECT_EQ(1U, origins.size());
4748 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4750 // Create local storage. We only simulate this by creating the backing files.
4751 // Note: This test depends on details of how the dom_storage library
4752 // stores data in the host file system.
4753 base::FilePath lso_dir_path =
4754 profile()->GetPath().AppendASCII("Local Storage");
4755 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4756 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4757 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4758 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4759 EXPECT_TRUE(base::PathExists(lso_file_path));
4761 // Create indexed db. Similarly, it is enough to only simulate this by
4762 // creating the directory on the disk.
4763 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4764 profile())->GetIndexedDBContext();
4765 idb_context->SetTaskRunnerForTesting(
4766 base::MessageLoop::current()->task_runner().get());
4767 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4768 EXPECT_TRUE(base::CreateDirectory(idb_path));
4769 EXPECT_TRUE(base::DirectoryExists(idb_path));
4771 // Uninstall the extension.
4772 base::RunLoop run_loop;
4773 ASSERT_TRUE(
4774 service()->UninstallExtension(good_crx,
4775 extensions::UNINSTALL_REASON_FOR_TESTING,
4776 run_loop.QuitClosure(),
4777 NULL));
4778 // The data deletion happens on the IO thread.
4779 run_loop.Run();
4781 // Check that the cookie is gone.
4782 cookie_monster->GetAllCookiesForURLAsync(
4783 ext_url,
4784 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4785 base::Unretained(&callback)));
4786 base::RunLoop().RunUntilIdle();
4787 EXPECT_EQ(0U, callback.list_.size());
4789 // The database should have vanished as well.
4790 origins.clear();
4791 db_tracker->GetAllOriginsInfo(&origins);
4792 EXPECT_EQ(0U, origins.size());
4794 // Check that the LSO file has been removed.
4795 EXPECT_FALSE(base::PathExists(lso_file_path));
4797 // Check if the indexed db has disappeared too.
4798 EXPECT_FALSE(base::DirectoryExists(idb_path));
4801 // Verifies app state is removed upon uninstall.
4802 TEST_F(ExtensionServiceTest, ClearAppData) {
4803 InitializeEmptyExtensionService();
4804 ExtensionCookieCallback callback;
4806 int pref_count = 0;
4808 // Install app1 with unlimited storage.
4809 const Extension* extension =
4810 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
4811 ValidatePrefKeyCount(++pref_count);
4812 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4813 const std::string id1 = extension->id();
4814 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4815 APIPermission::kUnlimitedStorage));
4816 const GURL origin1(
4817 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4818 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4819 origin1));
4820 std::string origin_id = storage::GetIdentifierFromOrigin(origin1);
4822 // Install app2 from the same origin with unlimited storage.
4823 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
4824 ValidatePrefKeyCount(++pref_count);
4825 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4826 const std::string id2 = extension->id();
4827 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4828 APIPermission::kUnlimitedStorage));
4829 EXPECT_TRUE(extension->web_extent().MatchesURL(
4830 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
4831 const GURL origin2(
4832 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4833 EXPECT_EQ(origin1, origin2);
4834 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4835 origin2));
4837 // Set a cookie for the extension.
4838 net::CookieMonster* cookie_monster = profile()
4839 ->GetRequestContext()
4840 ->GetURLRequestContext()
4841 ->cookie_store()
4842 ->GetCookieMonster();
4843 ASSERT_TRUE(cookie_monster);
4844 net::CookieOptions options;
4845 cookie_monster->SetCookieWithOptionsAsync(
4846 origin1, "dummy=value", options,
4847 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4848 base::Unretained(&callback)));
4849 base::RunLoop().RunUntilIdle();
4850 EXPECT_TRUE(callback.result_);
4852 cookie_monster->GetAllCookiesForURLAsync(
4853 origin1,
4854 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4855 base::Unretained(&callback)));
4856 base::RunLoop().RunUntilIdle();
4857 EXPECT_EQ(1U, callback.list_.size());
4859 // Open a database.
4860 storage::DatabaseTracker* db_tracker =
4861 BrowserContext::GetDefaultStoragePartition(profile())
4862 ->GetDatabaseTracker();
4863 base::string16 db_name = base::UTF8ToUTF16("db");
4864 base::string16 description = base::UTF8ToUTF16("db_description");
4865 int64 size;
4866 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4867 db_tracker->DatabaseClosed(origin_id, db_name);
4868 std::vector<storage::OriginInfo> origins;
4869 db_tracker->GetAllOriginsInfo(&origins);
4870 EXPECT_EQ(1U, origins.size());
4871 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4873 // Create local storage. We only simulate this by creating the backing files.
4874 // Note: This test depends on details of how the dom_storage library
4875 // stores data in the host file system.
4876 base::FilePath lso_dir_path =
4877 profile()->GetPath().AppendASCII("Local Storage");
4878 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4879 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4880 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4881 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4882 EXPECT_TRUE(base::PathExists(lso_file_path));
4884 // Create indexed db. Similarly, it is enough to only simulate this by
4885 // creating the directory on the disk.
4886 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4887 profile())->GetIndexedDBContext();
4888 idb_context->SetTaskRunnerForTesting(
4889 base::MessageLoop::current()->task_runner().get());
4890 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4891 EXPECT_TRUE(base::CreateDirectory(idb_path));
4892 EXPECT_TRUE(base::DirectoryExists(idb_path));
4894 // Uninstall one of them, unlimited storage should still be granted
4895 // to the origin.
4896 UninstallExtension(id1, false);
4897 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4898 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4899 origin1));
4901 // Check that the cookie is still there.
4902 cookie_monster->GetAllCookiesForURLAsync(
4903 origin1,
4904 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4905 base::Unretained(&callback)));
4906 base::RunLoop().RunUntilIdle();
4907 EXPECT_EQ(1U, callback.list_.size());
4909 // Now uninstall the other. Storage should be cleared for the apps.
4910 UninstallExtension(id2, false);
4911 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4912 EXPECT_FALSE(
4913 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4914 origin1));
4916 // Check that the cookie is gone.
4917 cookie_monster->GetAllCookiesForURLAsync(
4918 origin1,
4919 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4920 base::Unretained(&callback)));
4921 base::RunLoop().RunUntilIdle();
4922 EXPECT_EQ(0U, callback.list_.size());
4924 // The database should have vanished as well.
4925 origins.clear();
4926 db_tracker->GetAllOriginsInfo(&origins);
4927 EXPECT_EQ(0U, origins.size());
4929 // Check that the LSO file has been removed.
4930 EXPECT_FALSE(base::PathExists(lso_file_path));
4932 // Check if the indexed db has disappeared too.
4933 EXPECT_FALSE(base::DirectoryExists(idb_path));
4936 // Tests loading single extensions (like --load-extension)
4937 // Flaky crashes. http://crbug.com/231806
4938 TEST_F(ExtensionServiceTest, DISABLED_LoadExtension) {
4939 InitializeEmptyExtensionService();
4941 base::FilePath ext1 = data_dir()
4942 .AppendASCII("good")
4943 .AppendASCII("Extensions")
4944 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4945 .AppendASCII("1.0.0.0");
4946 extensions::UnpackedInstaller::Create(service())->Load(ext1);
4947 base::RunLoop().RunUntilIdle();
4948 EXPECT_EQ(0u, GetErrors().size());
4949 ASSERT_EQ(1u, loaded_.size());
4950 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
4951 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4953 ValidatePrefKeyCount(1);
4955 base::FilePath no_manifest =
4956 data_dir()
4957 .AppendASCII("bad")
4958 // .AppendASCII("Extensions")
4959 .AppendASCII("cccccccccccccccccccccccccccccccc")
4960 .AppendASCII("1");
4961 extensions::UnpackedInstaller::Create(service())->Load(no_manifest);
4962 base::RunLoop().RunUntilIdle();
4963 EXPECT_EQ(1u, GetErrors().size());
4964 ASSERT_EQ(1u, loaded_.size());
4965 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4967 // Test uninstall.
4968 std::string id = loaded_[0]->id();
4969 EXPECT_FALSE(unloaded_id_.length());
4970 service()->UninstallExtension(id,
4971 extensions::UNINSTALL_REASON_FOR_TESTING,
4972 base::Bind(&base::DoNothing),
4973 NULL);
4974 base::RunLoop().RunUntilIdle();
4975 EXPECT_EQ(id, unloaded_id_);
4976 ASSERT_EQ(0u, loaded_.size());
4977 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4980 // Tests that we generate IDs when they are not specified in the manifest for
4981 // --load-extension.
4982 TEST_F(ExtensionServiceTest, GenerateID) {
4983 InitializeEmptyExtensionService();
4985 base::FilePath no_id_ext = data_dir().AppendASCII("no_id");
4986 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
4987 base::RunLoop().RunUntilIdle();
4988 EXPECT_EQ(0u, GetErrors().size());
4989 ASSERT_EQ(1u, loaded_.size());
4990 ASSERT_TRUE(crx_file::id_util::IdIsValid(loaded_[0]->id()));
4991 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
4993 ValidatePrefKeyCount(1);
4995 std::string previous_id = loaded_[0]->id();
4997 // If we reload the same path, we should get the same extension ID.
4998 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
4999 base::RunLoop().RunUntilIdle();
5000 ASSERT_EQ(1u, loaded_.size());
5001 ASSERT_EQ(previous_id, loaded_[0]->id());
5004 TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
5005 InitializeEmptyExtensionService();
5007 base::FilePath bad_locale =
5008 data_dir().AppendASCII("unpacked").AppendASCII("bad_messages_file");
5009 extensions::UnpackedInstaller::Create(service())->Load(bad_locale);
5010 base::RunLoop().RunUntilIdle();
5011 EXPECT_EQ(1u, GetErrors().size());
5012 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
5013 .AppendASCII("ms")
5014 .AppendASCII("messages.json");
5015 EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
5016 testing::HasSubstr(
5017 base::UTF16ToUTF8(ms_messages_file.LossyDisplayName())),
5018 testing::HasSubstr("Dictionary keys must be quoted.")));
5019 ASSERT_EQ(0u, loaded_.size());
5022 void ExtensionServiceTest::TestExternalProvider(
5023 MockExtensionProvider* provider, Manifest::Location location) {
5024 // Verify that starting with no providers loads no extensions.
5025 service()->Init();
5026 ASSERT_EQ(0u, loaded_.size());
5028 provider->set_visit_count(0);
5030 // Register a test extension externally using the mock registry provider.
5031 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5033 // Add the extension.
5034 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5036 // Reloading extensions should find our externally registered extension
5037 // and install it.
5038 content::WindowedNotificationObserver observer(
5039 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5040 content::NotificationService::AllSources());
5041 service()->CheckForExternalUpdates();
5042 observer.Wait();
5044 ASSERT_EQ(0u, GetErrors().size());
5045 ASSERT_EQ(1u, loaded_.size());
5046 ASSERT_EQ(location, loaded_[0]->location());
5047 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
5048 ValidatePrefKeyCount(1);
5049 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5050 ValidateIntegerPref(good_crx, "location", location);
5052 // Reload extensions without changing anything. The extension should be
5053 // loaded again.
5054 loaded_.clear();
5055 service()->ReloadExtensionsForTest();
5056 base::RunLoop().RunUntilIdle();
5057 ASSERT_EQ(0u, GetErrors().size());
5058 ASSERT_EQ(1u, loaded_.size());
5059 ValidatePrefKeyCount(1);
5060 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5061 ValidateIntegerPref(good_crx, "location", location);
5063 // Now update the extension with a new version. We should get upgraded.
5064 source_path = source_path.DirName().AppendASCII("good2.crx");
5065 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5067 loaded_.clear();
5068 content::WindowedNotificationObserver observer_2(
5069 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5070 content::NotificationService::AllSources());
5071 service()->CheckForExternalUpdates();
5072 observer_2.Wait();
5073 ASSERT_EQ(0u, GetErrors().size());
5074 ASSERT_EQ(1u, loaded_.size());
5075 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
5076 ValidatePrefKeyCount(1);
5077 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5078 ValidateIntegerPref(good_crx, "location", location);
5080 // Uninstall the extension and reload. Nothing should happen because the
5081 // preference should prevent us from reinstalling.
5082 std::string id = loaded_[0]->id();
5083 bool no_uninstall =
5084 GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL);
5085 service()->UninstallExtension(id,
5086 extensions::UNINSTALL_REASON_FOR_TESTING,
5087 base::Bind(&base::DoNothing),
5088 NULL);
5089 base::RunLoop().RunUntilIdle();
5091 base::FilePath install_path = extensions_install_dir().AppendASCII(id);
5092 if (no_uninstall) {
5093 // Policy controlled extensions should not have been touched by uninstall.
5094 ASSERT_TRUE(base::PathExists(install_path));
5095 } else {
5096 // The extension should also be gone from the install directory.
5097 ASSERT_FALSE(base::PathExists(install_path));
5098 loaded_.clear();
5099 service()->CheckForExternalUpdates();
5100 base::RunLoop().RunUntilIdle();
5101 ASSERT_EQ(0u, loaded_.size());
5102 ValidatePrefKeyCount(1);
5103 ValidateIntegerPref(good_crx, "state",
5104 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
5105 ValidateIntegerPref(good_crx, "location", location);
5107 // Now clear the preference and reinstall.
5108 SetPrefInteg(good_crx, "state", Extension::ENABLED);
5110 loaded_.clear();
5111 content::WindowedNotificationObserver observer(
5112 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5113 content::NotificationService::AllSources());
5114 service()->CheckForExternalUpdates();
5115 observer.Wait();
5116 ASSERT_EQ(1u, loaded_.size());
5118 ValidatePrefKeyCount(1);
5119 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5120 ValidateIntegerPref(good_crx, "location", location);
5122 if (GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL)) {
5123 EXPECT_EQ(2, provider->visit_count());
5124 } else {
5125 // Now test an externally triggered uninstall (deleting the registry key or
5126 // the pref entry).
5127 provider->RemoveExtension(good_crx);
5129 loaded_.clear();
5130 service()->OnExternalProviderReady(provider);
5131 base::RunLoop().RunUntilIdle();
5132 ASSERT_EQ(0u, loaded_.size());
5133 ValidatePrefKeyCount(0);
5135 // The extension should also be gone from the install directory.
5136 ASSERT_FALSE(base::PathExists(install_path));
5138 // Now test the case where user uninstalls and then the extension is removed
5139 // from the external provider.
5140 content::WindowedNotificationObserver observer(
5141 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5142 content::NotificationService::AllSources());
5143 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5144 service()->CheckForExternalUpdates();
5145 observer.Wait();
5147 ASSERT_EQ(1u, loaded_.size());
5148 ASSERT_EQ(0u, GetErrors().size());
5150 // User uninstalls.
5151 loaded_.clear();
5152 service()->UninstallExtension(id,
5153 extensions::UNINSTALL_REASON_FOR_TESTING,
5154 base::Bind(&base::DoNothing),
5155 NULL);
5156 base::RunLoop().RunUntilIdle();
5157 ASSERT_EQ(0u, loaded_.size());
5159 // Then remove the extension from the extension provider.
5160 provider->RemoveExtension(good_crx);
5162 // Should still be at 0.
5163 loaded_.clear();
5164 extensions::InstalledLoader(service()).LoadAllExtensions();
5165 base::RunLoop().RunUntilIdle();
5166 ASSERT_EQ(0u, loaded_.size());
5167 ValidatePrefKeyCount(1);
5169 EXPECT_EQ(5, provider->visit_count());
5173 // Tests the external installation feature
5174 #if defined(OS_WIN)
5175 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
5176 // This should all work, even when normal extension installation is disabled.
5177 InitializeEmptyExtensionService();
5178 service()->set_extensions_enabled(false);
5180 // Now add providers. Extension system takes ownership of the objects.
5181 MockExtensionProvider* reg_provider =
5182 new MockExtensionProvider(service(), Manifest::EXTERNAL_REGISTRY);
5183 AddMockExternalProvider(reg_provider);
5184 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
5186 #endif
5188 TEST_F(ExtensionServiceTest, ExternalInstallPref) {
5189 InitializeEmptyExtensionService();
5191 // Now add providers. Extension system takes ownership of the objects.
5192 MockExtensionProvider* pref_provider =
5193 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
5195 AddMockExternalProvider(pref_provider);
5196 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
5199 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
5200 // This should all work, even when normal extension installation is disabled.
5201 InitializeEmptyExtensionService();
5202 service()->set_extensions_enabled(false);
5204 // TODO(skerner): The mock provider is not a good model of a provider
5205 // that works with update URLs, because it adds file and version info.
5206 // Extend the mock to work with update URLs. This test checks the
5207 // behavior that is common to all external extension visitors. The
5208 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5209 // what the visitor does results in an extension being downloaded and
5210 // installed.
5211 MockExtensionProvider* pref_provider =
5212 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF_DOWNLOAD);
5213 AddMockExternalProvider(pref_provider);
5214 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
5217 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
5218 // This should all work, even when normal extension installation is disabled.
5219 InitializeEmptyExtensionService();
5220 service()->set_extensions_enabled(false);
5222 // TODO(skerner): The mock provider is not a good model of a provider
5223 // that works with update URLs, because it adds file and version info.
5224 // Extend the mock to work with update URLs. This test checks the
5225 // behavior that is common to all external extension visitors. The
5226 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5227 // what the visitor does results in an extension being downloaded and
5228 // installed.
5229 MockExtensionProvider* pref_provider =
5230 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
5231 AddMockExternalProvider(pref_provider);
5232 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
5235 // Tests that external extensions get uninstalled when the external extension
5236 // providers can't account for them.
5237 TEST_F(ExtensionServiceTest, ExternalUninstall) {
5238 // Start the extensions service with one external extension already installed.
5239 base::FilePath source_install_dir =
5240 data_dir().AppendASCII("good").AppendASCII("Extensions");
5241 base::FilePath pref_path = source_install_dir
5242 .DirName()
5243 .AppendASCII("PreferencesExternal");
5245 // This initializes the extensions service with no ExternalProviders.
5246 InitializeInstalledExtensionService(pref_path, source_install_dir);
5247 service()->set_extensions_enabled(false);
5249 service()->Init();
5251 ASSERT_EQ(0u, GetErrors().size());
5252 ASSERT_EQ(0u, loaded_.size());
5254 // Verify that it's not the disabled extensions flag causing it not to load.
5255 service()->set_extensions_enabled(true);
5256 service()->ReloadExtensionsForTest();
5257 base::RunLoop().RunUntilIdle();
5259 ASSERT_EQ(0u, GetErrors().size());
5260 ASSERT_EQ(0u, loaded_.size());
5263 // Test that running multiple update checks simultaneously does not
5264 // keep the update from succeeding.
5265 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
5266 InitializeEmptyExtensionService();
5268 MockExtensionProvider* provider =
5269 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
5270 AddMockExternalProvider(provider);
5272 // Verify that starting with no providers loads no extensions.
5273 service()->Init();
5274 ASSERT_EQ(0u, loaded_.size());
5276 // Start two checks for updates.
5277 provider->set_visit_count(0);
5278 service()->CheckForExternalUpdates();
5279 service()->CheckForExternalUpdates();
5280 base::RunLoop().RunUntilIdle();
5282 // Two calls should cause two checks for external extensions.
5283 EXPECT_EQ(2, provider->visit_count());
5284 EXPECT_EQ(0u, GetErrors().size());
5285 EXPECT_EQ(0u, loaded_.size());
5287 // Register a test extension externally using the mock registry provider.
5288 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5289 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5291 // Two checks for external updates should find the extension, and install it
5292 // once.
5293 content::WindowedNotificationObserver observer(
5294 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5295 content::NotificationService::AllSources());
5296 provider->set_visit_count(0);
5297 service()->CheckForExternalUpdates();
5298 service()->CheckForExternalUpdates();
5299 observer.Wait();
5300 EXPECT_EQ(2, provider->visit_count());
5301 ASSERT_EQ(0u, GetErrors().size());
5302 ASSERT_EQ(1u, loaded_.size());
5303 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
5304 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
5305 ValidatePrefKeyCount(1);
5306 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5307 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
5309 provider->RemoveExtension(good_crx);
5310 provider->set_visit_count(0);
5311 service()->CheckForExternalUpdates();
5312 service()->CheckForExternalUpdates();
5313 base::RunLoop().RunUntilIdle();
5315 // Two calls should cause two checks for external extensions.
5316 // Because the external source no longer includes good_crx,
5317 // good_crx will be uninstalled. So, expect that no extensions
5318 // are loaded.
5319 EXPECT_EQ(2, provider->visit_count());
5320 EXPECT_EQ(0u, GetErrors().size());
5321 EXPECT_EQ(0u, loaded_.size());
5324 TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
5325 InitializeEmptyExtensionService();
5327 // Test some valid extension records.
5328 // Set a base path to avoid erroring out on relative paths.
5329 // Paths starting with // are absolute on every platform we support.
5330 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5331 ASSERT_TRUE(base_path.IsAbsolute());
5332 MockProviderVisitor visitor(base_path);
5333 std::string json_data =
5335 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5336 " \"external_crx\": \"RandomExtension.crx\","
5337 " \"external_version\": \"1.0\""
5338 " },"
5339 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5340 " \"external_crx\": \"RandomExtension2.crx\","
5341 " \"external_version\": \"2.0\""
5342 " },"
5343 " \"cccccccccccccccccccccccccccccccc\": {"
5344 " \"external_update_url\": \"http:\\\\foo.com/update\","
5345 " \"install_parameter\": \"id\""
5346 " }"
5347 "}";
5348 EXPECT_EQ(3, visitor.Visit(json_data));
5350 // Simulate an external_extensions.json file that contains seven invalid
5351 // records:
5352 // - One that is missing the 'external_crx' key.
5353 // - One that is missing the 'external_version' key.
5354 // - One that is specifying .. in the path.
5355 // - One that specifies both a file and update URL.
5356 // - One that specifies no file or update URL.
5357 // - One that has an update URL that is not well formed.
5358 // - One that contains a malformed version.
5359 // - One that has an invalid id.
5360 // - One that has a non-dictionary value.
5361 // - One that has an integer 'external_version' instead of a string.
5362 // The final extension is valid, and we check that it is read to make sure
5363 // failures don't stop valid records from being read.
5364 json_data =
5366 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5367 " \"external_version\": \"1.0\""
5368 " },"
5369 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5370 " \"external_crx\": \"RandomExtension.crx\""
5371 " },"
5372 " \"cccccccccccccccccccccccccccccccc\": {"
5373 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
5374 " \"external_version\": \"2.0\""
5375 " },"
5376 " \"dddddddddddddddddddddddddddddddd\": {"
5377 " \"external_crx\": \"RandomExtension2.crx\","
5378 " \"external_version\": \"2.0\","
5379 " \"external_update_url\": \"http:\\\\foo.com/update\""
5380 " },"
5381 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
5382 " },"
5383 " \"ffffffffffffffffffffffffffffffff\": {"
5384 " \"external_update_url\": \"This string is not a valid URL\""
5385 " },"
5386 " \"gggggggggggggggggggggggggggggggg\": {"
5387 " \"external_crx\": \"RandomExtension3.crx\","
5388 " \"external_version\": \"This is not a valid version!\""
5389 " },"
5390 " \"This is not a valid id!\": {},"
5391 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
5392 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
5393 " \"external_crx\": \"RandomExtension4.crx\","
5394 " \"external_version\": 1.0"
5395 " },"
5396 " \"pppppppppppppppppppppppppppppppp\": {"
5397 " \"external_crx\": \"RandomValidExtension.crx\","
5398 " \"external_version\": \"1.0\""
5399 " }"
5400 "}";
5401 EXPECT_EQ(1, visitor.Visit(json_data));
5403 // Check that if a base path is not provided, use of a relative
5404 // path fails.
5405 base::FilePath empty;
5406 MockProviderVisitor visitor_no_relative_paths(empty);
5408 // Use absolute paths. Expect success.
5409 json_data =
5411 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5412 " \"external_crx\": \"//RandomExtension1.crx\","
5413 " \"external_version\": \"3.0\""
5414 " },"
5415 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5416 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
5417 " \"external_version\": \"3.0\""
5418 " }"
5419 "}";
5420 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
5422 // Use a relative path. Expect that it will error out.
5423 json_data =
5425 " \"cccccccccccccccccccccccccccccccc\": {"
5426 " \"external_crx\": \"RandomExtension2.crx\","
5427 " \"external_version\": \"3.0\""
5428 " }"
5429 "}";
5430 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
5432 // Test supported_locales.
5433 json_data =
5435 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5436 " \"external_crx\": \"RandomExtension.crx\","
5437 " \"external_version\": \"1.0\","
5438 " \"supported_locales\": [ \"en\" ]"
5439 " },"
5440 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5441 " \"external_crx\": \"RandomExtension2.crx\","
5442 " \"external_version\": \"2.0\","
5443 " \"supported_locales\": [ \"en-GB\" ]"
5444 " },"
5445 " \"cccccccccccccccccccccccccccccccc\": {"
5446 " \"external_crx\": \"RandomExtension2.crx\","
5447 " \"external_version\": \"3.0\","
5448 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
5449 " }"
5450 "}";
5452 ScopedBrowserLocale guard("en-US");
5453 EXPECT_EQ(2, visitor.Visit(json_data));
5456 // Test keep_if_present.
5457 json_data =
5459 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5460 " \"external_crx\": \"RandomExtension.crx\","
5461 " \"external_version\": \"1.0\","
5462 " \"keep_if_present\": true"
5463 " }"
5464 "}";
5466 EXPECT_EQ(0, visitor.Visit(json_data));
5469 // Test is_bookmark_app.
5470 MockProviderVisitor from_bookmark_visitor(
5471 base_path, Extension::FROM_BOOKMARK);
5472 json_data =
5474 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5475 " \"external_crx\": \"RandomExtension.crx\","
5476 " \"external_version\": \"1.0\","
5477 " \"is_bookmark_app\": true"
5478 " }"
5479 "}";
5480 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
5482 // Test is_from_webstore.
5483 MockProviderVisitor from_webstore_visitor(
5484 base_path, Extension::FROM_WEBSTORE);
5485 json_data =
5487 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5488 " \"external_crx\": \"RandomExtension.crx\","
5489 " \"external_version\": \"1.0\","
5490 " \"is_from_webstore\": true"
5491 " }"
5492 "}";
5493 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
5495 // Test was_installed_by_eom.
5496 MockProviderVisitor was_installed_by_eom_visitor(
5497 base_path, Extension::WAS_INSTALLED_BY_OEM);
5498 json_data =
5500 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5501 " \"external_crx\": \"RandomExtension.crx\","
5502 " \"external_version\": \"1.0\","
5503 " \"was_installed_by_oem\": true"
5504 " }"
5505 "}";
5506 EXPECT_EQ(1, was_installed_by_eom_visitor.Visit(json_data));
5508 // Test min_profile_created_by_version.
5509 MockProviderVisitor min_profile_created_by_version_visitor(base_path);
5510 json_data =
5512 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5513 " \"external_crx\": \"RandomExtension.crx\","
5514 " \"external_version\": \"1.0\","
5515 " \"min_profile_created_by_version\": \"42.0.0.1\""
5516 " },"
5517 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5518 " \"external_crx\": \"RandomExtension2.crx\","
5519 " \"external_version\": \"1.0\","
5520 " \"min_profile_created_by_version\": \"43.0.0.1\""
5521 " },"
5522 " \"cccccccccccccccccccccccccccccccc\": {"
5523 " \"external_crx\": \"RandomExtension3.crx\","
5524 " \"external_version\": \"3.0\","
5525 " \"min_profile_created_by_version\": \"44.0.0.1\""
5526 " }"
5527 "}";
5528 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5529 prefs::kProfileCreatedByVersion, "40.0.0.1");
5530 EXPECT_EQ(0, min_profile_created_by_version_visitor.Visit(json_data));
5531 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5532 prefs::kProfileCreatedByVersion, "43.0.0.1");
5533 EXPECT_EQ(2, min_profile_created_by_version_visitor.Visit(json_data));
5534 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5535 prefs::kProfileCreatedByVersion, "45.0.0.1");
5536 EXPECT_EQ(3, min_profile_created_by_version_visitor.Visit(json_data));
5539 TEST_F(ExtensionServiceTest, DoNotInstallForEnterprise) {
5540 InitializeEmptyExtensionService();
5542 const base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5543 ASSERT_TRUE(base_path.IsAbsolute());
5544 MockProviderVisitor visitor(base_path);
5545 policy::ProfilePolicyConnector* const connector =
5546 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(
5547 visitor.profile());
5548 connector->OverrideIsManagedForTesting(true);
5549 EXPECT_TRUE(connector->IsManaged());
5551 std::string json_data =
5553 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5554 " \"external_crx\": \"RandomExtension.crx\","
5555 " \"external_version\": \"1.0\","
5556 " \"do_not_install_for_enterprise\": true"
5557 " },"
5558 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5559 " \"external_crx\": \"RandomExtension2.crx\","
5560 " \"external_version\": \"1.0\""
5561 " }"
5562 "}";
5563 EXPECT_EQ(1, visitor.Visit(json_data));
5566 // Test loading good extensions from the profile directory.
5567 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
5568 // Ensure we're testing in "en" and leave global state untouched.
5569 extension_l10n_util::ScopedLocaleForTest testLocale("en");
5571 // Initialize the test dir with a good Preferences/extensions.
5572 base::FilePath source_install_dir = data_dir().AppendASCII("l10n");
5573 base::FilePath pref_path =
5574 source_install_dir.Append(chrome::kPreferencesFilename);
5575 InitializeInstalledExtensionService(pref_path, source_install_dir);
5577 service()->Init();
5579 ASSERT_EQ(3u, loaded_.size());
5581 // This was equal to "sr" on load.
5582 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
5584 // These are untouched by re-localization.
5585 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
5586 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
5588 // This one starts with Serbian name, and gets re-localized into English.
5589 EXPECT_EQ("My name is simple.", loaded_[0]->name());
5591 // These are untouched by re-localization.
5592 EXPECT_EQ("My name is simple.", loaded_[1]->name());
5593 EXPECT_EQ("no l10n", loaded_[2]->name());
5596 class ExtensionsReadyRecorder : public content::NotificationObserver {
5597 public:
5598 ExtensionsReadyRecorder() : ready_(false) {
5599 registrar_.Add(this,
5600 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
5601 content::NotificationService::AllSources());
5604 void set_ready(bool value) { ready_ = value; }
5605 bool ready() { return ready_; }
5607 private:
5608 void Observe(int type,
5609 const content::NotificationSource& source,
5610 const content::NotificationDetails& details) override {
5611 switch (type) {
5612 case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED:
5613 ready_ = true;
5614 break;
5615 default:
5616 NOTREACHED();
5620 content::NotificationRegistrar registrar_;
5621 bool ready_;
5624 // Test that we get enabled/disabled correctly for all the pref/command-line
5625 // combinations. We don't want to derive from the ExtensionServiceTest class
5626 // for this test, so we use ExtensionServiceTestSimple.
5628 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
5629 // enabled or not.
5630 class ExtensionServiceTestSimple : public testing::Test {
5631 content::TestBrowserThreadBundle thread_bundle_;
5634 TEST_F(ExtensionServiceTestSimple, Enabledness) {
5635 // Make sure the PluginService singleton is destroyed at the end of the test.
5636 base::ShadowingAtExitManager at_exit_manager;
5637 #if defined(ENABLE_PLUGINS)
5638 content::PluginService::GetInstance()->Init();
5639 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
5640 #endif
5642 ExtensionErrorReporter::Init(false); // no noisy errors
5643 ExtensionsReadyRecorder recorder;
5644 scoped_ptr<TestingProfile> profile(new TestingProfile());
5645 #if defined OS_CHROMEOS
5646 chromeos::ScopedTestDeviceSettingsService device_settings_service;
5647 chromeos::ScopedTestCrosSettings cros_settings;
5648 scoped_ptr<chromeos::ScopedTestUserManager> user_manager(
5649 new chromeos::ScopedTestUserManager);
5650 #endif
5651 scoped_ptr<base::CommandLine> command_line;
5652 base::FilePath install_dir = profile->GetPath()
5653 .AppendASCII(extensions::kInstallDirectoryName);
5655 // By default, we are enabled.
5656 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5657 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
5658 ExtensionSystem::Get(profile.get()))->
5659 CreateExtensionService(
5660 command_line.get(),
5661 install_dir,
5662 false);
5663 EXPECT_TRUE(service->extensions_enabled());
5664 service->Init();
5665 base::RunLoop().RunUntilIdle();
5666 EXPECT_TRUE(recorder.ready());
5667 #if defined OS_CHROMEOS
5668 user_manager.reset();
5669 #endif
5671 // If either the command line or pref is set, we are disabled.
5672 recorder.set_ready(false);
5673 profile.reset(new TestingProfile());
5674 command_line->AppendSwitch(switches::kDisableExtensions);
5675 service = static_cast<extensions::TestExtensionSystem*>(
5676 ExtensionSystem::Get(profile.get()))->
5677 CreateExtensionService(
5678 command_line.get(),
5679 install_dir,
5680 false);
5681 EXPECT_FALSE(service->extensions_enabled());
5682 service->Init();
5683 base::RunLoop().RunUntilIdle();
5684 EXPECT_TRUE(recorder.ready());
5686 recorder.set_ready(false);
5687 profile.reset(new TestingProfile());
5688 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5689 service = static_cast<extensions::TestExtensionSystem*>(
5690 ExtensionSystem::Get(profile.get()))->
5691 CreateExtensionService(
5692 command_line.get(),
5693 install_dir,
5694 false);
5695 EXPECT_FALSE(service->extensions_enabled());
5696 service->Init();
5697 base::RunLoop().RunUntilIdle();
5698 EXPECT_TRUE(recorder.ready());
5700 recorder.set_ready(false);
5701 profile.reset(new TestingProfile());
5702 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5703 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5704 service = static_cast<extensions::TestExtensionSystem*>(
5705 ExtensionSystem::Get(profile.get()))->
5706 CreateExtensionService(
5707 command_line.get(),
5708 install_dir,
5709 false);
5710 EXPECT_FALSE(service->extensions_enabled());
5711 service->Init();
5712 base::RunLoop().RunUntilIdle();
5713 EXPECT_TRUE(recorder.ready());
5715 // Explicitly delete all the resources used in this test.
5716 profile.reset();
5717 service = NULL;
5718 // Execute any pending deletion tasks.
5719 base::RunLoop().RunUntilIdle();
5722 // Test loading extensions that require limited and unlimited storage quotas.
5723 TEST_F(ExtensionServiceTest, StorageQuota) {
5724 InitializeEmptyExtensionService();
5726 base::FilePath extensions_path = data_dir().AppendASCII("storage_quota");
5728 base::FilePath limited_quota_ext =
5729 extensions_path.AppendASCII("limited_quota")
5730 .AppendASCII("1.0");
5732 // The old permission name for unlimited quota was "unlimited_storage", but
5733 // we changed it to "unlimitedStorage". This tests both versions.
5734 base::FilePath unlimited_quota_ext =
5735 extensions_path.AppendASCII("unlimited_quota")
5736 .AppendASCII("1.0");
5737 base::FilePath unlimited_quota_ext2 =
5738 extensions_path.AppendASCII("unlimited_quota")
5739 .AppendASCII("2.0");
5740 extensions::UnpackedInstaller::Create(service())->Load(limited_quota_ext);
5741 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext);
5742 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext2);
5743 base::RunLoop().RunUntilIdle();
5745 ASSERT_EQ(3u, loaded_.size());
5746 EXPECT_TRUE(profile());
5747 EXPECT_FALSE(profile()->IsOffTheRecord());
5748 EXPECT_FALSE(
5749 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5750 loaded_[0]->url()));
5751 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5752 loaded_[1]->url()));
5753 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5754 loaded_[2]->url()));
5757 // Tests ComponentLoader::Add().
5758 TEST_F(ExtensionServiceTest, ComponentExtensions) {
5759 InitializeEmptyExtensionService();
5761 // Component extensions should work even when extensions are disabled.
5762 service()->set_extensions_enabled(false);
5764 base::FilePath path = data_dir()
5765 .AppendASCII("good")
5766 .AppendASCII("Extensions")
5767 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
5768 .AppendASCII("1.0.0.0");
5770 std::string manifest;
5771 ASSERT_TRUE(base::ReadFileToString(
5772 path.Append(extensions::kManifestFilename), &manifest));
5774 service()->component_loader()->Add(manifest, path);
5775 service()->Init();
5777 // Note that we do not pump messages -- the extension should be loaded
5778 // immediately.
5780 EXPECT_EQ(0u, GetErrors().size());
5781 ASSERT_EQ(1u, loaded_.size());
5782 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
5783 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5785 // Component extensions get a prefs entry on first install.
5786 ValidatePrefKeyCount(1);
5788 // Reload all extensions, and make sure it comes back.
5789 std::string extension_id = (*registry()->enabled_extensions().begin())->id();
5790 loaded_.clear();
5791 service()->ReloadExtensionsForTest();
5792 ASSERT_EQ(1u, registry()->enabled_extensions().size());
5793 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id());
5796 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
5797 InitializeEmptyExtensionService();
5798 InitializeExtensionSyncService();
5800 bool flare_was_called = false;
5801 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5802 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5803 extension_sync_service()->SetSyncStartFlare(
5804 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5805 factory.GetWeakPtr(),
5806 &flare_was_called, // Safe due to WeakPtrFactory scope.
5807 &triggered_type)); // Safe due to WeakPtrFactory scope.
5809 // Install a component extension.
5810 std::string manifest;
5811 ASSERT_TRUE(base::ReadFileToString(
5812 good0_path().Append(extensions::kManifestFilename), &manifest));
5813 service()->component_loader()->Add(manifest, good0_path());
5814 ASSERT_FALSE(service()->is_ready());
5815 service()->Init();
5816 ASSERT_TRUE(service()->is_ready());
5818 // Extensions added before service is_ready() don't trigger sync startup.
5819 EXPECT_FALSE(flare_was_called);
5820 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5823 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
5824 InitializeGoodInstalledExtensionService();
5825 InitializeExtensionSyncService();
5827 bool flare_was_called = false;
5828 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5829 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5830 extension_sync_service()->SetSyncStartFlare(
5831 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5832 factory.GetWeakPtr(),
5833 &flare_was_called, // Safe due to WeakPtrFactory scope.
5834 &triggered_type)); // Safe due to WeakPtrFactory scope.
5836 ASSERT_FALSE(service()->is_ready());
5837 service()->Init();
5838 ASSERT_EQ(3u, loaded_.size());
5839 ASSERT_TRUE(service()->is_ready());
5841 // Extensions added before service is_ready() don't trigger sync startup.
5842 EXPECT_FALSE(flare_was_called);
5843 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5846 TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
5847 InitializeEmptyExtensionService();
5848 InitializeExtensionSyncService();
5849 service()->Init();
5850 ASSERT_TRUE(service()->is_ready());
5852 bool flare_was_called = false;
5853 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5854 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5855 extension_sync_service()->SetSyncStartFlare(
5856 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5857 factory.GetWeakPtr(),
5858 &flare_was_called, // Safe due to WeakPtrFactory scope.
5859 &triggered_type)); // Safe due to WeakPtrFactory scope.
5861 base::FilePath path = data_dir().AppendASCII("good.crx");
5862 InstallCRX(path, INSTALL_NEW);
5864 EXPECT_TRUE(flare_was_called);
5865 EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
5867 // Reset.
5868 flare_was_called = false;
5869 triggered_type = syncer::UNSPECIFIED;
5871 // Once sync starts, flare should no longer be invoked.
5872 extension_sync_service()->MergeDataAndStartSyncing(
5873 syncer::EXTENSIONS,
5874 syncer::SyncDataList(),
5875 scoped_ptr<syncer::SyncChangeProcessor>(
5876 new syncer::FakeSyncChangeProcessor),
5877 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5878 path = data_dir().AppendASCII("page_action.crx");
5879 InstallCRX(path, INSTALL_NEW);
5880 EXPECT_FALSE(flare_was_called);
5881 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5884 TEST_F(ExtensionServiceTest, DisableExtensionFromSync) {
5885 // Start the extensions service with one external extension already installed.
5886 base::FilePath source_install_dir =
5887 data_dir().AppendASCII("good").AppendASCII("Extensions");
5888 base::FilePath pref_path =
5889 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5891 InitializeInstalledExtensionService(pref_path, source_install_dir);
5892 InitializeExtensionSyncService();
5894 // The user has enabled sync.
5895 ProfileSyncService* sync_service =
5896 ProfileSyncServiceFactory::GetForProfile(profile());
5897 sync_service->SetSyncSetupCompleted();
5899 service()->Init();
5900 ASSERT_TRUE(service()->is_ready());
5902 ASSERT_EQ(3u, loaded_.size());
5904 // We start enabled.
5905 const Extension* extension = service()->GetExtensionById(good0, true);
5906 ASSERT_TRUE(extension);
5907 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5909 // Then sync data arrives telling us to disable |good0|.
5910 ExtensionSyncData disable_good_crx(*extension, false,
5911 Extension::DISABLE_USER_ACTION, false,
5912 false, ExtensionSyncData::BOOLEAN_UNSET);
5913 syncer::SyncDataList sync_data;
5914 sync_data.push_back(disable_good_crx.GetSyncData());
5915 extension_sync_service()->MergeDataAndStartSyncing(
5916 syncer::EXTENSIONS,
5917 sync_data,
5918 scoped_ptr<syncer::SyncChangeProcessor>(
5919 new syncer::FakeSyncChangeProcessor),
5920 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5921 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5924 TEST_F(ExtensionServiceTest, DontDisableExtensionWithPendingEnableFromSync) {
5925 // Start the extensions service with one external extension already installed.
5926 base::FilePath source_install_dir =
5927 data_dir().AppendASCII("good").AppendASCII("Extensions");
5928 base::FilePath pref_path =
5929 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5931 InitializeInstalledExtensionService(pref_path, source_install_dir);
5932 InitializeExtensionSyncService();
5934 // The user has enabled sync.
5935 ProfileSyncService* sync_service =
5936 ProfileSyncServiceFactory::GetForProfile(profile());
5937 sync_service->SetSyncSetupCompleted();
5939 service()->Init();
5940 ASSERT_TRUE(service()->is_ready());
5941 ASSERT_EQ(3u, loaded_.size());
5943 const Extension* extension = service()->GetExtensionById(good0, true);
5944 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5946 // Disable extension before first sync data arrives.
5947 service()->DisableExtension(good0, Extension::DISABLE_USER_ACTION);
5948 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5950 // Enable extension - this is now the most recent state.
5951 service()->EnableExtension(good0);
5952 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5954 // Now sync data comes in that says to disable good0. This should be
5955 // ignored.
5956 ExtensionSyncData disable_good_crx(*extension, false,
5957 Extension::DISABLE_USER_ACTION, false,
5958 false, ExtensionSyncData::BOOLEAN_UNSET);
5959 syncer::SyncDataList sync_data;
5960 sync_data.push_back(disable_good_crx.GetSyncData());
5961 extension_sync_service()->MergeDataAndStartSyncing(
5962 syncer::EXTENSIONS,
5963 sync_data,
5964 scoped_ptr<syncer::SyncChangeProcessor>(
5965 new syncer::FakeSyncChangeProcessor),
5966 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5968 // The extension was enabled locally before the sync data arrived, so it
5969 // should still be enabled now.
5970 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5973 TEST_F(ExtensionServiceTest, GetSyncData) {
5974 InitializeEmptyExtensionService();
5975 InitializeExtensionSyncService();
5976 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5977 const Extension* extension = service()->GetInstalledExtension(good_crx);
5978 ASSERT_TRUE(extension);
5980 extension_sync_service()->MergeDataAndStartSyncing(
5981 syncer::EXTENSIONS,
5982 syncer::SyncDataList(),
5983 scoped_ptr<syncer::SyncChangeProcessor>(
5984 new syncer::FakeSyncChangeProcessor),
5985 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5987 syncer::SyncDataList list =
5988 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5989 ASSERT_EQ(list.size(), 1U);
5990 scoped_ptr<ExtensionSyncData> data =
5991 ExtensionSyncData::CreateFromSyncData(list[0]);
5992 ASSERT_TRUE(data.get());
5993 EXPECT_EQ(extension->id(), data->id());
5994 EXPECT_FALSE(data->uninstalled());
5995 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
5996 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
5997 data->incognito_enabled());
5998 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
5999 EXPECT_TRUE(data->version().Equals(*extension->version()));
6000 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
6001 data->update_url());
6002 EXPECT_EQ(extension->name(), data->name());
6005 TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
6006 InitializeEmptyExtensionService();
6007 InitializeExtensionSyncService();
6008 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6009 TerminateExtension(good_crx);
6010 const Extension* extension = service()->GetInstalledExtension(good_crx);
6011 ASSERT_TRUE(extension);
6013 syncer::FakeSyncChangeProcessor processor;
6014 extension_sync_service()->MergeDataAndStartSyncing(
6015 syncer::EXTENSIONS,
6016 syncer::SyncDataList(),
6017 scoped_ptr<syncer::SyncChangeProcessor>(
6018 new syncer::FakeSyncChangeProcessor),
6019 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6021 syncer::SyncDataList list =
6022 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6023 ASSERT_EQ(list.size(), 1U);
6024 scoped_ptr<ExtensionSyncData> data =
6025 ExtensionSyncData::CreateFromSyncData(list[0]);
6026 ASSERT_TRUE(data.get());
6027 EXPECT_EQ(extension->id(), data->id());
6028 EXPECT_FALSE(data->uninstalled());
6029 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
6030 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
6031 data->incognito_enabled());
6032 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6033 EXPECT_TRUE(data->version().Equals(*extension->version()));
6034 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
6035 data->update_url());
6036 EXPECT_EQ(extension->name(), data->name());
6039 TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
6040 InitializeEmptyExtensionService();
6041 InitializeExtensionSyncService();
6042 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6043 const Extension* extension = service()->GetInstalledExtension(good_crx);
6044 ASSERT_TRUE(extension);
6046 syncer::FakeSyncChangeProcessor processor;
6047 extension_sync_service()->MergeDataAndStartSyncing(
6048 syncer::APPS,
6049 syncer::SyncDataList(),
6050 scoped_ptr<syncer::SyncChangeProcessor>(
6051 new syncer::FakeSyncChangeProcessor),
6052 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6054 syncer::SyncDataList list =
6055 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6056 ASSERT_EQ(list.size(), 0U);
6059 TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
6060 InitializeEmptyExtensionService();
6061 InitializeExtensionSyncService();
6062 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6063 const Extension* extension = service()->GetInstalledExtension(good_crx);
6064 ASSERT_TRUE(extension);
6066 syncer::FakeSyncChangeProcessor processor;
6067 extension_sync_service()->MergeDataAndStartSyncing(
6068 syncer::EXTENSIONS,
6069 syncer::SyncDataList(),
6070 scoped_ptr<syncer::SyncChangeProcessor>(
6071 new syncer::FakeSyncChangeProcessor),
6072 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6075 syncer::SyncDataList list =
6076 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6077 ASSERT_EQ(list.size(), 1U);
6078 scoped_ptr<ExtensionSyncData> data =
6079 ExtensionSyncData::CreateFromSyncData(list[0]);
6080 ASSERT_TRUE(data.get());
6081 EXPECT_TRUE(data->enabled());
6082 EXPECT_FALSE(data->incognito_enabled());
6083 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6086 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
6088 syncer::SyncDataList list =
6089 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6090 ASSERT_EQ(list.size(), 1U);
6091 scoped_ptr<ExtensionSyncData> data =
6092 ExtensionSyncData::CreateFromSyncData(list[0]);
6093 ASSERT_TRUE(data.get());
6094 EXPECT_FALSE(data->enabled());
6095 EXPECT_FALSE(data->incognito_enabled());
6096 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6099 extensions::util::SetIsIncognitoEnabled(good_crx, profile(), true);
6100 extensions::util::SetAllowedScriptingOnAllUrls(
6101 good_crx, profile(), false);
6103 syncer::SyncDataList list =
6104 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6105 ASSERT_EQ(list.size(), 1U);
6106 scoped_ptr<ExtensionSyncData> data =
6107 ExtensionSyncData::CreateFromSyncData(list[0]);
6108 ASSERT_TRUE(data.get());
6109 EXPECT_FALSE(data->enabled());
6110 EXPECT_TRUE(data->incognito_enabled());
6111 EXPECT_EQ(ExtensionSyncData::BOOLEAN_FALSE, data->all_urls_enabled());
6114 service()->EnableExtension(good_crx);
6115 extensions::util::SetAllowedScriptingOnAllUrls(
6116 good_crx, profile(), true);
6118 syncer::SyncDataList list =
6119 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6120 ASSERT_EQ(list.size(), 1U);
6121 scoped_ptr<ExtensionSyncData> data =
6122 ExtensionSyncData::CreateFromSyncData(list[0]);
6123 ASSERT_TRUE(data.get());
6124 EXPECT_TRUE(data->enabled());
6125 EXPECT_TRUE(data->incognito_enabled());
6126 EXPECT_EQ(ExtensionSyncData::BOOLEAN_TRUE, data->all_urls_enabled());
6130 TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
6131 InitializeEmptyExtensionService();
6132 InitializeExtensionSyncService();
6133 InstallCRXWithLocation(
6134 data_dir().AppendASCII("good.crx"), Manifest::EXTERNAL_PREF, INSTALL_NEW);
6135 const Extension* extension = service()->GetInstalledExtension(good_crx);
6136 ASSERT_TRUE(extension);
6138 syncer::FakeSyncChangeProcessor processor;
6139 extension_sync_service()->MergeDataAndStartSyncing(
6140 syncer::EXTENSIONS,
6141 syncer::SyncDataList(),
6142 scoped_ptr<syncer::SyncChangeProcessor>(
6143 new syncer::FakeSyncChangeProcessor),
6144 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6146 UninstallExtension(good_crx, false);
6147 EXPECT_TRUE(
6148 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
6150 sync_pb::EntitySpecifics specifics;
6151 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6152 sync_pb::ExtensionSpecifics* extension_specifics =
6153 app_specifics->mutable_extension();
6154 extension_specifics->set_id(good_crx);
6155 extension_specifics->set_version("1.0");
6156 extension_specifics->set_enabled(true);
6158 syncer::SyncData sync_data =
6159 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6160 syncer::SyncChange sync_change(FROM_HERE,
6161 syncer::SyncChange::ACTION_UPDATE,
6162 sync_data);
6163 syncer::SyncChangeList list(1);
6164 list[0] = sync_change;
6166 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6167 EXPECT_TRUE(
6168 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
6171 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
6172 InitializeEmptyExtensionService();
6173 InitializeExtensionSyncService();
6174 const Extension* app =
6175 PackAndInstallCRX(data_dir().AppendASCII("app"), INSTALL_NEW);
6176 ASSERT_TRUE(app);
6177 ASSERT_TRUE(app->is_app());
6179 syncer::FakeSyncChangeProcessor processor;
6180 extension_sync_service()->MergeDataAndStartSyncing(
6181 syncer::APPS,
6182 syncer::SyncDataList(),
6183 scoped_ptr<syncer::SyncChangeProcessor>(
6184 new syncer::FakeSyncChangeProcessor),
6185 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6187 syncer::StringOrdinal initial_ordinal =
6188 syncer::StringOrdinal::CreateInitialOrdinal();
6190 syncer::SyncDataList list =
6191 extension_sync_service()->GetAllSyncData(syncer::APPS);
6192 ASSERT_EQ(list.size(), 1U);
6194 scoped_ptr<ExtensionSyncData> app_sync_data =
6195 ExtensionSyncData::CreateFromSyncData(list[0]);
6196 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->app_launch_ordinal()));
6197 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6200 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
6201 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
6203 syncer::SyncDataList list =
6204 extension_sync_service()->GetAllSyncData(syncer::APPS);
6205 ASSERT_EQ(list.size(), 1U);
6207 scoped_ptr<ExtensionSyncData> app_sync_data =
6208 ExtensionSyncData::CreateFromSyncData(list[0]);
6209 ASSERT_TRUE(app_sync_data.get());
6210 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6211 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6214 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
6216 syncer::SyncDataList list =
6217 extension_sync_service()->GetAllSyncData(syncer::APPS);
6218 ASSERT_EQ(list.size(), 1U);
6220 scoped_ptr<ExtensionSyncData> app_sync_data =
6221 ExtensionSyncData::CreateFromSyncData(list[0]);
6222 ASSERT_TRUE(app_sync_data.get());
6223 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6224 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->page_ordinal()));
6228 // TODO (rdevlin.cronin): The OnExtensionMoved() method has been removed from
6229 // ExtensionService, so this test probably needs a new home. Unfortunately, it
6230 // relies pretty heavily on things like InitializeExtension[Sync]Service() and
6231 // PackAndInstallCRX(). When we clean up a bit more, this should move out.
6232 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
6233 InitializeEmptyExtensionService();
6234 InitializeExtensionSyncService();
6235 const size_t kAppCount = 3;
6236 const Extension* apps[kAppCount];
6237 apps[0] = PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
6238 apps[1] = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
6239 apps[2] = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
6240 for (size_t i = 0; i < kAppCount; ++i) {
6241 ASSERT_TRUE(apps[i]);
6242 ASSERT_TRUE(apps[i]->is_app());
6245 syncer::FakeSyncChangeProcessor processor;
6246 extension_sync_service()->MergeDataAndStartSyncing(
6247 syncer::APPS,
6248 syncer::SyncDataList(),
6249 scoped_ptr<syncer::SyncChangeProcessor>(
6250 new syncer::FakeSyncChangeProcessor),
6251 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6253 ExtensionPrefs::Get(service()->GetBrowserContext())
6254 ->app_sorting()
6255 ->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
6257 syncer::SyncDataList list =
6258 extension_sync_service()->GetAllSyncData(syncer::APPS);
6259 ASSERT_EQ(list.size(), 3U);
6261 scoped_ptr<ExtensionSyncData> data[kAppCount];
6262 for (size_t i = 0; i < kAppCount; ++i) {
6263 data[i] = ExtensionSyncData::CreateFromSyncData(list[i]);
6264 ASSERT_TRUE(data[i].get());
6267 // The sync data is not always in the same order our apps were installed in,
6268 // so we do that sorting here so we can make sure the values are changed as
6269 // expected.
6270 syncer::StringOrdinal app_launch_ordinals[kAppCount];
6271 for (size_t i = 0; i < kAppCount; ++i) {
6272 for (size_t j = 0; j < kAppCount; ++j) {
6273 if (apps[i]->id() == data[j]->id())
6274 app_launch_ordinals[i] = data[j]->app_launch_ordinal();
6278 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
6279 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
6283 TEST_F(ExtensionServiceTest, GetSyncDataList) {
6284 InitializeEmptyExtensionService();
6285 InitializeExtensionSyncService();
6286 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6287 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
6288 InstallCRX(data_dir().AppendASCII("theme.crx"), INSTALL_NEW);
6289 InstallCRX(data_dir().AppendASCII("theme2.crx"), INSTALL_NEW);
6291 syncer::FakeSyncChangeProcessor processor;
6292 extension_sync_service()->MergeDataAndStartSyncing(
6293 syncer::APPS,
6294 syncer::SyncDataList(),
6295 scoped_ptr<syncer::SyncChangeProcessor>(
6296 new syncer::FakeSyncChangeProcessor),
6297 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6298 extension_sync_service()->MergeDataAndStartSyncing(
6299 syncer::EXTENSIONS,
6300 syncer::SyncDataList(),
6301 scoped_ptr<syncer::SyncChangeProcessor>(
6302 new syncer::FakeSyncChangeProcessor),
6303 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6305 service()->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
6306 TerminateExtension(theme2_crx);
6308 EXPECT_EQ(0u, extension_sync_service()->GetAllSyncData(syncer::APPS).size());
6309 EXPECT_EQ(
6310 2u, extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS).size());
6313 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
6314 InitializeEmptyExtensionService();
6315 InitializeExtensionSyncService();
6316 syncer::FakeSyncChangeProcessor processor;
6317 extension_sync_service()->MergeDataAndStartSyncing(
6318 syncer::EXTENSIONS,
6319 syncer::SyncDataList(),
6320 scoped_ptr<syncer::SyncChangeProcessor>(
6321 new syncer::FakeSyncChangeProcessor),
6322 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6324 sync_pb::EntitySpecifics specifics;
6325 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6326 ext_specifics->set_id(good_crx);
6327 ext_specifics->set_version("1.0");
6328 syncer::SyncData sync_data =
6329 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6330 syncer::SyncChange sync_change(FROM_HERE,
6331 syncer::SyncChange::ACTION_DELETE,
6332 sync_data);
6333 syncer::SyncChangeList list(1);
6334 list[0] = sync_change;
6336 // Should do nothing.
6337 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6338 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6340 // Install the extension.
6341 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6342 InstallCRX(extension_path, INSTALL_NEW);
6343 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6345 // Should uninstall the extension.
6346 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6347 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6349 // Should again do nothing.
6350 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6351 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6354 TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
6355 InitializeEmptyExtensionService();
6356 InitializeExtensionSyncService();
6358 // Install the extension.
6359 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6360 InstallCRX(extension_path, INSTALL_NEW);
6361 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6363 sync_pb::EntitySpecifics specifics;
6364 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6365 sync_pb::ExtensionSpecifics* extension_specifics =
6366 app_specifics->mutable_extension();
6367 extension_specifics->set_id(good_crx);
6368 extension_specifics->set_version(
6369 service()->GetInstalledExtension(good_crx)->version()->GetString());
6372 extension_specifics->set_enabled(true);
6373 syncer::SyncData sync_data =
6374 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6375 syncer::SyncChange sync_change(FROM_HERE,
6376 syncer::SyncChange::ACTION_DELETE,
6377 sync_data);
6378 syncer::SyncChangeList list(1);
6379 list[0] = sync_change;
6381 // Should do nothing
6382 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6383 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6387 extension_specifics->set_enabled(false);
6388 syncer::SyncData sync_data =
6389 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6390 syncer::SyncChange sync_change(FROM_HERE,
6391 syncer::SyncChange::ACTION_UPDATE,
6392 sync_data);
6393 syncer::SyncChangeList list(1);
6394 list[0] = sync_change;
6396 // Should again do nothing.
6397 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6398 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
6402 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
6403 InitializeEmptyExtensionService();
6404 InitializeExtensionSyncService();
6405 syncer::FakeSyncChangeProcessor processor;
6406 extension_sync_service()->MergeDataAndStartSyncing(
6407 syncer::EXTENSIONS,
6408 syncer::SyncDataList(),
6409 scoped_ptr<syncer::SyncChangeProcessor>(
6410 new syncer::FakeSyncChangeProcessor),
6411 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6413 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6414 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6415 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6416 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6417 good_crx, profile()));
6418 const bool kDefaultAllowedScripting =
6419 extensions::util::DefaultAllowedScriptingOnAllUrls();
6420 EXPECT_EQ(kDefaultAllowedScripting,
6421 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6423 sync_pb::EntitySpecifics specifics;
6424 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6425 ext_specifics->set_id(good_crx);
6426 ext_specifics->set_version(
6427 service()->GetInstalledExtension(good_crx)->version()->GetString());
6428 ext_specifics->set_enabled(false);
6431 syncer::SyncData sync_data =
6432 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6433 syncer::SyncChange sync_change(FROM_HERE,
6434 syncer::SyncChange::ACTION_UPDATE,
6435 sync_data);
6436 syncer::SyncChangeList list(1);
6437 list[0] = sync_change;
6438 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6439 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6440 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6441 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6442 good_crx, profile()));
6443 EXPECT_EQ(kDefaultAllowedScripting,
6444 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6448 ext_specifics->set_enabled(true);
6449 ext_specifics->set_incognito_enabled(true);
6450 syncer::SyncData sync_data =
6451 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6452 syncer::SyncChange sync_change(FROM_HERE,
6453 syncer::SyncChange::ACTION_UPDATE,
6454 sync_data);
6455 syncer::SyncChangeList list(1);
6456 list[0] = sync_change;
6457 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6458 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6459 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6463 ext_specifics->set_enabled(false);
6464 ext_specifics->set_incognito_enabled(true);
6465 syncer::SyncData sync_data =
6466 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6467 syncer::SyncChange sync_change(FROM_HERE,
6468 syncer::SyncChange::ACTION_UPDATE,
6469 sync_data);
6470 syncer::SyncChangeList list(1);
6471 list[0] = sync_change;
6472 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6473 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6474 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6478 ext_specifics->set_enabled(true);
6479 ext_specifics->set_all_urls_enabled(!kDefaultAllowedScripting);
6480 syncer::SyncData sync_data =
6481 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6482 syncer::SyncChange sync_change(FROM_HERE,
6483 syncer::SyncChange::ACTION_UPDATE,
6484 sync_data);
6485 syncer::SyncChangeList list(1);
6486 list[0] = sync_change;
6487 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6488 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6489 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6490 good_crx, profile()));
6491 EXPECT_EQ(!kDefaultAllowedScripting,
6492 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6496 ext_specifics->set_all_urls_enabled(kDefaultAllowedScripting);
6497 syncer::SyncData sync_data =
6498 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6499 syncer::SyncChange sync_change(FROM_HERE,
6500 syncer::SyncChange::ACTION_UPDATE,
6501 sync_data);
6502 syncer::SyncChangeList list(1);
6503 list[0] = sync_change;
6504 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6505 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6506 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6507 good_crx, profile()));
6508 EXPECT_EQ(kDefaultAllowedScripting,
6509 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6512 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6515 TEST_F(ExtensionServiceTest, ProcessSyncDataNewExtension) {
6516 InitializeEmptyExtensionService();
6517 InitializeExtensionSyncService();
6518 syncer::FakeSyncChangeProcessor processor;
6519 extension_sync_service()->MergeDataAndStartSyncing(
6520 syncer::EXTENSIONS,
6521 syncer::SyncDataList(),
6522 scoped_ptr<syncer::SyncChangeProcessor>(
6523 new syncer::FakeSyncChangeProcessor),
6524 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6526 const base::FilePath path = data_dir().AppendASCII("good.crx");
6527 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6529 struct TestCase {
6530 const char* name; // For failure output only.
6531 bool sync_enabled; // The "enabled" flag coming in from Sync.
6532 // The disable reason(s) coming in from Sync, or -1 for "not set".
6533 int sync_disable_reasons;
6534 // The disable reason(s) that should be set on the installed extension.
6535 // This will usually be the same as |sync_disable_reasons|, but see the
6536 // "Legacy" case.
6537 int expect_disable_reasons;
6538 // Whether the extension's permissions should be auto-granted during
6539 // installation.
6540 bool expect_permissions_granted;
6541 } test_cases[] = {
6542 // Standard case: Extension comes in enabled; permissions should be granted
6543 // during installation.
6544 { "Standard", true, 0, 0, true },
6545 // If the extension comes in disabled, its permissions should still be
6546 // granted (the user already approved them on another machine).
6547 { "Disabled", false, Extension::DISABLE_USER_ACTION,
6548 Extension::DISABLE_USER_ACTION, true },
6549 // Legacy case (<M45): No disable reasons come in from Sync (see
6550 // crbug.com/484214). After installation, the reason should be set to
6551 // DISABLE_UNKNOWN_FROM_SYNC.
6552 { "Legacy", false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC, true },
6553 // If the extension came in disabled due to a permissions increase, then the
6554 // user has *not* approved the permissions, and they shouldn't be granted.
6555 // crbug.com/484214
6556 { "PermissionsIncrease", false, Extension::DISABLE_PERMISSIONS_INCREASE,
6557 Extension::DISABLE_PERMISSIONS_INCREASE, false },
6560 for (const TestCase& test_case : test_cases) {
6561 SCOPED_TRACE(test_case.name);
6563 sync_pb::EntitySpecifics specifics;
6564 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6565 ext_specifics->set_id(good_crx);
6566 ext_specifics->set_version(base::Version("1").GetString());
6567 ext_specifics->set_enabled(test_case.sync_enabled);
6568 if (test_case.sync_disable_reasons != -1)
6569 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6571 syncer::SyncData sync_data =
6572 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6573 syncer::SyncChange sync_change(FROM_HERE,
6574 syncer::SyncChange::ACTION_UPDATE,
6575 sync_data);
6576 syncer::SyncChangeList list(1, sync_change);
6577 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6579 ASSERT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
6580 UpdateExtension(good_crx, path, test_case.sync_enabled ? ENABLED
6581 : DISABLED);
6582 EXPECT_EQ(test_case.expect_disable_reasons,
6583 prefs->GetDisableReasons(good_crx));
6584 scoped_refptr<PermissionSet> permissions(
6585 prefs->GetGrantedPermissions(good_crx));
6586 EXPECT_EQ(test_case.expect_permissions_granted, !permissions->IsEmpty());
6587 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6589 // Remove the extension again, so we can install it again for the next case.
6590 UninstallExtension(good_crx, false,
6591 test_case.sync_enabled ? Extension::ENABLED
6592 : Extension::DISABLED);
6596 TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
6597 InitializeExtensionServiceWithUpdater();
6598 InitializeExtensionSyncService();
6599 syncer::FakeSyncChangeProcessor processor;
6600 extension_sync_service()->MergeDataAndStartSyncing(
6601 syncer::EXTENSIONS,
6602 syncer::SyncDataList(),
6603 scoped_ptr<syncer::SyncChangeProcessor>(
6604 new syncer::FakeSyncChangeProcessor),
6605 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6607 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6608 TerminateExtension(good_crx);
6609 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6610 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6612 sync_pb::EntitySpecifics specifics;
6613 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6614 ext_specifics->set_id(good_crx);
6615 ext_specifics->set_version(
6616 service()->GetInstalledExtension(good_crx)->version()->GetString());
6617 ext_specifics->set_enabled(false);
6618 ext_specifics->set_incognito_enabled(true);
6619 syncer::SyncData sync_data =
6620 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6621 syncer::SyncChange sync_change(FROM_HERE,
6622 syncer::SyncChange::ACTION_UPDATE,
6623 sync_data);
6624 syncer::SyncChangeList list(1);
6625 list[0] = sync_change;
6627 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6628 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6629 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6631 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6634 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
6635 InitializeExtensionServiceWithUpdater();
6636 InitializeExtensionSyncService();
6637 syncer::FakeSyncChangeProcessor processor;
6638 extension_sync_service()->MergeDataAndStartSyncing(
6639 syncer::EXTENSIONS,
6640 syncer::SyncDataList(),
6641 scoped_ptr<syncer::SyncChangeProcessor>(
6642 new syncer::FakeSyncChangeProcessor),
6643 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6645 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6646 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6647 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6649 sync_pb::EntitySpecifics specifics;
6650 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6651 ext_specifics->set_id(good_crx);
6652 ext_specifics->set_enabled(true);
6655 ext_specifics->set_version(
6656 service()->GetInstalledExtension(good_crx)->version()->GetString());
6657 syncer::SyncData sync_data =
6658 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6659 syncer::SyncChange sync_change(FROM_HERE,
6660 syncer::SyncChange::ACTION_UPDATE,
6661 sync_data);
6662 syncer::SyncChangeList list(1);
6663 list[0] = sync_change;
6665 // Should do nothing if extension version == sync version.
6666 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6667 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6670 // Should do nothing if extension version > sync version (but see
6671 // the TODO in ProcessExtensionSyncData).
6673 ext_specifics->set_version("0.0.0.0");
6674 syncer::SyncData sync_data =
6675 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6676 syncer::SyncChange sync_change(FROM_HERE,
6677 syncer::SyncChange::ACTION_UPDATE,
6678 sync_data);
6679 syncer::SyncChangeList list(1);
6680 list[0] = sync_change;
6682 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6683 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6686 // Should kick off an update if extension version < sync version.
6688 ext_specifics->set_version("9.9.9.9");
6689 syncer::SyncData sync_data =
6690 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6691 syncer::SyncChange sync_change(FROM_HERE,
6692 syncer::SyncChange::ACTION_UPDATE,
6693 sync_data);
6694 syncer::SyncChangeList list(1);
6695 list[0] = sync_change;
6697 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6698 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6701 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6704 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
6705 InitializeExtensionServiceWithUpdater();
6706 InitializeExtensionSyncService();
6707 syncer::FakeSyncChangeProcessor processor;
6708 extension_sync_service()->MergeDataAndStartSyncing(
6709 syncer::EXTENSIONS,
6710 syncer::SyncDataList(),
6711 scoped_ptr<syncer::SyncChangeProcessor>(
6712 new syncer::FakeSyncChangeProcessor),
6713 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6715 sync_pb::EntitySpecifics specifics;
6716 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6717 ext_specifics->set_id(good_crx);
6718 ext_specifics->set_enabled(false);
6719 ext_specifics->set_incognito_enabled(true);
6720 ext_specifics->set_update_url("http://www.google.com/");
6721 ext_specifics->set_version("1.2.3.4");
6722 syncer::SyncData sync_data =
6723 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6724 syncer::SyncChange sync_change(FROM_HERE,
6725 syncer::SyncChange::ACTION_UPDATE,
6726 sync_data);
6727 syncer::SyncChangeList list(1);
6728 list[0] = sync_change;
6730 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6731 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6732 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6733 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6734 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6735 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6737 const extensions::PendingExtensionInfo* info;
6738 EXPECT_TRUE(
6739 (info = service()->pending_extension_manager()->GetById(good_crx)));
6740 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
6741 EXPECT_TRUE(info->is_from_sync());
6742 EXPECT_EQ(Manifest::INTERNAL, info->install_source());
6743 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
6746 TEST_F(ExtensionServiceTest, ProcessSyncDataEnableDisable) {
6747 InitializeEmptyExtensionService();
6748 InitializeExtensionSyncService();
6749 extension_sync_service()->MergeDataAndStartSyncing(
6750 syncer::EXTENSIONS,
6751 syncer::SyncDataList(),
6752 scoped_ptr<syncer::SyncChangeProcessor>(
6753 new syncer::FakeSyncChangeProcessor),
6754 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6756 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6758 struct TestCase {
6759 const char* name; // For failure output only.
6760 // Set of disable reasons before any Sync data comes in. If this is != 0,
6761 // the extension is disabled.
6762 int previous_disable_reasons;
6763 bool sync_enable; // The enabled flag coming in from Sync.
6764 // The disable reason(s) coming in from Sync, or -1 for "not set".
6765 int sync_disable_reasons;
6766 // The expected set of disable reasons after processing the Sync update. The
6767 // extension should be disabled iff this is != 0.
6768 int expect_disable_reasons;
6769 } test_cases[] = {
6770 { "NopEnable", 0, true, 0, 0 },
6771 { "NopDisable", Extension::DISABLE_USER_ACTION, false,
6772 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6773 { "Disable", 0, false, Extension::DISABLE_USER_ACTION,
6774 Extension::DISABLE_USER_ACTION },
6775 { "DisableLegacy", 0, false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC },
6776 { "AddDisableReason", Extension::DISABLE_REMOTE_INSTALL, false,
6777 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION,
6778 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION },
6779 { "AddDisableReasonLegacy", Extension::DISABLE_USER_ACTION, false, -1,
6780 Extension::DISABLE_USER_ACTION | Extension::DISABLE_UNKNOWN_FROM_SYNC},
6781 { "RemoveDisableReason",
6782 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION, false,
6783 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6784 { "Enable", Extension::DISABLE_USER_ACTION, true, 0, 0 },
6785 { "EnableLegacy", Extension::DISABLE_USER_ACTION, true, -1, 0 },
6788 for (const TestCase& test_case : test_cases) {
6789 SCOPED_TRACE(test_case.name);
6791 std::string id;
6792 std::string version;
6793 // Don't keep |extension| around longer than necessary.
6795 const Extension* extension =
6796 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6797 // The extension should now be installed and enabled.
6798 ASSERT_TRUE(extension);
6799 id = extension->id();
6800 version = extension->VersionString();
6802 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6804 // Disable it if the test case says so.
6805 if (test_case.previous_disable_reasons) {
6806 service()->DisableExtension(id, test_case.previous_disable_reasons);
6807 ASSERT_TRUE(registry()->disabled_extensions().Contains(id));
6810 // Now a sync update comes in.
6811 sync_pb::EntitySpecifics specifics;
6812 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6813 ext_specifics->set_id(id);
6814 ext_specifics->set_enabled(test_case.sync_enable);
6815 ext_specifics->set_version(version);
6816 if (test_case.sync_disable_reasons != -1)
6817 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6819 syncer::SyncData sync_data =
6820 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6821 syncer::SyncChange sync_change(FROM_HERE,
6822 syncer::SyncChange::ACTION_UPDATE,
6823 sync_data);
6824 syncer::SyncChangeList list(1, sync_change);
6825 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6827 // Check expectations.
6828 const bool expect_enabled = !test_case.expect_disable_reasons;
6829 EXPECT_EQ(expect_enabled, service()->IsExtensionEnabled(id));
6830 EXPECT_EQ(test_case.expect_disable_reasons, prefs->GetDisableReasons(id));
6832 // Remove the extension again, so we can install it again for the next case.
6833 UninstallExtension(id, false, expect_enabled ? Extension::ENABLED
6834 : Extension::DISABLED);
6838 TEST_F(ExtensionServiceTest, ProcessSyncDataPermissionApproval) {
6839 // This is the update URL specified in the test extension. Setting it here is
6840 // necessary to make it considered syncable.
6841 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6842 switches::kAppsGalleryUpdateURL,
6843 "http://localhost/autoupdate/updates.xml");
6845 InitializeEmptyExtensionService();
6846 InitializeExtensionSyncService();
6847 extension_sync_service()->MergeDataAndStartSyncing(
6848 syncer::EXTENSIONS,
6849 syncer::SyncDataList(),
6850 scoped_ptr<syncer::SyncChangeProcessor>(
6851 new syncer::FakeSyncChangeProcessor),
6852 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6854 const base::FilePath base_path =
6855 data_dir().AppendASCII("permissions_increase");
6856 const base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
6857 const base::FilePath path_v1 = base_path.AppendASCII("v1");
6858 const base::FilePath path_v2 = base_path.AppendASCII("v2");
6860 base::ScopedTempDir crx_dir;
6861 ASSERT_TRUE(crx_dir.CreateUniqueTempDir());
6862 const base::FilePath crx_path_v1 = crx_dir.path().AppendASCII("temp1.crx");
6863 PackCRX(path_v1, pem_path, crx_path_v1);
6864 const base::FilePath crx_path_v2 = crx_dir.path().AppendASCII("temp2.crx");
6865 PackCRX(path_v2, pem_path, crx_path_v2);
6867 const std::string v1("1");
6868 const std::string v2("2");
6870 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6872 struct TestCase {
6873 const char* name; // For failure output only.
6874 const std::string& sync_version; // The version coming in from Sync.
6875 // The disable reason(s) coming in from Sync, or -1 for "not set".
6876 int sync_disable_reasons;
6877 // Whether the extension's permissions should be auto-granted.
6878 bool expect_permissions_granted;
6879 } test_cases[] = {
6880 // Sync tells us to re-enable an older version. No permissions should be
6881 // granted, since we can't be sure if the user actually approved the right
6882 // set of permissions. Note that the extension will get disabled again the
6883 // next time ExtensionService::CheckPermissionsIncrease runs because of the
6884 // extra permissions.
6885 { "OldVersion", v1, 0, false },
6886 // Legacy case: Sync tells us to re-enable the extension, but doesn't
6887 // specify disable reasons. No permissions should be granted.
6888 { "Legacy", v2, -1, false },
6889 // Sync tells us to re-enable the extension and explicitly removes the
6890 // disable reasons. Now the extension should have its permissions granted.
6891 { "GrantPermissions", v2, 0, true },
6894 for (const TestCase& test_case : test_cases) {
6895 SCOPED_TRACE(test_case.name);
6897 std::string id;
6898 // Don't keep |extension| around longer than necessary (it'll be destroyed
6899 // during updating).
6901 const Extension* extension = InstallCRX(crx_path_v1, INSTALL_NEW);
6902 // The extension should now be installed and enabled.
6903 ASSERT_TRUE(extension);
6904 ASSERT_EQ(v1, extension->VersionString());
6905 id = extension->id();
6907 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6909 scoped_refptr<PermissionSet> granted_permissions_v1(
6910 prefs->GetGrantedPermissions(id));
6912 // Update to a new version with increased permissions.
6913 UpdateExtension(id, crx_path_v2, DISABLED);
6915 // Now the extension should be disabled due to a permissions increase.
6917 const Extension* extension =
6918 registry()->disabled_extensions().GetByID(id);
6919 ASSERT_TRUE(extension);
6920 ASSERT_EQ(v2, extension->VersionString());
6922 ASSERT_TRUE(prefs->HasDisableReason(
6923 id, Extension::DISABLE_PERMISSIONS_INCREASE));
6925 // No new permissions should have been granted.
6926 scoped_refptr<PermissionSet> granted_permissions_v2(
6927 prefs->GetGrantedPermissions(id));
6928 ASSERT_EQ(*granted_permissions_v1, *granted_permissions_v2);
6930 // Now a sync update comes in.
6931 sync_pb::EntitySpecifics specifics;
6932 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6933 ext_specifics->set_id(id);
6934 ext_specifics->set_enabled(true);
6935 ext_specifics->set_version(test_case.sync_version);
6936 if (test_case.sync_disable_reasons != -1)
6937 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6939 syncer::SyncData sync_data =
6940 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6941 syncer::SyncChange sync_change(FROM_HERE,
6942 syncer::SyncChange::ACTION_UPDATE,
6943 sync_data);
6944 syncer::SyncChangeList list(1, sync_change);
6945 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6947 // Check expectations.
6948 EXPECT_TRUE(registry()->GetExtensionById(id, ExtensionRegistry::ENABLED));
6949 scoped_refptr<PermissionSet> granted_permissions(
6950 prefs->GetGrantedPermissions(id));
6951 if (test_case.expect_permissions_granted) {
6952 scoped_refptr<PermissionSet> active_permissions(
6953 prefs->GetActivePermissions(id));
6954 EXPECT_EQ(*granted_permissions, *active_permissions);
6955 } else {
6956 EXPECT_EQ(*granted_permissions, *granted_permissions_v1);
6958 EXPECT_EQ(Extension::DISABLE_NONE, prefs->GetDisableReasons(id));
6960 // Remove the extension again, so we can install it again for the next case.
6961 UninstallExtension(id, false);
6965 #if defined(ENABLE_SUPERVISED_USERS)
6966 class ScopedSupervisedUserServiceDelegate
6967 : public SupervisedUserService::Delegate {
6968 public:
6969 explicit ScopedSupervisedUserServiceDelegate(SupervisedUserService* service)
6970 : service_(service) {
6971 service_->SetDelegate(this);
6973 ~ScopedSupervisedUserServiceDelegate() override {
6974 service_->SetDelegate(nullptr);
6977 // This prevents the legacy supervised user init code from running.
6978 bool SetActive(bool active) override { return true; }
6980 private:
6981 SupervisedUserService* service_;
6984 class MockPermissionRequestCreator : public PermissionRequestCreator {
6985 public:
6986 MockPermissionRequestCreator() {}
6987 ~MockPermissionRequestCreator() override {}
6989 bool IsEnabled() const override { return true; }
6991 void CreateURLAccessRequest(const GURL& url_requested,
6992 const SuccessCallback& callback) override {
6993 FAIL();
6996 MOCK_METHOD2(CreateExtensionUpdateRequest,
6997 void(const std::string& id,
6998 const SupervisedUserService::SuccessCallback& callback));
7000 private:
7001 DISALLOW_COPY_AND_ASSIGN(MockPermissionRequestCreator);
7004 TEST_F(ExtensionServiceTest, SupervisedUser_InstallOnlyAllowedByCustodian) {
7005 ExtensionServiceInitParams params = CreateDefaultInitParams();
7006 params.profile_is_supervised = true;
7007 InitializeExtensionService(params);
7009 SupervisedUserService* supervised_user_service =
7010 SupervisedUserServiceFactory::GetForProfile(profile());
7011 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7012 supervised_user_service->Init();
7014 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7015 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7016 const Extension* extensions[] = {
7017 InstallCRX(path1, INSTALL_FAILED),
7018 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7021 // Only the extension with the "installed by custodian" flag should have been
7022 // installed and enabled.
7023 EXPECT_FALSE(extensions[0]);
7024 ASSERT_TRUE(extensions[1]);
7025 EXPECT_TRUE(registry()->enabled_extensions().Contains(extensions[1]->id()));
7028 TEST_F(ExtensionServiceTest, SupervisedUser_PreinstalledExtension) {
7029 ExtensionServiceInitParams params = CreateDefaultInitParams();
7030 // Do *not* set the profile to supervised here!
7031 InitializeExtensionService(params);
7033 SupervisedUserService* supervised_user_service =
7034 SupervisedUserServiceFactory::GetForProfile(profile());
7035 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7036 supervised_user_service->Init();
7038 // Install an extension.
7039 base::FilePath path = data_dir().AppendASCII("good.crx");
7040 const Extension* extension = InstallCRX(path, INSTALL_NEW);
7041 std::string id = extension->id();
7043 // Now make the profile supervised.
7044 profile()->AsTestingProfile()->SetSupervisedUserId(
7045 supervised_users::kChildAccountSUID);
7047 // The extension should not be enabled anymore.
7048 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7051 TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithoutPermissionIncrease) {
7052 ExtensionServiceInitParams params = CreateDefaultInitParams();
7053 params.profile_is_supervised = true;
7054 InitializeExtensionService(params);
7056 SupervisedUserService* supervised_user_service =
7057 SupervisedUserServiceFactory::GetForProfile(profile());
7058 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7059 supervised_user_service->Init();
7061 base::FilePath base_path = data_dir().AppendASCII("autoupdate");
7062 base::FilePath pem_path = base_path.AppendASCII("key.pem");
7064 base::FilePath path = base_path.AppendASCII("v1");
7065 const Extension* extension =
7066 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
7067 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7068 // The extension must now be installed and enabled.
7069 ASSERT_TRUE(extension);
7070 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7072 // Save the id, as the extension object will be destroyed during updating.
7073 std::string id = extension->id();
7075 std::string old_version = extension->VersionString();
7077 // Update to a new version.
7078 path = base_path.AppendASCII("v2");
7079 PackCRXAndUpdateExtension(id, path, pem_path, ENABLED);
7081 // The extension should still be there and enabled.
7082 extension = registry()->enabled_extensions().GetByID(id);
7083 ASSERT_TRUE(extension);
7084 // The version should have changed.
7085 EXPECT_NE(extension->VersionString(), old_version);
7088 TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithPermissionIncrease) {
7089 ExtensionServiceInitParams params = CreateDefaultInitParams();
7090 params.profile_is_supervised = true;
7091 InitializeExtensionService(params);
7093 SupervisedUserService* supervised_user_service =
7094 SupervisedUserServiceFactory::GetForProfile(profile());
7095 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7096 supervised_user_service->Init();
7097 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
7098 supervised_user_service->AddPermissionRequestCreator(
7099 make_scoped_ptr(creator));
7101 base::FilePath base_path = data_dir().AppendASCII("permissions_increase");
7102 base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
7104 base::FilePath path = base_path.AppendASCII("v1");
7105 const Extension* extension =
7106 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
7107 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7108 // The extension must now be installed and enabled.
7109 ASSERT_TRUE(extension);
7110 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7112 // Save the id, as the extension object will be destroyed during updating.
7113 std::string id = extension->id();
7115 std::string old_version = extension->VersionString();
7117 // Update to a new version with increased permissions.
7118 EXPECT_CALL(*creator,
7119 CreateExtensionUpdateRequest(id + ":2", testing::_));
7120 path = base_path.AppendASCII("v2");
7121 PackCRXAndUpdateExtension(id, path, pem_path, DISABLED);
7123 // The extension should still be there, but disabled.
7124 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7125 extension = registry()->disabled_extensions().GetByID(id);
7126 ASSERT_TRUE(extension);
7127 // The version should have changed.
7128 EXPECT_NE(extension->VersionString(), old_version);
7131 TEST_F(ExtensionServiceTest,
7132 SupervisedUser_SyncUninstallByCustodianSkipsPolicy) {
7133 InitializeEmptyExtensionService();
7134 InitializeExtensionSyncService();
7135 extension_sync_service()->MergeDataAndStartSyncing(
7136 syncer::EXTENSIONS,
7137 syncer::SyncDataList(),
7138 scoped_ptr<syncer::SyncChangeProcessor>(
7139 new syncer::FakeSyncChangeProcessor),
7140 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
7142 // Install two extensions.
7143 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7144 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7145 const Extension* extensions[] = {
7146 InstallCRX(path1, INSTALL_NEW),
7147 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7150 // Add a policy provider that will disallow any changes.
7151 extensions::TestManagementPolicyProvider provider(
7152 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
7153 GetManagementPolicy()->RegisterProvider(&provider);
7155 // Create a sync deletion for each extension.
7156 syncer::SyncChangeList change_list;
7157 for (size_t i = 0; i < arraysize(extensions); i++) {
7158 const std::string& id = extensions[i]->id();
7159 sync_pb::EntitySpecifics specifics;
7160 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
7161 ext_specifics->set_id(id);
7162 ext_specifics->set_version("1.0");
7163 ext_specifics->set_installed_by_custodian(
7164 extensions[i]->was_installed_by_custodian());
7165 syncer::SyncData sync_data =
7166 syncer::SyncData::CreateLocalData(id, "Name", specifics);
7167 change_list.push_back(syncer::SyncChange(FROM_HERE,
7168 syncer::SyncChange::ACTION_DELETE,
7169 sync_data));
7172 // Save the extension ids, as uninstalling destroys the Extension instance.
7173 std::string extension_ids[] = {
7174 extensions[0]->id(),
7175 extensions[1]->id()
7178 // Now apply the uninstallations.
7179 extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
7181 // Uninstalling the extension without installed_by_custodian should have been
7182 // blocked by policy, so it should still be there.
7183 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_ids[0]));
7185 // But installed_by_custodian should result in bypassing the policy check.
7186 EXPECT_FALSE(
7187 registry()->GenerateInstalledExtensionsSet()->Contains(extension_ids[1]));
7189 #endif // defined(ENABLE_SUPERVISED_USERS)
7191 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
7192 InitializeEmptyExtensionService();
7194 base::FilePath path = data_dir().AppendASCII("good.crx");
7195 InstallCRX(path, INSTALL_NEW);
7196 ValidatePrefKeyCount(1u);
7197 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7198 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7200 extensions::PendingExtensionManager* pending =
7201 service()->pending_extension_manager();
7202 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7204 // Skip install when the location is the same.
7205 EXPECT_FALSE(
7206 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
7207 std::string(),
7208 GURL(kGoodUpdateURL),
7209 Manifest::INTERNAL,
7210 Extension::NO_FLAGS,
7211 false));
7212 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7214 // Install when the location has higher priority.
7215 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
7216 kGoodId,
7217 std::string(),
7218 GURL(kGoodUpdateURL),
7219 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7220 Extension::NO_FLAGS,
7221 false));
7222 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7224 // Try the low priority again. Should be rejected.
7225 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(
7226 kGoodId,
7227 std::string(),
7228 GURL(kGoodUpdateURL),
7229 Manifest::EXTERNAL_PREF_DOWNLOAD,
7230 Extension::NO_FLAGS,
7231 false));
7232 // The existing record should still be present in the pending extension
7233 // manager.
7234 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7236 pending->Remove(kGoodId);
7238 // Skip install when the location has the same priority as the installed
7239 // location.
7240 EXPECT_FALSE(
7241 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
7242 std::string(),
7243 GURL(kGoodUpdateURL),
7244 Manifest::INTERNAL,
7245 Extension::NO_FLAGS,
7246 false));
7248 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7251 TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
7252 Version older_version("0.1.0.0");
7253 Version newer_version("2.0.0.0");
7255 // We don't want the extension to be installed. A path that doesn't
7256 // point to a valid CRX ensures this.
7257 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
7259 const int kCreationFlags = 0;
7260 const bool kDontMarkAcknowledged = false;
7261 const bool kDontInstallImmediately = false;
7263 InitializeEmptyExtensionService();
7265 // The test below uses install source constants to test that
7266 // priority is enforced. It assumes a specific ranking of install
7267 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
7268 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
7269 // The following assertions verify these assumptions:
7270 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
7271 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
7272 Manifest::EXTERNAL_PREF));
7273 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
7274 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
7275 Manifest::INTERNAL));
7276 ASSERT_EQ(Manifest::EXTERNAL_PREF,
7277 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
7278 Manifest::INTERNAL));
7280 extensions::PendingExtensionManager* pending =
7281 service()->pending_extension_manager();
7282 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7285 // Simulate an external source adding the extension as INTERNAL.
7286 content::WindowedNotificationObserver observer(
7287 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7288 content::NotificationService::AllSources());
7289 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7290 kGoodId,
7291 &older_version,
7292 kInvalidPathToCrx,
7293 Manifest::INTERNAL,
7294 kCreationFlags,
7295 kDontMarkAcknowledged,
7296 kDontInstallImmediately));
7297 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7298 observer.Wait();
7299 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7303 // Simulate an external source adding the extension as EXTERNAL_PREF.
7304 content::WindowedNotificationObserver observer(
7305 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7306 content::NotificationService::AllSources());
7307 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7308 kGoodId,
7309 &older_version,
7310 kInvalidPathToCrx,
7311 Manifest::EXTERNAL_PREF,
7312 kCreationFlags,
7313 kDontMarkAcknowledged,
7314 kDontInstallImmediately));
7315 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7316 observer.Wait();
7317 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7320 // Simulate an external source adding as EXTERNAL_PREF again.
7321 // This is rejected because the version and the location are the same as
7322 // the previous installation, which is still pending.
7323 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7324 kGoodId,
7325 &older_version,
7326 kInvalidPathToCrx,
7327 Manifest::EXTERNAL_PREF,
7328 kCreationFlags,
7329 kDontMarkAcknowledged,
7330 kDontInstallImmediately));
7331 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7333 // Try INTERNAL again. Should fail.
7334 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7335 kGoodId,
7336 &older_version,
7337 kInvalidPathToCrx,
7338 Manifest::INTERNAL,
7339 kCreationFlags,
7340 kDontMarkAcknowledged,
7341 kDontInstallImmediately));
7342 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7345 // Now the registry adds the extension.
7346 content::WindowedNotificationObserver observer(
7347 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7348 content::NotificationService::AllSources());
7349 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7350 kGoodId,
7351 &older_version,
7352 kInvalidPathToCrx,
7353 Manifest::EXTERNAL_REGISTRY,
7354 kCreationFlags,
7355 kDontMarkAcknowledged,
7356 kDontInstallImmediately));
7357 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7358 observer.Wait();
7359 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7362 // Registry outranks both external pref and internal, so both fail.
7363 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7364 kGoodId,
7365 &older_version,
7366 kInvalidPathToCrx,
7367 Manifest::EXTERNAL_PREF,
7368 kCreationFlags,
7369 kDontMarkAcknowledged,
7370 kDontInstallImmediately));
7371 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7373 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7374 kGoodId,
7375 &older_version,
7376 kInvalidPathToCrx,
7377 Manifest::INTERNAL,
7378 kCreationFlags,
7379 kDontMarkAcknowledged,
7380 kDontInstallImmediately));
7381 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7383 pending->Remove(kGoodId);
7385 // Install the extension.
7386 base::FilePath path = data_dir().AppendASCII("good.crx");
7387 const Extension* ext = InstallCRX(path, INSTALL_NEW);
7388 ValidatePrefKeyCount(1u);
7389 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7390 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7392 // Now test the logic of OnExternalExtensionFileFound() when the extension
7393 // being added is already installed.
7395 // Tests assume |older_version| is less than the installed version, and
7396 // |newer_version| is greater. Verify this:
7397 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
7398 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
7400 // An external install for the same location should fail if the version is
7401 // older, or the same, and succeed if the version is newer.
7403 // Older than the installed version...
7404 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7405 kGoodId,
7406 &older_version,
7407 kInvalidPathToCrx,
7408 Manifest::INTERNAL,
7409 kCreationFlags,
7410 kDontMarkAcknowledged,
7411 kDontInstallImmediately));
7412 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7414 // Same version as the installed version...
7415 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7416 kGoodId,
7417 ext->version(),
7418 kInvalidPathToCrx,
7419 Manifest::INTERNAL,
7420 kCreationFlags,
7421 kDontMarkAcknowledged,
7422 kDontInstallImmediately));
7423 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7425 // Newer than the installed version...
7426 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7427 kGoodId,
7428 &newer_version,
7429 kInvalidPathToCrx,
7430 Manifest::INTERNAL,
7431 kCreationFlags,
7432 kDontMarkAcknowledged,
7433 kDontInstallImmediately));
7434 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7436 // An external install for a higher priority install source should succeed
7437 // if the version is greater. |older_version| is not...
7438 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7439 kGoodId,
7440 &older_version,
7441 kInvalidPathToCrx,
7442 Manifest::EXTERNAL_PREF,
7443 kCreationFlags,
7444 kDontMarkAcknowledged,
7445 kDontInstallImmediately));
7446 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7448 // |newer_version| is newer.
7449 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7450 kGoodId,
7451 &newer_version,
7452 kInvalidPathToCrx,
7453 Manifest::EXTERNAL_PREF,
7454 kCreationFlags,
7455 kDontMarkAcknowledged,
7456 kDontInstallImmediately));
7457 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7459 // An external install for an even higher priority install source should
7460 // succeed if the version is greater.
7461 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7462 kGoodId,
7463 &newer_version,
7464 kInvalidPathToCrx,
7465 Manifest::EXTERNAL_REGISTRY,
7466 kCreationFlags,
7467 kDontMarkAcknowledged,
7468 kDontInstallImmediately));
7469 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7471 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
7472 // adding from external pref will now fail.
7473 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7474 kGoodId,
7475 &newer_version,
7476 kInvalidPathToCrx,
7477 Manifest::EXTERNAL_PREF,
7478 kCreationFlags,
7479 kDontMarkAcknowledged,
7480 kDontInstallImmediately));
7481 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7484 TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
7485 Version kVersion123("1.2.3");
7486 Version kVersion124("1.2.4");
7487 Version kVersion125("1.2.5");
7488 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
7489 const int kCreationFlags = 0;
7490 const bool kDontMarkAcknowledged = false;
7491 const bool kDontInstallImmediately = false;
7493 InitializeEmptyExtensionService();
7495 extensions::PendingExtensionManager* pending =
7496 service()->pending_extension_manager();
7497 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7499 // An external provider starts installing from a local crx.
7500 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7501 kGoodId,
7502 &kVersion123,
7503 kInvalidPathToCrx,
7504 Manifest::EXTERNAL_PREF,
7505 kCreationFlags,
7506 kDontMarkAcknowledged,
7507 kDontInstallImmediately));
7508 const extensions::PendingExtensionInfo* info;
7509 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7510 EXPECT_TRUE(info->version().IsValid());
7511 EXPECT_TRUE(info->version().Equals(kVersion123));
7513 // Adding a newer version overrides the currently pending version.
7514 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7515 kGoodId,
7516 &kVersion124,
7517 kInvalidPathToCrx,
7518 Manifest::EXTERNAL_PREF,
7519 kCreationFlags,
7520 kDontMarkAcknowledged,
7521 kDontInstallImmediately));
7522 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7523 EXPECT_TRUE(info->version().IsValid());
7524 EXPECT_TRUE(info->version().Equals(kVersion124));
7526 // Adding an older version fails.
7527 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7528 kGoodId,
7529 &kVersion123,
7530 kInvalidPathToCrx,
7531 Manifest::EXTERNAL_PREF,
7532 kCreationFlags,
7533 kDontMarkAcknowledged,
7534 kDontInstallImmediately));
7535 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7536 EXPECT_TRUE(info->version().IsValid());
7537 EXPECT_TRUE(info->version().Equals(kVersion124));
7539 // Adding an older version fails even when coming from a higher-priority
7540 // location.
7541 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7542 kGoodId,
7543 &kVersion123,
7544 kInvalidPathToCrx,
7545 Manifest::EXTERNAL_REGISTRY,
7546 kCreationFlags,
7547 kDontMarkAcknowledged,
7548 kDontInstallImmediately));
7549 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7550 EXPECT_TRUE(info->version().IsValid());
7551 EXPECT_TRUE(info->version().Equals(kVersion124));
7553 // Adding the latest version from the webstore overrides a specific version.
7554 GURL kUpdateUrl("http://example.com/update");
7555 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
7556 kGoodId,
7557 std::string(),
7558 kUpdateUrl,
7559 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7560 Extension::NO_FLAGS,
7561 false));
7562 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7563 EXPECT_FALSE(info->version().IsValid());
7566 // This makes sure we can package and install CRX files that use whitelisted
7567 // permissions.
7568 TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
7569 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
7570 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
7571 extensions::switches::kWhitelistedExtensionID, test_id);
7573 InitializeEmptyExtensionService();
7574 base::FilePath path = data_dir().AppendASCII("permissions");
7575 base::FilePath pem_path = path
7576 .AppendASCII("whitelist.pem");
7577 path = path
7578 .AppendASCII("whitelist");
7580 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
7581 EXPECT_EQ(0u, GetErrors().size());
7582 ASSERT_EQ(1u, registry()->enabled_extensions().size());
7583 EXPECT_EQ(test_id, extension->id());
7586 // Test that when multiple sources try to install an extension,
7587 // we consistently choose the right one. To make tests easy to read,
7588 // methods that fake requests to install crx files in several ways
7589 // are provided.
7590 class ExtensionSourcePriorityTest : public ExtensionServiceTest {
7591 public:
7592 void SetUp() override {
7593 ExtensionServiceTest::SetUp();
7595 // All tests use a single extension. Put the id and path in member vars
7596 // that all methods can read.
7597 crx_id_ = kGoodId;
7598 crx_path_ = data_dir().AppendASCII("good.crx");
7601 // Fake an external source adding a URL to fetch an extension from.
7602 bool AddPendingExternalPrefUrl() {
7603 return service()->pending_extension_manager()->AddFromExternalUpdateUrl(
7604 crx_id_,
7605 std::string(),
7606 GURL(),
7607 Manifest::EXTERNAL_PREF_DOWNLOAD,
7608 Extension::NO_FLAGS,
7609 false);
7612 // Fake an external file from external_extensions.json.
7613 bool AddPendingExternalPrefFileInstall() {
7614 Version version("1.0.0.0");
7616 return service()->OnExternalExtensionFileFound(crx_id_,
7617 &version,
7618 crx_path_,
7619 Manifest::EXTERNAL_PREF,
7620 Extension::NO_FLAGS,
7621 false,
7622 false);
7625 // Fake a request from sync to install an extension.
7626 bool AddPendingSyncInstall() {
7627 return service()->pending_extension_manager()->AddFromSync(
7628 crx_id_,
7629 GURL(kGoodUpdateURL),
7630 &IsExtension,
7631 kGoodRemoteInstall,
7632 kGoodInstalledByCustodian);
7635 // Fake a policy install.
7636 bool AddPendingPolicyInstall() {
7637 // Get path to the CRX with id |kGoodId|.
7638 return service()->OnExternalExtensionUpdateUrlFound(
7639 crx_id_,
7640 std::string(),
7641 GURL(),
7642 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7643 Extension::NO_FLAGS,
7644 false);
7647 // Get the install source of a pending extension.
7648 Manifest::Location GetPendingLocation() {
7649 const extensions::PendingExtensionInfo* info;
7650 EXPECT_TRUE(
7651 (info = service()->pending_extension_manager()->GetById(crx_id_)));
7652 return info->install_source();
7655 // Is an extension pending from a sync request?
7656 bool GetPendingIsFromSync() {
7657 const extensions::PendingExtensionInfo* info;
7658 EXPECT_TRUE(
7659 (info = service()->pending_extension_manager()->GetById(crx_id_)));
7660 return info->is_from_sync();
7663 // Is the CRX id these tests use pending?
7664 bool IsCrxPending() {
7665 return service()->pending_extension_manager()->IsIdPending(crx_id_);
7668 // Is an extension installed?
7669 bool IsCrxInstalled() {
7670 return (service()->GetExtensionById(crx_id_, true) != NULL);
7673 protected:
7674 // All tests use a single extension. Making the id and path member
7675 // vars avoids pasing the same argument to every method.
7676 std::string crx_id_;
7677 base::FilePath crx_path_;
7680 // Test that a pending request for installation of an external CRX from
7681 // an update URL overrides a pending request to install the same extension
7682 // from sync.
7683 TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
7684 InitializeEmptyExtensionService();
7686 ASSERT_FALSE(IsCrxInstalled());
7688 // Install pending extension from sync.
7689 content::WindowedNotificationObserver observer(
7690 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7691 content::NotificationService::AllSources());
7692 EXPECT_TRUE(AddPendingSyncInstall());
7693 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
7694 EXPECT_TRUE(GetPendingIsFromSync());
7695 ASSERT_FALSE(IsCrxInstalled());
7697 // Install pending as external prefs json would.
7698 AddPendingExternalPrefFileInstall();
7699 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
7700 ASSERT_FALSE(IsCrxInstalled());
7702 // Another request from sync should be ignored.
7703 EXPECT_FALSE(AddPendingSyncInstall());
7704 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
7705 ASSERT_FALSE(IsCrxInstalled());
7707 observer.Wait();
7708 VerifyCrxInstall(crx_path_, INSTALL_NEW);
7709 ASSERT_TRUE(IsCrxInstalled());
7712 // Test that an install of an external CRX from an update overrides
7713 // an install of the same extension from sync.
7714 TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
7715 InitializeEmptyExtensionService();
7716 ASSERT_FALSE(IsCrxInstalled());
7718 EXPECT_TRUE(AddPendingSyncInstall());
7719 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
7720 EXPECT_TRUE(GetPendingIsFromSync());
7721 ASSERT_FALSE(IsCrxInstalled());
7723 ASSERT_TRUE(AddPendingExternalPrefUrl());
7724 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
7725 EXPECT_FALSE(GetPendingIsFromSync());
7726 ASSERT_FALSE(IsCrxInstalled());
7728 EXPECT_FALSE(AddPendingSyncInstall());
7729 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
7730 EXPECT_FALSE(GetPendingIsFromSync());
7731 ASSERT_FALSE(IsCrxInstalled());
7734 // Test that an external install request stops sync from installing
7735 // the same extension.
7736 TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
7737 InitializeEmptyExtensionService();
7738 ASSERT_FALSE(IsCrxInstalled());
7740 // External prefs starts an install.
7741 AddPendingExternalPrefFileInstall();
7743 // Crx installer was made, but has not yet run.
7744 ASSERT_FALSE(IsCrxInstalled());
7746 // Before the CRX installer runs, Sync requests that the same extension
7747 // be installed. Should fail, because an external source is pending.
7748 content::WindowedNotificationObserver observer(
7749 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7750 content::NotificationService::AllSources());
7751 ASSERT_FALSE(AddPendingSyncInstall());
7753 // Wait for the external source to install.
7754 observer.Wait();
7755 VerifyCrxInstall(crx_path_, INSTALL_NEW);
7756 ASSERT_TRUE(IsCrxInstalled());
7758 // Now that the extension is installed, sync request should fail
7759 // because the extension is already installed.
7760 ASSERT_FALSE(AddPendingSyncInstall());
7763 // Test that installing an external extension displays a GlobalError.
7764 TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
7765 FeatureSwitch::ScopedOverride prompt(
7766 FeatureSwitch::prompt_for_external_extensions(), true);
7768 InitializeEmptyExtensionService();
7769 MockExtensionProvider* provider =
7770 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7771 AddMockExternalProvider(provider);
7773 service()->external_install_manager()->UpdateExternalExtensionAlert();
7774 // Should return false, meaning there aren't any extensions that the user
7775 // needs to know about.
7776 EXPECT_FALSE(
7777 service()->external_install_manager()->HasExternalInstallError());
7779 // This is a normal extension, installed normally.
7780 // This should NOT trigger an alert.
7781 service()->set_extensions_enabled(true);
7782 base::FilePath path = data_dir().AppendASCII("good.crx");
7783 InstallCRX(path, INSTALL_NEW);
7785 service()->CheckForExternalUpdates();
7786 base::RunLoop().RunUntilIdle();
7787 EXPECT_FALSE(
7788 service()->external_install_manager()->HasExternalInstallError());
7790 // A hosted app, installed externally.
7791 // This should NOT trigger an alert.
7792 provider->UpdateOrAddExtension(
7793 hosted_app, "1.0.0.0", data_dir().AppendASCII("hosted_app.crx"));
7795 content::WindowedNotificationObserver observer(
7796 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7797 content::NotificationService::AllSources());
7798 service()->CheckForExternalUpdates();
7799 observer.Wait();
7800 EXPECT_FALSE(
7801 service()->external_install_manager()->HasExternalInstallError());
7803 // Another normal extension, but installed externally.
7804 // This SHOULD trigger an alert.
7805 provider->UpdateOrAddExtension(
7806 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7808 content::WindowedNotificationObserver observer2(
7809 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7810 content::NotificationService::AllSources());
7811 service()->CheckForExternalUpdates();
7812 observer2.Wait();
7813 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7816 // Test that external extensions are initially disabled, and that enabling
7817 // them clears the prompt.
7818 TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
7819 FeatureSwitch::ScopedOverride prompt(
7820 FeatureSwitch::prompt_for_external_extensions(), true);
7822 InitializeEmptyExtensionService();
7823 MockExtensionProvider* provider =
7824 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7825 AddMockExternalProvider(provider);
7827 provider->UpdateOrAddExtension(
7828 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7830 content::WindowedNotificationObserver observer(
7831 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7832 content::NotificationService::AllSources());
7833 service()->CheckForExternalUpdates();
7834 observer.Wait();
7835 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7836 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
7838 const Extension* extension =
7839 registry()->disabled_extensions().GetByID(page_action);
7840 EXPECT_TRUE(extension);
7841 EXPECT_EQ(page_action, extension->id());
7843 service()->EnableExtension(page_action);
7844 EXPECT_FALSE(
7845 service()->external_install_manager()->HasExternalInstallError());
7846 EXPECT_TRUE(service()->IsExtensionEnabled(page_action));
7849 // Test that installing multiple external extensions works.
7850 // Flaky on windows; http://crbug.com/295757 .
7851 #if defined(OS_WIN)
7852 #define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
7853 #else
7854 #define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
7855 #endif
7856 TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
7857 FeatureSwitch::ScopedOverride prompt(
7858 FeatureSwitch::prompt_for_external_extensions(), true);
7860 InitializeEmptyExtensionService();
7861 MockExtensionProvider* provider =
7862 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7863 AddMockExternalProvider(provider);
7865 provider->UpdateOrAddExtension(
7866 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7867 provider->UpdateOrAddExtension(
7868 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
7869 provider->UpdateOrAddExtension(
7870 theme_crx, "2.0", data_dir().AppendASCII("theme.crx"));
7872 int count = 3;
7873 content::WindowedNotificationObserver observer(
7874 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7875 base::Bind(&WaitForCountNotificationsCallback, &count));
7876 service()->CheckForExternalUpdates();
7877 observer.Wait();
7878 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7879 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
7880 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
7881 EXPECT_FALSE(service()->IsExtensionEnabled(theme_crx));
7883 service()->EnableExtension(page_action);
7884 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7885 EXPECT_FALSE(service()
7886 ->external_install_manager()
7887 ->HasExternalInstallBubbleForTesting());
7889 service()->EnableExtension(theme_crx);
7890 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7891 EXPECT_FALSE(service()
7892 ->external_install_manager()
7893 ->HasExternalInstallBubbleForTesting());
7895 service()->EnableExtension(good_crx);
7896 EXPECT_FALSE(
7897 service()->external_install_manager()->HasExternalInstallError());
7898 EXPECT_FALSE(service()
7899 ->external_install_manager()
7900 ->HasExternalInstallBubbleForTesting());
7903 // Test that there is a bubble for external extensions that update
7904 // from the webstore if the profile is not new.
7905 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
7906 FeatureSwitch::ScopedOverride prompt(
7907 FeatureSwitch::prompt_for_external_extensions(), true);
7909 // This sets up the ExtensionPrefs used by our ExtensionService to be
7910 // post-first run.
7911 ExtensionServiceInitParams params = CreateDefaultInitParams();
7912 params.is_first_run = false;
7913 InitializeExtensionService(params);
7915 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7916 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7917 data_dir().AppendASCII("update_from_webstore.pem"),
7918 crx_path);
7920 MockExtensionProvider* provider =
7921 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7922 AddMockExternalProvider(provider);
7923 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7925 content::WindowedNotificationObserver observer(
7926 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7927 content::NotificationService::AllSources());
7928 service()->CheckForExternalUpdates();
7929 observer.Wait();
7930 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7931 EXPECT_TRUE(service()
7932 ->external_install_manager()
7933 ->HasExternalInstallBubbleForTesting());
7934 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7937 // Test that there is no bubble for external extensions if the profile is new.
7938 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
7939 FeatureSwitch::ScopedOverride prompt(
7940 FeatureSwitch::prompt_for_external_extensions(), true);
7942 InitializeEmptyExtensionService();
7944 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7945 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7946 data_dir().AppendASCII("update_from_webstore.pem"),
7947 crx_path);
7949 MockExtensionProvider* provider =
7950 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7951 AddMockExternalProvider(provider);
7952 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7954 content::WindowedNotificationObserver observer(
7955 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7956 content::NotificationService::AllSources());
7957 service()->CheckForExternalUpdates();
7958 observer.Wait();
7959 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7960 EXPECT_FALSE(service()
7961 ->external_install_manager()
7962 ->HasExternalInstallBubbleForTesting());
7963 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7966 // Test that clicking to remove the extension on an external install warning
7967 // uninstalls the extension.
7968 TEST_F(ExtensionServiceTest, ExternalInstallClickToRemove) {
7969 FeatureSwitch::ScopedOverride prompt(
7970 FeatureSwitch::prompt_for_external_extensions(), true);
7972 ExtensionServiceInitParams params = CreateDefaultInitParams();
7973 params.is_first_run = false;
7974 InitializeExtensionService(params);
7976 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7977 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7978 data_dir().AppendASCII("update_from_webstore.pem"),
7979 crx_path);
7981 MockExtensionProvider* provider =
7982 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
7983 AddMockExternalProvider(provider);
7984 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7986 content::WindowedNotificationObserver observer(
7987 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7988 content::NotificationService::AllSources());
7989 service_->CheckForExternalUpdates();
7990 observer.Wait();
7991 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
7993 // We check both enabled and disabled, since these are "eventually exclusive"
7994 // sets.
7995 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
7996 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7998 // Click the negative response.
7999 service_->external_install_manager()->error_for_testing()->InstallUIAbort(
8000 true);
8001 // The Extension should be uninstalled.
8002 EXPECT_FALSE(registry()->GetExtensionById(updates_from_webstore,
8003 ExtensionRegistry::EVERYTHING));
8004 // The error should be removed.
8005 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
8008 // Test that clicking to keep the extension on an external install warning
8009 // re-enables the extension.
8010 TEST_F(ExtensionServiceTest, ExternalInstallClickToKeep) {
8011 FeatureSwitch::ScopedOverride prompt(
8012 FeatureSwitch::prompt_for_external_extensions(), true);
8014 ExtensionServiceInitParams params = CreateDefaultInitParams();
8015 params.is_first_run = false;
8016 InitializeExtensionService(params);
8018 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
8019 PackCRX(data_dir().AppendASCII("update_from_webstore"),
8020 data_dir().AppendASCII("update_from_webstore.pem"),
8021 crx_path);
8023 MockExtensionProvider* provider =
8024 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
8025 AddMockExternalProvider(provider);
8026 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
8028 content::WindowedNotificationObserver observer(
8029 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
8030 content::NotificationService::AllSources());
8031 service_->CheckForExternalUpdates();
8032 observer.Wait();
8033 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
8035 // We check both enabled and disabled, since these are "eventually exclusive"
8036 // sets.
8037 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
8038 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8040 // Accept the extension.
8041 service_->external_install_manager()->error_for_testing()->InstallUIProceed();
8043 // It should be enabled again.
8044 EXPECT_TRUE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8045 EXPECT_FALSE(
8046 registry()->disabled_extensions().GetByID(updates_from_webstore));
8048 // The error should be removed.
8049 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
8052 TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) {
8053 InitializeEmptyExtensionService();
8055 scoped_refptr<Extension> extension = extensions::ExtensionBuilder()
8056 .SetManifest(extensions::DictionaryBuilder()
8057 .Set("name", "extension")
8058 .Set("version", "1.0")
8059 .Set("manifest_version", 2).Build())
8060 .Build();
8061 ASSERT_TRUE(extension.get());
8062 const std::string& id = extension->id();
8064 std::set<std::string> id_set;
8065 id_set.insert(id);
8066 extensions::ExtensionNotificationObserver notifications(
8067 content::NotificationService::AllSources(), id_set);
8069 // Installation should be allowed but the extension should never have been
8070 // loaded and it should be blacklisted in prefs.
8071 service()->OnExtensionInstalled(
8072 extension.get(),
8073 syncer::StringOrdinal(),
8074 (extensions::kInstallFlagIsBlacklistedForMalware |
8075 extensions::kInstallFlagInstallImmediately));
8076 base::RunLoop().RunUntilIdle();
8078 // Extension was installed but not loaded.
8079 EXPECT_TRUE(notifications.CheckNotifications(
8080 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED));
8081 EXPECT_TRUE(service()->GetInstalledExtension(id));
8083 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
8084 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(id));
8086 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlacklisted(id));
8087 EXPECT_TRUE(
8088 ExtensionPrefs::Get(profile())->IsBlacklistedExtensionAcknowledged(id));
8091 // Tests a profile being destroyed correctly disables extensions.
8092 TEST_F(ExtensionServiceTest, DestroyingProfileClearsExtensions) {
8093 InitializeEmptyExtensionService();
8095 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
8096 EXPECT_NE(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8097 EXPECT_EQ(1u, registry()->enabled_extensions().size());
8098 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8099 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8100 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
8102 service()->Observe(chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
8103 content::Source<Profile>(profile()),
8104 content::NotificationService::NoDetails());
8105 EXPECT_EQ(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8106 EXPECT_EQ(0u, registry()->enabled_extensions().size());
8107 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8108 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8109 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());