Roll src/third_party/WebKit f298044:aa8346d (svn 202628:202629)
[chromium-blink-merge.git] / chrome / browser / extensions / extension_service_unittest.cc
blob68f942949f945858d85b527bccf4a702379ae17b
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/metrics/field_trial.h"
23 #include "base/prefs/scoped_user_pref_update.h"
24 #include "base/single_thread_task_runner.h"
25 #include "base/stl_util.h"
26 #include "base/strings/pattern.h"
27 #include "base/strings/string16.h"
28 #include "base/strings/string_number_conversions.h"
29 #include "base/strings/string_util.h"
30 #include "base/strings/utf_string_conversions.h"
31 #include "base/test/mock_entropy_provider.h"
32 #include "base/thread_task_runner_handle.h"
33 #include "base/version.h"
34 #include "chrome/browser/browser_process.h"
35 #include "chrome/browser/chrome_notification_types.h"
36 #include "chrome/browser/extensions/blacklist.h"
37 #include "chrome/browser/extensions/chrome_app_sorting.h"
38 #include "chrome/browser/extensions/component_loader.h"
39 #include "chrome/browser/extensions/crx_installer.h"
40 #include "chrome/browser/extensions/default_apps.h"
41 #include "chrome/browser/extensions/extension_creator.h"
42 #include "chrome/browser/extensions/extension_error_reporter.h"
43 #include "chrome/browser/extensions/extension_error_ui.h"
44 #include "chrome/browser/extensions/extension_management_test_util.h"
45 #include "chrome/browser/extensions/extension_notification_observer.h"
46 #include "chrome/browser/extensions/extension_service.h"
47 #include "chrome/browser/extensions/extension_service_test_base.h"
48 #include "chrome/browser/extensions/extension_special_storage_policy.h"
49 #include "chrome/browser/extensions/extension_sync_data.h"
50 #include "chrome/browser/extensions/extension_sync_service.h"
51 #include "chrome/browser/extensions/extension_util.h"
52 #include "chrome/browser/extensions/external_install_error.h"
53 #include "chrome/browser/extensions/external_install_manager.h"
54 #include "chrome/browser/extensions/external_policy_loader.h"
55 #include "chrome/browser/extensions/external_pref_loader.h"
56 #include "chrome/browser/extensions/external_provider_impl.h"
57 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
58 #include "chrome/browser/extensions/installed_loader.h"
59 #include "chrome/browser/extensions/pack_extension_job.h"
60 #include "chrome/browser/extensions/pending_extension_info.h"
61 #include "chrome/browser/extensions/pending_extension_manager.h"
62 #include "chrome/browser/extensions/permissions_updater.h"
63 #include "chrome/browser/extensions/test_blacklist.h"
64 #include "chrome/browser/extensions/test_extension_system.h"
65 #include "chrome/browser/extensions/unpacked_installer.h"
66 #include "chrome/browser/extensions/updater/extension_updater.h"
67 #include "chrome/browser/policy/profile_policy_connector.h"
68 #include "chrome/browser/policy/profile_policy_connector_factory.h"
69 #include "chrome/browser/sync/profile_sync_service.h"
70 #include "chrome/browser/sync/profile_sync_service_factory.h"
71 #include "chrome/common/chrome_constants.h"
72 #include "chrome/common/chrome_switches.h"
73 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
74 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
75 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
76 #include "chrome/common/extensions/sync_helper.h"
77 #include "chrome/common/pref_names.h"
78 #include "chrome/common/url_constants.h"
79 #include "chrome/test/base/scoped_browser_locale.h"
80 #include "chrome/test/base/testing_profile.h"
81 #include "components/crx_file/id_util.h"
82 #include "components/pref_registry/pref_registry_syncable.h"
83 #include "components/syncable_prefs/pref_service_syncable.h"
84 #include "components/syncable_prefs/testing_pref_service_syncable.h"
85 #include "content/public/browser/dom_storage_context.h"
86 #include "content/public/browser/gpu_data_manager.h"
87 #include "content/public/browser/indexed_db_context.h"
88 #include "content/public/browser/notification_registrar.h"
89 #include "content/public/browser/notification_service.h"
90 #include "content/public/browser/plugin_service.h"
91 #include "content/public/browser/render_process_host.h"
92 #include "content/public/browser/storage_partition.h"
93 #include "content/public/common/content_constants.h"
94 #include "content/public/test/test_browser_thread_bundle.h"
95 #include "content/public/test/test_utils.h"
96 #include "extensions/browser/extension_dialog_auto_confirm.h"
97 #include "extensions/browser/extension_prefs.h"
98 #include "extensions/browser/extension_registry.h"
99 #include "extensions/browser/extension_system.h"
100 #include "extensions/browser/external_provider_interface.h"
101 #include "extensions/browser/install_flag.h"
102 #include "extensions/browser/management_policy.h"
103 #include "extensions/browser/test_management_policy.h"
104 #include "extensions/browser/uninstall_reason.h"
105 #include "extensions/common/constants.h"
106 #include "extensions/common/extension.h"
107 #include "extensions/common/extension_builder.h"
108 #include "extensions/common/extension_l10n_util.h"
109 #include "extensions/common/extension_resource.h"
110 #include "extensions/common/feature_switch.h"
111 #include "extensions/common/manifest_constants.h"
112 #include "extensions/common/manifest_handlers/background_info.h"
113 #include "extensions/common/manifest_handlers/permissions_parser.h"
114 #include "extensions/common/manifest_url_handlers.h"
115 #include "extensions/common/permissions/permission_set.h"
116 #include "extensions/common/permissions/permissions_data.h"
117 #include "extensions/common/switches.h"
118 #include "extensions/common/url_pattern.h"
119 #include "extensions/common/value_builder.h"
120 #include "gpu/config/gpu_info.h"
121 #include "grit/browser_resources.h"
122 #include "grit/generated_resources.h"
123 #include "net/cookies/canonical_cookie.h"
124 #include "net/cookies/cookie_monster.h"
125 #include "net/cookies/cookie_options.h"
126 #include "net/url_request/url_request_context.h"
127 #include "net/url_request/url_request_context_getter.h"
128 #include "storage/browser/database/database_tracker.h"
129 #include "storage/browser/quota/quota_manager.h"
130 #include "storage/common/database/database_identifier.h"
131 #include "sync/api/fake_sync_change_processor.h"
132 #include "sync/api/string_ordinal.h"
133 #include "sync/api/sync_data.h"
134 #include "sync/api/sync_error_factory.h"
135 #include "sync/api/sync_error_factory_mock.h"
136 #include "sync/api/syncable_service.h"
137 #include "sync/protocol/app_specifics.pb.h"
138 #include "sync/protocol/extension_specifics.pb.h"
139 #include "sync/protocol/sync.pb.h"
140 #include "testing/gtest/include/gtest/gtest.h"
141 #include "testing/platform_test.h"
142 #include "ui/base/l10n/l10n_util.h"
143 #include "url/gurl.h"
145 #if defined(ENABLE_SUPERVISED_USERS)
146 #include "chrome/browser/supervised_user/permission_request_creator.h"
147 #include "chrome/browser/supervised_user/supervised_user_constants.h"
148 #include "chrome/browser/supervised_user/supervised_user_service.h"
149 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
150 #endif
152 #if defined(OS_CHROMEOS)
153 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
154 #include "chrome/browser/chromeos/settings/cros_settings.h"
155 #include "chrome/browser/chromeos/settings/device_settings_service.h"
156 #endif
158 // The blacklist tests rely on the safe-browsing database.
159 #if defined(SAFE_BROWSING_DB_LOCAL)
160 #define ENABLE_BLACKLIST_TESTS
161 #endif
163 using base::DictionaryValue;
164 using base::ListValue;
165 using base::Value;
166 using content::BrowserContext;
167 using content::BrowserThread;
168 using content::DOMStorageContext;
169 using content::IndexedDBContext;
170 using content::PluginService;
171 using extensions::APIPermission;
172 using extensions::APIPermissionSet;
173 using extensions::AppSorting;
174 using extensions::Blacklist;
175 using extensions::CrxInstaller;
176 using extensions::Extension;
177 using extensions::ExtensionCreator;
178 using extensions::ExtensionPrefs;
179 using extensions::ExtensionRegistry;
180 using extensions::ExtensionResource;
181 using extensions::ExtensionSyncData;
182 using extensions::ExtensionSystem;
183 using extensions::FakeSafeBrowsingDatabaseManager;
184 using extensions::FeatureSwitch;
185 using extensions::Manifest;
186 using extensions::PermissionSet;
187 using extensions::TestExtensionSystem;
188 using extensions::UnloadedExtensionInfo;
189 using extensions::URLPatternSet;
191 namespace keys = extensions::manifest_keys;
193 namespace {
195 // Extension ids used during testing.
196 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
197 const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
198 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
199 const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
200 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
201 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
202 const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
203 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
204 const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad";
205 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
206 const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
207 const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
208 const char permissions_blocklist[] = "noffkehfcaggllbcojjbopcmlhcnhcdn";
210 struct ExtensionsOrder {
211 bool operator()(const scoped_refptr<const Extension>& a,
212 const scoped_refptr<const Extension>& b) {
213 return a->name() < b->name();
217 static std::vector<base::string16> GetErrors() {
218 const std::vector<base::string16>* errors =
219 ExtensionErrorReporter::GetInstance()->GetErrors();
220 std::vector<base::string16> ret_val;
222 for (std::vector<base::string16>::const_iterator iter = errors->begin();
223 iter != errors->end(); ++iter) {
224 std::string utf8_error = base::UTF16ToUTF8(*iter);
225 if (utf8_error.find(".svn") == std::string::npos) {
226 ret_val.push_back(*iter);
230 // The tests rely on the errors being in a certain order, which can vary
231 // depending on how filesystem iteration works.
232 std::stable_sort(ret_val.begin(), ret_val.end());
234 return ret_val;
237 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
238 int schemes = URLPattern::SCHEME_ALL;
239 extent->AddPattern(URLPattern(schemes, pattern));
242 base::FilePath GetTemporaryFile() {
243 base::FilePath temp_file;
244 CHECK(base::CreateTemporaryFile(&temp_file));
245 return temp_file;
248 bool WaitForCountNotificationsCallback(int *count) {
249 return --(*count) == 0;
252 } // namespace
254 class MockExtensionProvider : public extensions::ExternalProviderInterface {
255 public:
256 MockExtensionProvider(
257 VisitorInterface* visitor,
258 Manifest::Location location)
259 : location_(location), visitor_(visitor), visit_count_(0) {
262 ~MockExtensionProvider() override {}
264 void UpdateOrAddExtension(const std::string& id,
265 const std::string& version,
266 const base::FilePath& path) {
267 extension_map_[id] = std::make_pair(version, path);
270 void RemoveExtension(const std::string& id) {
271 extension_map_.erase(id);
274 // ExternalProvider implementation:
275 void VisitRegisteredExtension() override {
276 visit_count_++;
277 for (DataMap::const_iterator i = extension_map_.begin();
278 i != extension_map_.end(); ++i) {
279 Version version(i->second.first);
281 visitor_->OnExternalExtensionFileFound(
282 i->first, &version, i->second.second, location_,
283 Extension::NO_FLAGS, false, false);
285 visitor_->OnExternalProviderReady(this);
288 bool HasExtension(const std::string& id) const override {
289 return extension_map_.find(id) != extension_map_.end();
292 bool GetExtensionDetails(const std::string& id,
293 Manifest::Location* location,
294 scoped_ptr<Version>* version) const override {
295 DataMap::const_iterator it = extension_map_.find(id);
296 if (it == extension_map_.end())
297 return false;
299 if (version)
300 version->reset(new Version(it->second.first));
302 if (location)
303 *location = location_;
305 return true;
308 bool IsReady() const override { return true; }
310 void ServiceShutdown() override {}
312 int visit_count() const { return visit_count_; }
313 void set_visit_count(int visit_count) {
314 visit_count_ = visit_count;
317 private:
318 typedef std::map< std::string, std::pair<std::string, base::FilePath> >
319 DataMap;
320 DataMap extension_map_;
321 Manifest::Location location_;
322 VisitorInterface* visitor_;
324 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
325 // Mutable because it must be incremented on each call to
326 // VisitRegisteredExtension(), which must be a const method to inherit
327 // from the class being mocked.
328 mutable int visit_count_;
330 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
333 class MockProviderVisitor
334 : public extensions::ExternalProviderInterface::VisitorInterface {
335 public:
336 // The provider will return |fake_base_path| from
337 // GetBaseCrxFilePath(). User can test the behavior with
338 // and without an empty path using this parameter.
339 explicit MockProviderVisitor(base::FilePath fake_base_path)
340 : ids_found_(0),
341 fake_base_path_(fake_base_path),
342 expected_creation_flags_(Extension::NO_FLAGS) {
343 profile_.reset(new TestingProfile);
346 MockProviderVisitor(base::FilePath fake_base_path,
347 int expected_creation_flags)
348 : ids_found_(0),
349 fake_base_path_(fake_base_path),
350 expected_creation_flags_(expected_creation_flags) {
351 profile_.reset(new TestingProfile);
354 int Visit(const std::string& json_data) {
355 // Give the test json file to the provider for parsing.
356 provider_.reset(new extensions::ExternalProviderImpl(
357 this,
358 new extensions::ExternalTestingLoader(json_data, fake_base_path_),
359 profile_.get(),
360 Manifest::EXTERNAL_PREF,
361 Manifest::EXTERNAL_PREF_DOWNLOAD,
362 Extension::NO_FLAGS));
364 // We also parse the file into a dictionary to compare what we get back
365 // from the provider.
366 JSONStringValueDeserializer deserializer(json_data);
367 base::Value* json_value = deserializer.Deserialize(NULL, NULL);
369 if (!json_value || !json_value->IsType(base::Value::TYPE_DICTIONARY)) {
370 NOTREACHED() << "Unable to deserialize json data";
371 return -1;
372 } else {
373 base::DictionaryValue* external_extensions =
374 static_cast<base::DictionaryValue*>(json_value);
375 prefs_.reset(external_extensions);
378 // Reset our counter.
379 ids_found_ = 0;
380 // Ask the provider to look up all extensions and return them.
381 provider_->VisitRegisteredExtension();
383 return ids_found_;
386 bool OnExternalExtensionFileFound(const std::string& id,
387 const Version* version,
388 const base::FilePath& path,
389 Manifest::Location unused,
390 int creation_flags,
391 bool mark_acknowledged,
392 bool install_immediately) override {
393 EXPECT_EQ(expected_creation_flags_, creation_flags);
395 ++ids_found_;
396 base::DictionaryValue* pref;
397 // This tests is to make sure that the provider only notifies us of the
398 // values we gave it. So if the id we doesn't exist in our internal
399 // dictionary then something is wrong.
400 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
401 << "Got back ID (" << id.c_str() << ") we weren't expecting";
403 EXPECT_TRUE(path.IsAbsolute());
404 if (!fake_base_path_.empty())
405 EXPECT_TRUE(fake_base_path_.IsParent(path));
407 if (pref) {
408 EXPECT_TRUE(provider_->HasExtension(id));
410 // Ask provider if the extension we got back is registered.
411 Manifest::Location location = Manifest::INVALID_LOCATION;
412 scoped_ptr<Version> v1;
413 base::FilePath crx_path;
415 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
416 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
418 scoped_ptr<Version> v2;
419 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
420 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
421 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
422 EXPECT_EQ(Manifest::EXTERNAL_PREF, location);
424 // Remove it so we won't count it ever again.
425 prefs_->Remove(id, NULL);
427 return true;
430 bool OnExternalExtensionUpdateUrlFound(const std::string& id,
431 const std::string& install_parameter,
432 const GURL& update_url,
433 Manifest::Location location,
434 int creation_flags,
435 bool mark_acknowledged) override {
436 ++ids_found_;
437 base::DictionaryValue* pref;
438 // This tests is to make sure that the provider only notifies us of the
439 // values we gave it. So if the id we doesn't exist in our internal
440 // dictionary then something is wrong.
441 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
442 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
443 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location);
445 if (pref) {
446 EXPECT_TRUE(provider_->HasExtension(id));
448 // External extensions with update URLs do not have versions.
449 scoped_ptr<Version> v1;
450 Manifest::Location location1 = Manifest::INVALID_LOCATION;
451 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
452 EXPECT_FALSE(v1.get());
453 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1);
455 std::string parsed_install_parameter;
456 pref->GetString("install_parameter", &parsed_install_parameter);
457 EXPECT_EQ(parsed_install_parameter, install_parameter);
459 // Remove it so we won't count it again.
460 prefs_->Remove(id, NULL);
462 return true;
465 void OnExternalProviderReady(
466 const extensions::ExternalProviderInterface* provider) override {
467 EXPECT_EQ(provider, provider_.get());
468 EXPECT_TRUE(provider->IsReady());
471 Profile* profile() { return profile_.get(); }
473 private:
474 int ids_found_;
475 base::FilePath fake_base_path_;
476 int expected_creation_flags_;
477 scoped_ptr<extensions::ExternalProviderImpl> provider_;
478 scoped_ptr<base::DictionaryValue> prefs_;
479 scoped_ptr<TestingProfile> profile_;
481 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
484 class ExtensionServiceTest : public extensions::ExtensionServiceTestBase,
485 public content::NotificationObserver {
486 public:
487 ExtensionServiceTest()
488 : unloaded_reason_(UnloadedExtensionInfo::REASON_UNDEFINED),
489 installed_(NULL),
490 was_update_(false),
491 override_external_install_prompt_(
492 FeatureSwitch::prompt_for_external_extensions(),
493 false),
494 expected_extensions_count_(0) {
495 registrar_.Add(this,
496 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
497 content::NotificationService::AllSources());
498 registrar_.Add(this,
499 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
500 content::NotificationService::AllSources());
501 registrar_.Add(
502 this,
503 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
504 content::NotificationService::AllSources());
507 void Observe(int type,
508 const content::NotificationSource& source,
509 const content::NotificationDetails& details) override {
510 switch (type) {
511 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
512 const Extension* extension =
513 content::Details<const Extension>(details).ptr();
514 loaded_.push_back(make_scoped_refptr(extension));
515 // The tests rely on the errors being in a certain order, which can vary
516 // depending on how filesystem iteration works.
517 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
518 break;
521 case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
522 UnloadedExtensionInfo* unloaded_info =
523 content::Details<UnloadedExtensionInfo>(details).ptr();
524 const Extension* e = unloaded_info->extension;
525 unloaded_id_ = e->id();
526 unloaded_reason_ = unloaded_info->reason;
527 extensions::ExtensionList::iterator i =
528 std::find(loaded_.begin(), loaded_.end(), e);
529 // TODO(erikkay) fix so this can be an assert. Right now the tests
530 // are manually calling clear() on loaded_, so this isn't doable.
531 if (i == loaded_.end())
532 return;
533 loaded_.erase(i);
534 break;
536 case extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED: {
537 const extensions::InstalledExtensionInfo* installed_info =
538 content::Details<const extensions::InstalledExtensionInfo>(details)
539 .ptr();
540 installed_ = installed_info->extension;
541 was_update_ = installed_info->is_update;
542 old_name_ = installed_info->old_name;
543 break;
546 default:
547 DCHECK(false);
551 void AddMockExternalProvider(
552 extensions::ExternalProviderInterface* provider) {
553 service()->AddProviderForTesting(provider);
556 void MockSyncStartFlare(bool* was_called,
557 syncer::ModelType* model_type_passed_in,
558 syncer::ModelType model_type) {
559 *was_called = true;
560 *model_type_passed_in = model_type;
563 protected:
564 // Paths to some of the fake extensions.
565 base::FilePath good0_path() {
566 return data_dir()
567 .AppendASCII("good")
568 .AppendASCII("Extensions")
569 .AppendASCII(good0)
570 .AppendASCII("1.0.0.0");
573 base::FilePath good1_path() {
574 return data_dir()
575 .AppendASCII("good")
576 .AppendASCII("Extensions")
577 .AppendASCII(good1)
578 .AppendASCII("2");
581 base::FilePath good2_path() {
582 return data_dir()
583 .AppendASCII("good")
584 .AppendASCII("Extensions")
585 .AppendASCII(good2)
586 .AppendASCII("1.0");
589 void TestExternalProvider(MockExtensionProvider* provider,
590 Manifest::Location location);
592 void PackCRX(const base::FilePath& dir_path,
593 const base::FilePath& pem_path,
594 const base::FilePath& crx_path) {
595 // Use the existing pem key, if provided.
596 base::FilePath pem_output_path;
597 if (pem_path.value().empty()) {
598 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
599 } else {
600 ASSERT_TRUE(base::PathExists(pem_path));
603 ASSERT_TRUE(base::DeleteFile(crx_path, false));
605 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
606 ASSERT_TRUE(creator->Run(dir_path,
607 crx_path,
608 pem_path,
609 pem_output_path,
610 ExtensionCreator::kOverwriteCRX));
612 ASSERT_TRUE(base::PathExists(crx_path));
615 enum InstallState {
616 INSTALL_FAILED,
617 INSTALL_UPDATED,
618 INSTALL_NEW,
619 INSTALL_WITHOUT_LOAD,
622 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
623 const base::FilePath& pem_path,
624 InstallState install_state,
625 int creation_flags) {
626 base::FilePath crx_path;
627 base::ScopedTempDir temp_dir;
628 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
629 crx_path = temp_dir.path().AppendASCII("temp.crx");
631 PackCRX(dir_path, pem_path, crx_path);
632 return InstallCRX(crx_path, install_state, creation_flags);
635 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
636 const base::FilePath& pem_path,
637 InstallState install_state) {
638 return PackAndInstallCRX(dir_path, pem_path, install_state,
639 Extension::NO_FLAGS);
642 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
643 InstallState install_state) {
644 return PackAndInstallCRX(dir_path, base::FilePath(), install_state,
645 Extension::NO_FLAGS);
648 // Attempts to install an extension. Use INSTALL_FAILED if the installation
649 // is expected to fail.
650 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
651 // non-empty, expects that the existing extension's title was
652 // |expected_old_name|.
653 const Extension* InstallCRX(const base::FilePath& path,
654 InstallState install_state,
655 int creation_flags,
656 const std::string& expected_old_name) {
657 InstallCRXInternal(path, creation_flags);
658 return VerifyCrxInstall(path, install_state, expected_old_name);
661 // Attempts to install an extension. Use INSTALL_FAILED if the installation
662 // is expected to fail.
663 const Extension* InstallCRX(const base::FilePath& path,
664 InstallState install_state,
665 int creation_flags) {
666 return InstallCRX(path, install_state, creation_flags, std::string());
669 // Attempts to install an extension. Use INSTALL_FAILED if the installation
670 // is expected to fail.
671 const Extension* InstallCRX(const base::FilePath& path,
672 InstallState install_state) {
673 return InstallCRX(path, install_state, Extension::NO_FLAGS);
676 const Extension* InstallCRXFromWebStore(const base::FilePath& path,
677 InstallState install_state) {
678 InstallCRXInternal(path, Extension::FROM_WEBSTORE);
679 return VerifyCrxInstall(path, install_state);
682 const Extension* InstallCRXWithLocation(const base::FilePath& crx_path,
683 Manifest::Location install_location,
684 InstallState install_state) {
685 EXPECT_TRUE(base::PathExists(crx_path))
686 << "Path does not exist: "<< crx_path.value().c_str();
687 // no client (silent install)
688 scoped_refptr<CrxInstaller> installer(
689 CrxInstaller::CreateSilent(service()));
690 installer->set_install_source(install_location);
692 content::WindowedNotificationObserver observer(
693 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
694 content::NotificationService::AllSources());
695 installer->InstallCrx(crx_path);
696 observer.Wait();
698 return VerifyCrxInstall(crx_path, install_state);
701 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
702 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
703 // Returns an Extension pointer if the install succeeded, NULL otherwise.
704 const Extension* VerifyCrxInstall(const base::FilePath& path,
705 InstallState install_state) {
706 return VerifyCrxInstall(path, install_state, std::string());
709 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
710 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
711 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
712 // non-empty, expects that the existing extension's title was
713 // |expected_old_name|.
714 // Returns an Extension pointer if the install succeeded, NULL otherwise.
715 const Extension* VerifyCrxInstall(const base::FilePath& path,
716 InstallState install_state,
717 const std::string& expected_old_name) {
718 std::vector<base::string16> errors = GetErrors();
719 const Extension* extension = NULL;
720 if (install_state != INSTALL_FAILED) {
721 if (install_state == INSTALL_NEW)
722 ++expected_extensions_count_;
724 EXPECT_TRUE(installed_) << path.value();
725 // If and only if INSTALL_UPDATED, it should have the is_update flag.
726 EXPECT_EQ(install_state == INSTALL_UPDATED, was_update_)
727 << path.value();
728 // If INSTALL_UPDATED, old_name_ should match the given string.
729 if (install_state == INSTALL_UPDATED && !expected_old_name.empty())
730 EXPECT_EQ(expected_old_name, old_name_);
731 EXPECT_EQ(0u, errors.size()) << path.value();
733 if (install_state == INSTALL_WITHOUT_LOAD) {
734 EXPECT_EQ(0u, loaded_.size()) << path.value();
735 } else {
736 EXPECT_EQ(1u, loaded_.size()) << path.value();
737 size_t actual_extension_count =
738 registry()->enabled_extensions().size() +
739 registry()->disabled_extensions().size();
740 EXPECT_EQ(expected_extensions_count_, actual_extension_count) <<
741 path.value();
742 extension = loaded_[0].get();
743 EXPECT_TRUE(service()->GetExtensionById(extension->id(), false))
744 << path.value();
747 for (std::vector<base::string16>::iterator err = errors.begin();
748 err != errors.end(); ++err) {
749 LOG(ERROR) << *err;
751 } else {
752 EXPECT_FALSE(installed_) << path.value();
753 EXPECT_EQ(0u, loaded_.size()) << path.value();
754 EXPECT_EQ(1u, errors.size()) << path.value();
757 installed_ = NULL;
758 was_update_ = false;
759 old_name_ = "";
760 loaded_.clear();
761 ExtensionErrorReporter::GetInstance()->ClearErrors();
762 return extension;
765 enum UpdateState {
766 FAILED_SILENTLY,
767 FAILED,
768 UPDATED,
769 INSTALLED,
770 DISABLED,
771 ENABLED
774 void BlackListWebGL() {
775 static const std::string json_blacklist =
776 "{\n"
777 " \"name\": \"gpu blacklist\",\n"
778 " \"version\": \"1.0\",\n"
779 " \"entries\": [\n"
780 " {\n"
781 " \"id\": 1,\n"
782 " \"features\": [\"webgl\"]\n"
783 " }\n"
784 " ]\n"
785 "}";
786 gpu::GPUInfo gpu_info;
787 content::GpuDataManager::GetInstance()->InitializeForTesting(
788 json_blacklist, gpu_info);
791 // Grants all optional permissions stated in manifest to active permission
792 // set for extension |id|.
793 void GrantAllOptionalPermissions(const std::string& id) {
794 const Extension* extension = service()->GetInstalledExtension(id);
795 scoped_refptr<const PermissionSet> all_optional_permissions =
796 extensions::PermissionsParser::GetOptionalPermissions(extension);
797 extensions::PermissionsUpdater perms_updater(profile());
798 perms_updater.AddPermissions(extension, all_optional_permissions.get());
801 // Helper method to set up a WindowedNotificationObserver to wait for a
802 // specific CrxInstaller to finish if we don't know the value of the
803 // |installer| yet.
804 static bool IsCrxInstallerDone(extensions::CrxInstaller** installer,
805 const content::NotificationSource& source,
806 const content::NotificationDetails& details) {
807 return content::Source<extensions::CrxInstaller>(source).ptr() ==
808 *installer;
811 void PackCRXAndUpdateExtension(const std::string& id,
812 const base::FilePath& dir_path,
813 const base::FilePath& pem_path,
814 UpdateState expected_state) {
815 base::ScopedTempDir temp_dir;
816 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
817 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
819 PackCRX(dir_path, pem_path, crx_path);
820 UpdateExtension(id, crx_path, expected_state);
823 void UpdateExtension(const std::string& id,
824 const base::FilePath& in_path,
825 UpdateState expected_state) {
826 ASSERT_TRUE(base::PathExists(in_path));
828 // We need to copy this to a temporary location because Update() will delete
829 // it.
830 base::FilePath path = temp_dir().path();
831 path = path.Append(in_path.BaseName());
832 ASSERT_TRUE(base::CopyFile(in_path, path));
834 int previous_enabled_extension_count =
835 registry()->enabled_extensions().size();
836 int previous_installed_extension_count =
837 previous_enabled_extension_count +
838 registry()->disabled_extensions().size();
840 extensions::CrxInstaller* installer = NULL;
841 content::WindowedNotificationObserver observer(
842 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
843 base::Bind(&IsCrxInstallerDone, &installer));
844 service()->UpdateExtension(extensions::CRXFileInfo(id, path), true,
845 &installer);
847 if (installer)
848 observer.Wait();
849 else
850 base::RunLoop().RunUntilIdle();
852 std::vector<base::string16> errors = GetErrors();
853 int error_count = errors.size();
854 int enabled_extension_count = registry()->enabled_extensions().size();
855 int installed_extension_count =
856 enabled_extension_count + registry()->disabled_extensions().size();
858 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
859 EXPECT_EQ(expected_error_count, error_count) << path.value();
861 if (expected_state <= FAILED) {
862 EXPECT_EQ(previous_enabled_extension_count,
863 enabled_extension_count);
864 EXPECT_EQ(previous_installed_extension_count,
865 installed_extension_count);
866 } else {
867 int expected_installed_extension_count =
868 (expected_state >= INSTALLED) ? 1 : 0;
869 int expected_enabled_extension_count =
870 (expected_state >= ENABLED) ? 1 : 0;
871 EXPECT_EQ(expected_installed_extension_count,
872 installed_extension_count);
873 EXPECT_EQ(expected_enabled_extension_count,
874 enabled_extension_count);
877 // Update() should the temporary input file.
878 EXPECT_FALSE(base::PathExists(path));
881 void TerminateExtension(const std::string& id) {
882 const Extension* extension = service()->GetInstalledExtension(id);
883 if (!extension) {
884 ADD_FAILURE();
885 return;
887 service()->TrackTerminatedExtensionForTest(extension);
890 testing::AssertionResult IsBlocked(const std::string& id) {
891 scoped_ptr<extensions::ExtensionSet> all_unblocked_extensions =
892 registry()->GenerateInstalledExtensionsSet(
893 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::BLOCKED);
894 if (all_unblocked_extensions.get()->Contains(id))
895 return testing::AssertionFailure() << id << " is still unblocked!";
896 if (!registry()->blocked_extensions().Contains(id))
897 return testing::AssertionFailure() << id << " is not blocked!";
898 return testing::AssertionSuccess();
901 // Helper method to test that an extension moves through being blocked and
902 // unblocked as appropriate for its type.
903 void AssertExtensionBlocksAndUnblocks(
904 bool should_block, const std::string extension_id) {
905 // Assume we start in an unblocked state.
906 EXPECT_FALSE(IsBlocked(extension_id));
908 // Block the extensions.
909 service()->BlockAllExtensions();
910 base::RunLoop().RunUntilIdle();
912 if (should_block)
913 ASSERT_TRUE(IsBlocked(extension_id));
914 else
915 ASSERT_FALSE(IsBlocked(extension_id));
917 service()->UnblockAllExtensions();
918 base::RunLoop().RunUntilIdle();
920 ASSERT_FALSE(IsBlocked(extension_id));
923 size_t GetPrefKeyCount() {
924 const base::DictionaryValue* dict =
925 profile()->GetPrefs()->GetDictionary("extensions.settings");
926 if (!dict) {
927 ADD_FAILURE();
928 return 0;
930 return dict->size();
933 void UninstallExtension(const std::string& id, bool use_helper) {
934 UninstallExtension(id, use_helper, Extension::ENABLED);
937 void UninstallExtension(const std::string& id, bool use_helper,
938 Extension::State expected_state) {
939 // Verify that the extension is installed.
940 base::FilePath extension_path = extensions_install_dir().AppendASCII(id);
941 EXPECT_TRUE(base::PathExists(extension_path));
942 size_t pref_key_count = GetPrefKeyCount();
943 EXPECT_GT(pref_key_count, 0u);
944 ValidateIntegerPref(id, "state", expected_state);
946 // Uninstall it.
947 if (use_helper) {
948 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(
949 service(), id, extensions::UNINSTALL_REASON_FOR_TESTING));
950 } else {
951 EXPECT_TRUE(service()->UninstallExtension(
953 extensions::UNINSTALL_REASON_FOR_TESTING,
954 base::Bind(&base::DoNothing),
955 NULL));
957 --expected_extensions_count_;
959 // We should get an unload notification.
960 EXPECT_FALSE(unloaded_id_.empty());
961 EXPECT_EQ(id, unloaded_id_);
963 // Verify uninstalled state.
964 size_t new_pref_key_count = GetPrefKeyCount();
965 if (new_pref_key_count == pref_key_count) {
966 ValidateIntegerPref(id, "state",
967 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
968 } else {
969 EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
972 // The extension should not be in the service anymore.
973 EXPECT_FALSE(service()->GetInstalledExtension(id));
974 base::RunLoop().RunUntilIdle();
976 // The directory should be gone.
977 EXPECT_FALSE(base::PathExists(extension_path));
980 void ValidatePrefKeyCount(size_t count) {
981 EXPECT_EQ(count, GetPrefKeyCount());
984 testing::AssertionResult ValidateBooleanPref(
985 const std::string& extension_id,
986 const std::string& pref_path,
987 bool expected_val) {
988 std::string msg = "while checking: ";
989 msg += extension_id;
990 msg += " ";
991 msg += pref_path;
992 msg += " == ";
993 msg += expected_val ? "true" : "false";
995 PrefService* prefs = profile()->GetPrefs();
996 const base::DictionaryValue* dict =
997 prefs->GetDictionary("extensions.settings");
998 if (!dict) {
999 return testing::AssertionFailure()
1000 << "extension.settings does not exist " << msg;
1003 const base::DictionaryValue* pref = NULL;
1004 if (!dict->GetDictionary(extension_id, &pref)) {
1005 return testing::AssertionFailure()
1006 << "extension pref does not exist " << msg;
1009 bool val;
1010 if (!pref->GetBoolean(pref_path, &val)) {
1011 return testing::AssertionFailure()
1012 << pref_path << " pref not found " << msg;
1015 return expected_val == val
1016 ? testing::AssertionSuccess()
1017 : testing::AssertionFailure() << "base::Value is incorrect " << msg;
1020 bool IsPrefExist(const std::string& extension_id,
1021 const std::string& pref_path) {
1022 const base::DictionaryValue* dict =
1023 profile()->GetPrefs()->GetDictionary("extensions.settings");
1024 if (dict == NULL) return false;
1025 const base::DictionaryValue* pref = NULL;
1026 if (!dict->GetDictionary(extension_id, &pref)) {
1027 return false;
1029 if (pref == NULL) {
1030 return false;
1032 bool val;
1033 if (!pref->GetBoolean(pref_path, &val)) {
1034 return false;
1036 return true;
1039 void ValidateIntegerPref(const std::string& extension_id,
1040 const std::string& pref_path,
1041 int expected_val) {
1042 std::string msg = " while checking: ";
1043 msg += extension_id;
1044 msg += " ";
1045 msg += pref_path;
1046 msg += " == ";
1047 msg += base::IntToString(expected_val);
1049 PrefService* prefs = profile()->GetPrefs();
1050 const base::DictionaryValue* dict =
1051 prefs->GetDictionary("extensions.settings");
1052 ASSERT_TRUE(dict != NULL) << msg;
1053 const base::DictionaryValue* pref = NULL;
1054 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1055 EXPECT_TRUE(pref != NULL) << msg;
1056 int val;
1057 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
1058 EXPECT_EQ(expected_val, val) << msg;
1061 void ValidateStringPref(const std::string& extension_id,
1062 const std::string& pref_path,
1063 const std::string& expected_val) {
1064 std::string msg = " while checking: ";
1065 msg += extension_id;
1066 msg += ".manifest.";
1067 msg += pref_path;
1068 msg += " == ";
1069 msg += expected_val;
1071 const base::DictionaryValue* dict =
1072 profile()->GetPrefs()->GetDictionary("extensions.settings");
1073 ASSERT_TRUE(dict != NULL) << msg;
1074 const base::DictionaryValue* pref = NULL;
1075 std::string manifest_path = extension_id + ".manifest";
1076 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
1077 EXPECT_TRUE(pref != NULL) << msg;
1078 std::string val;
1079 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
1080 EXPECT_EQ(expected_val, val) << msg;
1083 void SetPref(const std::string& extension_id,
1084 const std::string& pref_path,
1085 base::Value* value,
1086 const std::string& msg) {
1087 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1088 base::DictionaryValue* dict = update.Get();
1089 ASSERT_TRUE(dict != NULL) << msg;
1090 base::DictionaryValue* pref = NULL;
1091 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1092 EXPECT_TRUE(pref != NULL) << msg;
1093 pref->Set(pref_path, value);
1096 void SetPrefInteg(const std::string& extension_id,
1097 const std::string& pref_path,
1098 int value) {
1099 std::string msg = " while setting: ";
1100 msg += extension_id;
1101 msg += " ";
1102 msg += pref_path;
1103 msg += " = ";
1104 msg += base::IntToString(value);
1106 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1109 void SetPrefBool(const std::string& extension_id,
1110 const std::string& pref_path,
1111 bool value) {
1112 std::string msg = " while setting: ";
1113 msg += extension_id + " " + pref_path;
1114 msg += " = ";
1115 msg += (value ? "true" : "false");
1117 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1120 void ClearPref(const std::string& extension_id,
1121 const std::string& pref_path) {
1122 std::string msg = " while clearing: ";
1123 msg += extension_id + " " + pref_path;
1125 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1126 base::DictionaryValue* dict = update.Get();
1127 ASSERT_TRUE(dict != NULL) << msg;
1128 base::DictionaryValue* pref = NULL;
1129 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1130 EXPECT_TRUE(pref != NULL) << msg;
1131 pref->Remove(pref_path, NULL);
1134 void SetPrefStringSet(const std::string& extension_id,
1135 const std::string& pref_path,
1136 const std::set<std::string>& value) {
1137 std::string msg = " while setting: ";
1138 msg += extension_id + " " + pref_path;
1140 base::ListValue* list_value = new base::ListValue();
1141 for (std::set<std::string>::const_iterator iter = value.begin();
1142 iter != value.end(); ++iter)
1143 list_value->Append(new base::StringValue(*iter));
1145 SetPref(extension_id, pref_path, list_value, msg);
1148 void InitPluginService() {
1149 #if defined(ENABLE_PLUGINS)
1150 PluginService::GetInstance()->Init();
1151 #endif
1154 void InitializeEmptyExtensionServiceWithTestingPrefs() {
1155 ExtensionServiceTestBase::ExtensionServiceInitParams params =
1156 CreateDefaultInitParams();
1157 params.pref_file = base::FilePath();
1158 InitializeExtensionService(params);
1161 extensions::ManagementPolicy* GetManagementPolicy() {
1162 return ExtensionSystem::Get(browser_context())->management_policy();
1165 ExtensionSyncService* extension_sync_service() {
1166 return ExtensionSyncService::Get(profile());
1169 protected:
1170 typedef extensions::ExtensionManagementPrefUpdater<
1171 syncable_prefs::TestingPrefServiceSyncable> ManagementPrefUpdater;
1172 extensions::ExtensionList loaded_;
1173 std::string unloaded_id_;
1174 UnloadedExtensionInfo::Reason unloaded_reason_;
1175 const Extension* installed_;
1176 bool was_update_;
1177 std::string old_name_;
1178 FeatureSwitch::ScopedOverride override_external_install_prompt_;
1180 private:
1181 // Create a CrxInstaller and install the CRX file.
1182 // Instead of calling this method yourself, use InstallCRX(), which does extra
1183 // error checking.
1184 void InstallCRXInternal(const base::FilePath& crx_path) {
1185 InstallCRXInternal(crx_path, Extension::NO_FLAGS);
1188 void InstallCRXInternal(const base::FilePath& crx_path, int creation_flags) {
1189 ASSERT_TRUE(base::PathExists(crx_path))
1190 << "Path does not exist: "<< crx_path.value().c_str();
1191 scoped_refptr<CrxInstaller> installer(
1192 CrxInstaller::CreateSilent(service()));
1193 installer->set_creation_flags(creation_flags);
1194 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT))
1195 installer->set_allow_silent_install(true);
1197 content::WindowedNotificationObserver observer(
1198 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1199 content::Source<extensions::CrxInstaller>(installer.get()));
1201 installer->InstallCrx(crx_path);
1203 observer.Wait();
1206 size_t expected_extensions_count_;
1207 content::NotificationRegistrar registrar_;
1210 // Receives notifications from a PackExtensionJob, indicating either that
1211 // packing succeeded or that there was some error.
1212 class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
1213 public:
1214 PackExtensionTestClient(const base::FilePath& expected_crx_path,
1215 const base::FilePath& expected_private_key_path);
1216 void OnPackSuccess(const base::FilePath& crx_path,
1217 const base::FilePath& private_key_path) override;
1218 void OnPackFailure(const std::string& error_message,
1219 ExtensionCreator::ErrorType type) override;
1221 private:
1222 const base::FilePath expected_crx_path_;
1223 const base::FilePath expected_private_key_path_;
1224 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
1227 PackExtensionTestClient::PackExtensionTestClient(
1228 const base::FilePath& expected_crx_path,
1229 const base::FilePath& expected_private_key_path)
1230 : expected_crx_path_(expected_crx_path),
1231 expected_private_key_path_(expected_private_key_path) {}
1233 // If packing succeeded, we make sure that the package names match our
1234 // expectations.
1235 void PackExtensionTestClient::OnPackSuccess(
1236 const base::FilePath& crx_path,
1237 const base::FilePath& private_key_path) {
1238 // We got the notification and processed it; we don't expect any further tasks
1239 // to be posted to the current thread, so we should stop blocking and continue
1240 // on with the rest of the test.
1241 // This call to |Quit()| matches the call to |Run()| in the
1242 // |PackPunctuatedExtension| test.
1243 base::MessageLoop::current()->Quit();
1244 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
1245 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
1246 ASSERT_TRUE(base::PathExists(private_key_path));
1249 // The tests are designed so that we never expect to see a packing error.
1250 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1251 ExtensionCreator::ErrorType type) {
1252 if (type == ExtensionCreator::kCRXExists)
1253 FAIL() << "Packing should not fail.";
1254 else
1255 FAIL() << "Existing CRX should have been overwritten.";
1258 // Test loading good extensions from the profile directory.
1259 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1260 InitPluginService();
1261 InitializeGoodInstalledExtensionService();
1262 service()->Init();
1264 uint32 expected_num_extensions = 3u;
1265 ASSERT_EQ(expected_num_extensions, loaded_.size());
1267 EXPECT_EQ(std::string(good0), loaded_[0]->id());
1268 EXPECT_EQ(std::string("My extension 1"),
1269 loaded_[0]->name());
1270 EXPECT_EQ(std::string("The first extension that I made."),
1271 loaded_[0]->description());
1272 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
1273 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false));
1274 EXPECT_EQ(expected_num_extensions, registry()->enabled_extensions().size());
1276 ValidatePrefKeyCount(3);
1277 ValidateIntegerPref(good0, "state", Extension::ENABLED);
1278 ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
1279 ValidateIntegerPref(good1, "state", Extension::ENABLED);
1280 ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
1281 ValidateIntegerPref(good2, "state", Extension::ENABLED);
1282 ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
1284 URLPatternSet expected_patterns;
1285 AddPattern(&expected_patterns, "file:///*");
1286 AddPattern(&expected_patterns, "http://*.google.com/*");
1287 AddPattern(&expected_patterns, "https://*.google.com/*");
1288 const Extension* extension = loaded_[0].get();
1289 const extensions::UserScriptList& scripts =
1290 extensions::ContentScriptsInfo::GetContentScripts(extension);
1291 ASSERT_EQ(2u, scripts.size());
1292 EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
1293 EXPECT_EQ(2u, scripts[0].js_scripts().size());
1294 ExtensionResource resource00(extension->id(),
1295 scripts[0].js_scripts()[0].extension_root(),
1296 scripts[0].js_scripts()[0].relative_path());
1297 base::FilePath expected_path =
1298 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
1299 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
1300 ExtensionResource resource01(extension->id(),
1301 scripts[0].js_scripts()[1].extension_root(),
1302 scripts[0].js_scripts()[1].relative_path());
1303 expected_path =
1304 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
1305 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
1306 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension));
1307 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
1308 EXPECT_EQ("http://*.news.com/*",
1309 scripts[1].url_patterns().begin()->GetAsString());
1310 ExtensionResource resource10(extension->id(),
1311 scripts[1].js_scripts()[0].extension_root(),
1312 scripts[1].js_scripts()[0].relative_path());
1313 expected_path =
1314 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
1315 expected_path = base::MakeAbsoluteFilePath(expected_path);
1316 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
1318 expected_patterns.ClearPatterns();
1319 AddPattern(&expected_patterns, "http://*.google.com/*");
1320 AddPattern(&expected_patterns, "https://*.google.com/*");
1321 EXPECT_EQ(
1322 expected_patterns,
1323 extension->permissions_data()->active_permissions()->explicit_hosts());
1325 EXPECT_EQ(std::string(good1), loaded_[1]->id());
1326 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
1327 EXPECT_EQ(std::string(), loaded_[1]->description());
1328 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
1329 extensions::BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
1330 EXPECT_EQ(0u,
1331 extensions::ContentScriptsInfo::GetContentScripts(loaded_[1].get())
1332 .size());
1334 // We don't parse the plugins section on Chrome OS.
1335 #if defined(OS_CHROMEOS)
1336 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1337 #else
1338 ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1339 const std::vector<extensions::PluginInfo>* plugins =
1340 extensions::PluginInfo::GetPlugins(loaded_[1].get());
1341 ASSERT_TRUE(plugins);
1342 ASSERT_EQ(2u, plugins->size());
1343 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
1344 plugins->at(0).path.value());
1345 EXPECT_TRUE(plugins->at(0).is_public);
1346 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1347 plugins->at(1).path.value());
1348 EXPECT_FALSE(plugins->at(1).is_public);
1349 #endif
1351 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
1353 int index = expected_num_extensions - 1;
1354 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1355 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1356 EXPECT_EQ(std::string(), loaded_[index]->description());
1357 EXPECT_EQ(0u,
1358 extensions::ContentScriptsInfo::GetContentScripts(
1359 loaded_[index].get()).size());
1360 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
1363 // Test loading bad extensions from the profile directory.
1364 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
1365 // Initialize the test dir with a bad Preferences/extensions.
1366 base::FilePath source_install_dir =
1367 data_dir().AppendASCII("bad").AppendASCII("Extensions");
1368 base::FilePath pref_path =
1369 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1371 InitializeInstalledExtensionService(pref_path, source_install_dir);
1373 service()->Init();
1375 ASSERT_EQ(4u, GetErrors().size());
1376 ASSERT_EQ(0u, loaded_.size());
1378 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[0]),
1379 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1380 extensions::manifest_errors::kManifestUnreadable)) <<
1381 base::UTF16ToUTF8(GetErrors()[0]);
1383 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[1]),
1384 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1385 extensions::manifest_errors::kManifestUnreadable)) <<
1386 base::UTF16ToUTF8(GetErrors()[1]);
1388 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[2]),
1389 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1390 extensions::manifest_errors::kMissingFile)) <<
1391 base::UTF16ToUTF8(GetErrors()[2]);
1393 EXPECT_TRUE(base::MatchPattern(base::UTF16ToUTF8(GetErrors()[3]),
1394 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1395 extensions::manifest_errors::kManifestUnreadable)) <<
1396 base::UTF16ToUTF8(GetErrors()[3]);
1399 // Test various cases for delayed install because of missing imports.
1400 TEST_F(ExtensionServiceTest, PendingImports) {
1401 InitPluginService();
1403 base::FilePath source_install_dir =
1404 data_dir().AppendASCII("pending_updates_with_imports").AppendASCII(
1405 "Extensions");
1406 base::FilePath pref_path =
1407 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1409 InitializeInstalledExtensionService(pref_path, source_install_dir);
1411 // Verify there are no pending extensions initially.
1412 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions());
1414 service()->Init();
1415 // Wait for GarbageCollectExtensions task to complete.
1416 base::RunLoop().RunUntilIdle();
1418 // These extensions are used by the extensions we test below, they must be
1419 // installed.
1420 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1421 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1422 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1423 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1425 // Each of these extensions should have been rejected because of dependencies
1426 // that cannot be satisfied.
1427 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1428 EXPECT_FALSE(
1429 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1430 EXPECT_FALSE(
1431 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1432 EXPECT_FALSE(
1433 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1434 EXPECT_FALSE(
1435 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1436 EXPECT_FALSE(
1437 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
1438 EXPECT_FALSE(
1439 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
1441 // Make sure the import started for the extension with a dependency.
1442 EXPECT_TRUE(
1443 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1444 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1445 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1447 EXPECT_FALSE(base::PathExists(extensions_install_dir().AppendASCII(
1448 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
1450 EXPECT_TRUE(service()->pending_extension_manager()->HasPendingExtensions());
1451 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
1452 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
1453 // Remove it because we are not testing the pending extension manager's
1454 // ability to download and install extensions.
1455 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id));
1458 // Test installing extensions. This test tries to install few extensions using
1459 // crx files. If you need to change those crx files, feel free to repackage
1460 // them, throw away the key used and change the id's above.
1461 TEST_F(ExtensionServiceTest, InstallExtension) {
1462 InitializeEmptyExtensionService();
1464 // Extensions not enabled.
1465 service()->set_extensions_enabled(false);
1466 base::FilePath path = data_dir().AppendASCII("good.crx");
1467 InstallCRX(path, INSTALL_FAILED);
1468 service()->set_extensions_enabled(true);
1470 ValidatePrefKeyCount(0);
1472 // A simple extension that should install without error.
1473 path = data_dir().AppendASCII("good.crx");
1474 InstallCRX(path, INSTALL_NEW);
1475 // TODO(erikkay): verify the contents of the installed extension.
1477 int pref_count = 0;
1478 ValidatePrefKeyCount(++pref_count);
1479 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1480 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
1482 // An extension with page actions.
1483 path = data_dir().AppendASCII("page_action.crx");
1484 InstallCRX(path, INSTALL_NEW);
1485 ValidatePrefKeyCount(++pref_count);
1486 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1487 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
1489 // Bad signature.
1490 path = data_dir().AppendASCII("bad_signature.crx");
1491 InstallCRX(path, INSTALL_FAILED);
1492 ValidatePrefKeyCount(pref_count);
1494 // 0-length extension file.
1495 path = data_dir().AppendASCII("not_an_extension.crx");
1496 InstallCRX(path, INSTALL_FAILED);
1497 ValidatePrefKeyCount(pref_count);
1499 // Bad magic number.
1500 path = data_dir().AppendASCII("bad_magic.crx");
1501 InstallCRX(path, INSTALL_FAILED);
1502 ValidatePrefKeyCount(pref_count);
1504 // Packed extensions may have folders or files that have underscores.
1505 // This will only cause a warning, rather than a fatal error.
1506 path = data_dir().AppendASCII("bad_underscore.crx");
1507 InstallCRX(path, INSTALL_NEW);
1508 ValidatePrefKeyCount(++pref_count);
1510 // A test for an extension with a 2048-bit public key.
1511 path = data_dir().AppendASCII("good2048.crx");
1512 InstallCRX(path, INSTALL_NEW);
1513 ValidatePrefKeyCount(++pref_count);
1514 ValidateIntegerPref(good2048, "state", Extension::ENABLED);
1515 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
1517 // TODO(erikkay): add more tests for many of the failure cases.
1518 // TODO(erikkay): add tests for upgrade cases.
1521 struct MockExtensionRegistryObserver
1522 : public extensions::ExtensionRegistryObserver {
1523 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
1524 const Extension* extension,
1525 bool is_update,
1526 bool from_ephemeral,
1527 const std::string& old_name) override {
1528 last_extension_installed = extension->id();
1531 void OnExtensionUninstalled(content::BrowserContext* browser_context,
1532 const Extension* extension,
1533 extensions::UninstallReason reason) override {
1534 last_extension_uninstalled = extension->id();
1537 std::string last_extension_installed;
1538 std::string last_extension_uninstalled;
1541 // Test that correct notifications are sent to ExtensionRegistryObserver on
1542 // extension install and uninstall.
1543 TEST_F(ExtensionServiceTest, InstallObserverNotified) {
1544 InitializeEmptyExtensionService();
1546 extensions::ExtensionRegistry* registry(
1547 extensions::ExtensionRegistry::Get(profile()));
1548 MockExtensionRegistryObserver observer;
1549 registry->AddObserver(&observer);
1551 // A simple extension that should install without error.
1552 ASSERT_TRUE(observer.last_extension_installed.empty());
1553 base::FilePath path = data_dir().AppendASCII("good.crx");
1554 InstallCRX(path, INSTALL_NEW);
1555 ASSERT_EQ(good_crx, observer.last_extension_installed);
1557 // Uninstall the extension.
1558 ASSERT_TRUE(observer.last_extension_uninstalled.empty());
1559 UninstallExtension(good_crx, false);
1560 ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
1562 registry->RemoveObserver(&observer);
1565 // Tests that flags passed to OnExternalExtensionFileFound() make it to the
1566 // extension object.
1567 TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
1568 const char kPrefFromBookmark[] = "from_bookmark";
1570 InitializeEmptyExtensionService();
1572 base::FilePath path = data_dir().AppendASCII("good.crx");
1573 service()->set_extensions_enabled(true);
1575 // Register and install an external extension.
1576 Version version("1.0.0.0");
1577 content::WindowedNotificationObserver observer(
1578 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1579 content::NotificationService::AllSources());
1580 if (service()->OnExternalExtensionFileFound(
1581 good_crx,
1582 &version,
1583 path,
1584 Manifest::EXTERNAL_PREF,
1585 Extension::FROM_BOOKMARK,
1586 false /* mark_acknowledged */,
1587 false /* install_immediately */)) {
1588 observer.Wait();
1591 const Extension* extension = service()->GetExtensionById(good_crx, false);
1592 ASSERT_TRUE(extension);
1593 ASSERT_TRUE(extension->from_bookmark());
1594 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1596 // Upgrade to version 2.0, the flag should be preserved.
1597 path = data_dir().AppendASCII("good2.crx");
1598 UpdateExtension(good_crx, path, ENABLED);
1599 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1600 extension = service()->GetExtensionById(good_crx, false);
1601 ASSERT_TRUE(extension);
1602 ASSERT_TRUE(extension->from_bookmark());
1605 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1606 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
1607 InitializeEmptyExtensionService();
1609 base::FilePath path = data_dir().AppendASCII("good.crx");
1610 service()->set_extensions_enabled(true);
1612 // Install an external extension.
1613 Version version("1.0.0.0");
1614 content::WindowedNotificationObserver observer(
1615 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1616 content::NotificationService::AllSources());
1617 if (service()->OnExternalExtensionFileFound(good_crx,
1618 &version,
1619 path,
1620 Manifest::EXTERNAL_PREF,
1621 Extension::NO_FLAGS,
1622 false,
1623 false)) {
1624 observer.Wait();
1627 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1629 // Uninstall it and check that its killbit gets set.
1630 UninstallExtension(good_crx, false);
1631 ValidateIntegerPref(good_crx, "state",
1632 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1634 // Try to re-install it externally. This should fail because of the killbit.
1635 service()->OnExternalExtensionFileFound(good_crx,
1636 &version,
1637 path,
1638 Manifest::EXTERNAL_PREF,
1639 Extension::NO_FLAGS,
1640 false,
1641 false);
1642 base::RunLoop().RunUntilIdle();
1643 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1644 ValidateIntegerPref(good_crx, "state",
1645 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1647 version = Version("1.0.0.1");
1648 // Repeat the same thing with a newer version of the extension.
1649 path = data_dir().AppendASCII("good2.crx");
1650 service()->OnExternalExtensionFileFound(good_crx,
1651 &version,
1652 path,
1653 Manifest::EXTERNAL_PREF,
1654 Extension::NO_FLAGS,
1655 false,
1656 false);
1657 base::RunLoop().RunUntilIdle();
1658 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1659 ValidateIntegerPref(good_crx, "state",
1660 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1662 // Try adding the same extension from an external update URL.
1663 ASSERT_FALSE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
1664 good_crx,
1665 std::string(),
1666 GURL("http:://fake.update/url"),
1667 Manifest::EXTERNAL_PREF_DOWNLOAD,
1668 Extension::NO_FLAGS,
1669 false));
1671 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
1674 // Test that uninstalling an external extension does not crash when
1675 // the extension could not be loaded.
1676 // This extension shown in preferences file requires an experimental permission.
1677 // It could not be loaded without such permission.
1678 TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
1679 base::FilePath source_install_dir =
1680 data_dir().AppendASCII("good").AppendASCII("Extensions");
1681 // The preference contains an external extension
1682 // that requires 'experimental' permission.
1683 base::FilePath pref_path = source_install_dir
1684 .DirName()
1685 .AppendASCII("PreferencesExperimental");
1687 // Aforementioned extension will not be loaded if
1688 // there is no '--enable-experimental-extension-apis' command line flag.
1689 InitializeInstalledExtensionService(pref_path, source_install_dir);
1691 service()->Init();
1693 // Check and try to uninstall it.
1694 // If we don't check whether the extension is loaded before we uninstall it
1695 // in CheckExternalUninstall, a crash will happen here because we will get or
1696 // dereference a NULL pointer (extension) inside UninstallExtension.
1697 MockExtensionProvider provider(NULL, Manifest::EXTERNAL_REGISTRY);
1698 service()->OnExternalProviderReady(&provider);
1701 // Test that external extensions with incorrect IDs are not installed.
1702 TEST_F(ExtensionServiceTest, FailOnWrongId) {
1703 InitializeEmptyExtensionService();
1704 base::FilePath path = data_dir().AppendASCII("good.crx");
1705 service()->set_extensions_enabled(true);
1707 Version version("1.0.0.0");
1709 const std::string wrong_id = all_zero;
1710 const std::string correct_id = good_crx;
1711 ASSERT_NE(correct_id, wrong_id);
1713 // Install an external extension with an ID from the external
1714 // source that is not equal to the ID in the extension manifest.
1715 content::WindowedNotificationObserver observer(
1716 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1717 content::NotificationService::AllSources());
1718 service()->OnExternalExtensionFileFound(wrong_id,
1719 &version,
1720 path,
1721 Manifest::EXTERNAL_PREF,
1722 Extension::NO_FLAGS,
1723 false,
1724 false);
1726 observer.Wait();
1727 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1729 // Try again with the right ID. Expect success.
1730 content::WindowedNotificationObserver observer2(
1731 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1732 content::NotificationService::AllSources());
1733 if (service()->OnExternalExtensionFileFound(correct_id,
1734 &version,
1735 path,
1736 Manifest::EXTERNAL_PREF,
1737 Extension::NO_FLAGS,
1738 false,
1739 false)) {
1740 observer2.Wait();
1742 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1745 // Test that external extensions with incorrect versions are not installed.
1746 TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1747 InitializeEmptyExtensionService();
1748 base::FilePath path = data_dir().AppendASCII("good.crx");
1749 service()->set_extensions_enabled(true);
1751 // Install an external extension with a version from the external
1752 // source that is not equal to the version in the extension manifest.
1753 Version wrong_version("1.2.3.4");
1754 content::WindowedNotificationObserver observer(
1755 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1756 content::NotificationService::AllSources());
1757 service()->OnExternalExtensionFileFound(good_crx,
1758 &wrong_version,
1759 path,
1760 Manifest::EXTERNAL_PREF,
1761 Extension::NO_FLAGS,
1762 false,
1763 false);
1765 observer.Wait();
1766 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1768 // Try again with the right version. Expect success.
1769 service()->pending_extension_manager()->Remove(good_crx);
1770 Version correct_version("1.0.0.0");
1771 content::WindowedNotificationObserver observer2(
1772 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1773 content::NotificationService::AllSources());
1774 if (service()->OnExternalExtensionFileFound(good_crx,
1775 &correct_version,
1776 path,
1777 Manifest::EXTERNAL_PREF,
1778 Extension::NO_FLAGS,
1779 false,
1780 false)) {
1781 observer2.Wait();
1783 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1786 // Install a user script (they get converted automatically to an extension)
1787 TEST_F(ExtensionServiceTest, InstallUserScript) {
1788 // The details of script conversion are tested elsewhere, this just tests
1789 // integration with ExtensionService.
1790 InitializeEmptyExtensionService();
1792 base::FilePath path = data_dir().AppendASCII("user_script_basic.user.js");
1794 ASSERT_TRUE(base::PathExists(path));
1795 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1796 installer->set_allow_silent_install(true);
1797 installer->InstallUserScript(
1798 path,
1799 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1801 base::RunLoop().RunUntilIdle();
1802 std::vector<base::string16> errors = GetErrors();
1803 EXPECT_TRUE(installed_) << "Nothing was installed.";
1804 EXPECT_FALSE(was_update_) << path.value();
1805 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1806 EXPECT_EQ(0u, errors.size())
1807 << "There were errors: "
1808 << base::JoinString(errors, base::ASCIIToUTF16(","));
1809 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false))
1810 << path.value();
1812 installed_ = NULL;
1813 was_update_ = false;
1814 loaded_.clear();
1815 ExtensionErrorReporter::GetInstance()->ClearErrors();
1818 // Extensions don't install during shutdown.
1819 TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
1820 InitializeEmptyExtensionService();
1822 // Simulate shutdown.
1823 service()->set_browser_terminating_for_test(true);
1825 base::FilePath path = data_dir().AppendASCII("good.crx");
1826 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1827 installer->set_allow_silent_install(true);
1828 installer->InstallCrx(path);
1829 base::RunLoop().RunUntilIdle();
1831 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
1832 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
1835 // This tests that the granted permissions preferences are correctly set when
1836 // installing an extension.
1837 TEST_F(ExtensionServiceTest, GrantedPermissions) {
1838 InitializeEmptyExtensionService();
1839 base::FilePath path = data_dir().AppendASCII("permissions");
1841 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1842 path = path.AppendASCII("unknown");
1844 ASSERT_TRUE(base::PathExists(pem_path));
1845 ASSERT_TRUE(base::PathExists(path));
1847 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1849 APIPermissionSet expected_api_perms;
1850 URLPatternSet expected_host_perms;
1852 // Make sure there aren't any granted permissions before the
1853 // extension is installed.
1854 scoped_refptr<const PermissionSet> known_perms(
1855 prefs->GetGrantedPermissions(permissions_crx));
1856 EXPECT_FALSE(known_perms.get());
1858 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
1860 EXPECT_EQ(0u, GetErrors().size());
1861 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1862 EXPECT_EQ(permissions_crx, extension->id());
1864 // Verify that the valid API permissions have been recognized.
1865 expected_api_perms.insert(APIPermission::kTab);
1867 AddPattern(&expected_host_perms, "http://*.google.com/*");
1868 AddPattern(&expected_host_perms, "https://*.google.com/*");
1869 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
1870 AddPattern(&expected_host_perms, "http://www.example.com/*");
1872 known_perms = prefs->GetGrantedPermissions(extension->id());
1873 EXPECT_TRUE(known_perms.get());
1874 EXPECT_FALSE(known_perms->IsEmpty());
1875 EXPECT_EQ(expected_api_perms, known_perms->apis());
1876 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1877 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
1881 #if !defined(OS_CHROMEOS)
1882 // This tests that the granted permissions preferences are correctly set for
1883 // default apps.
1884 TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
1885 InitializeEmptyExtensionService();
1886 base::FilePath path = data_dir().AppendASCII("permissions");
1888 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1889 path = path.AppendASCII("unknown");
1891 ASSERT_TRUE(base::PathExists(pem_path));
1892 ASSERT_TRUE(base::PathExists(path));
1894 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1896 APIPermissionSet expected_api_perms;
1897 URLPatternSet expected_host_perms;
1899 // Make sure there aren't any granted permissions before the
1900 // extension is installed.
1901 scoped_refptr<const PermissionSet> known_perms(
1902 prefs->GetGrantedPermissions(permissions_crx));
1903 EXPECT_FALSE(known_perms.get());
1905 const Extension* extension = PackAndInstallCRX(
1906 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
1908 EXPECT_EQ(0u, GetErrors().size());
1909 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1910 EXPECT_EQ(permissions_crx, extension->id());
1912 // Verify that the valid API permissions have been recognized.
1913 expected_api_perms.insert(APIPermission::kTab);
1915 known_perms = prefs->GetGrantedPermissions(extension->id());
1916 EXPECT_TRUE(known_perms.get());
1917 EXPECT_FALSE(known_perms->IsEmpty());
1918 EXPECT_EQ(expected_api_perms, known_perms->apis());
1919 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1921 #endif
1923 #if !defined(OS_POSIX) || defined(OS_MACOSX)
1924 // Tests that the granted permissions full_access bit gets set correctly when
1925 // an extension contains an NPAPI plugin.
1926 // Only run this on platforms that support NPAPI plugins.
1927 TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
1928 InitPluginService();
1930 InitializeEmptyExtensionService();
1932 ASSERT_TRUE(base::PathExists(good1_path()));
1933 const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW);
1934 EXPECT_EQ(0u, GetErrors().size());
1935 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1936 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1938 scoped_refptr<const PermissionSet> permissions(
1939 prefs->GetGrantedPermissions(extension->id()));
1940 EXPECT_FALSE(permissions->IsEmpty());
1941 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
1942 EXPECT_FALSE(permissions->apis().empty());
1943 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
1945 // Full access implies full host access too...
1946 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
1948 #endif
1950 // Tests that the extension is disabled when permissions are missing from
1951 // the extension's granted permissions preferences. (This simulates updating
1952 // the browser to a version which recognizes more permissions).
1953 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
1954 InitializeEmptyExtensionService();
1956 base::FilePath path =
1957 data_dir().AppendASCII("permissions").AppendASCII("unknown");
1959 ASSERT_TRUE(base::PathExists(path));
1961 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
1963 EXPECT_EQ(0u, GetErrors().size());
1964 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1965 std::string extension_id = extension->id();
1967 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1969 APIPermissionSet expected_api_permissions;
1970 URLPatternSet expected_host_permissions;
1972 expected_api_permissions.insert(APIPermission::kTab);
1973 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1974 AddPattern(&expected_host_permissions, "https://*.google.com/*");
1975 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
1976 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1978 std::set<std::string> host_permissions;
1980 // Test that the extension is disabled when an API permission is missing from
1981 // the extension's granted api permissions preference. (This simulates
1982 // updating the browser to a version which recognizes a new API permission).
1983 SetPref(extension_id, "granted_permissions.api",
1984 new base::ListValue(), "granted_permissions.api");
1985 service()->ReloadExtensionsForTest();
1987 EXPECT_EQ(1u, registry()->disabled_extensions().size());
1988 extension = registry()->disabled_extensions().begin()->get();
1990 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
1991 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
1992 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1994 // Now grant and re-enable the extension, making sure the prefs are updated.
1995 service()->GrantPermissionsAndEnableExtension(extension);
1997 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
1998 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
1999 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2001 scoped_refptr<const PermissionSet> current_perms(
2002 prefs->GetGrantedPermissions(extension_id));
2003 ASSERT_TRUE(current_perms.get());
2004 ASSERT_FALSE(current_perms->IsEmpty());
2005 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2006 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2007 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2009 // Tests that the extension is disabled when a host permission is missing from
2010 // the extension's granted host permissions preference. (This simulates
2011 // updating the browser to a version which recognizes additional host
2012 // permissions).
2013 host_permissions.clear();
2014 current_perms = NULL;
2016 host_permissions.insert("http://*.google.com/*");
2017 host_permissions.insert("https://*.google.com/*");
2018 host_permissions.insert("http://*.google.com.hk/*");
2020 base::ListValue* api_permissions = new base::ListValue();
2021 api_permissions->Append(
2022 new base::StringValue("tabs"));
2023 SetPref(extension_id, "granted_permissions.api",
2024 api_permissions, "granted_permissions.api");
2025 SetPrefStringSet(
2026 extension_id, "granted_permissions.scriptable_host", host_permissions);
2028 service()->ReloadExtensionsForTest();
2030 EXPECT_EQ(1u, registry()->disabled_extensions().size());
2031 extension = registry()->disabled_extensions().begin()->get();
2033 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2034 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
2035 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2037 // Now grant and re-enable the extension, making sure the prefs are updated.
2038 service()->GrantPermissionsAndEnableExtension(extension);
2040 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
2041 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2043 current_perms = prefs->GetGrantedPermissions(extension_id);
2044 ASSERT_TRUE(current_perms.get());
2045 ASSERT_FALSE(current_perms->IsEmpty());
2046 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2047 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2048 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2051 // Test Packaging and installing an extension.
2052 TEST_F(ExtensionServiceTest, PackExtension) {
2053 InitializeEmptyExtensionService();
2054 base::FilePath input_directory =
2055 data_dir()
2056 .AppendASCII("good")
2057 .AppendASCII("Extensions")
2058 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2059 .AppendASCII("1.0.0.0");
2061 base::ScopedTempDir temp_dir;
2062 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2063 base::FilePath output_directory = temp_dir.path();
2065 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2066 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2068 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2069 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2070 privkey_path, ExtensionCreator::kNoRunFlags));
2071 ASSERT_TRUE(base::PathExists(crx_path));
2072 ASSERT_TRUE(base::PathExists(privkey_path));
2074 // Repeat the run with the pem file gone, and no special flags
2075 // Should refuse to overwrite the existing crx.
2076 base::DeleteFile(privkey_path, false);
2077 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2078 privkey_path, ExtensionCreator::kNoRunFlags));
2080 // OK, now try it with a flag to overwrite existing crx. Should work.
2081 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2082 privkey_path, ExtensionCreator::kOverwriteCRX));
2084 // Repeat the run allowing existing crx, but the existing pem is still
2085 // an error. Should fail.
2086 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2087 privkey_path, ExtensionCreator::kOverwriteCRX));
2089 ASSERT_TRUE(base::PathExists(privkey_path));
2090 InstallCRX(crx_path, INSTALL_NEW);
2092 // Try packing with invalid paths.
2093 creator.reset(new ExtensionCreator());
2094 ASSERT_FALSE(
2095 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
2096 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2098 // Try packing an empty directory. Should fail because an empty directory is
2099 // not a valid extension.
2100 base::ScopedTempDir temp_dir2;
2101 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
2102 creator.reset(new ExtensionCreator());
2103 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2104 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2106 // Try packing with an invalid manifest.
2107 std::string invalid_manifest_content = "I am not a manifest.";
2108 ASSERT_TRUE(base::WriteFile(
2109 temp_dir2.path().Append(extensions::kManifestFilename),
2110 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
2111 creator.reset(new ExtensionCreator());
2112 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2113 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2115 // Try packing with a private key that is a valid key, but invalid for the
2116 // extension.
2117 base::FilePath bad_private_key_dir =
2118 data_dir().AppendASCII("bad_private_key");
2119 crx_path = output_directory.AppendASCII("bad_private_key.crx");
2120 privkey_path = data_dir().AppendASCII("bad_private_key.pem");
2121 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
2122 privkey_path, ExtensionCreator::kOverwriteCRX));
2125 // Test Packaging and installing an extension whose name contains punctuation.
2126 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
2127 InitializeEmptyExtensionService();
2128 base::FilePath input_directory = data_dir()
2129 .AppendASCII("good")
2130 .AppendASCII("Extensions")
2131 .AppendASCII(good0)
2132 .AppendASCII("1.0.0.0");
2134 base::ScopedTempDir temp_dir;
2135 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2137 // Extension names containing punctuation, and the expected names for the
2138 // packed extensions.
2139 const base::FilePath punctuated_names[] = {
2140 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2141 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2142 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
2143 NormalizePathSeparators(),
2145 const base::FilePath expected_crx_names[] = {
2146 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2147 base::FilePath(
2148 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2149 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
2151 const base::FilePath expected_private_key_names[] = {
2152 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2153 base::FilePath(
2154 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2155 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
2158 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
2159 SCOPED_TRACE(punctuated_names[i].value().c_str());
2160 base::FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
2162 // Copy the extension into the output directory, as PackExtensionJob doesn't
2163 // let us choose where to output the packed extension.
2164 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
2166 base::FilePath expected_crx_path =
2167 temp_dir.path().Append(expected_crx_names[i]);
2168 base::FilePath expected_private_key_path =
2169 temp_dir.path().Append(expected_private_key_names[i]);
2170 PackExtensionTestClient pack_client(expected_crx_path,
2171 expected_private_key_path);
2172 scoped_refptr<extensions::PackExtensionJob> packer(
2173 new extensions::PackExtensionJob(&pack_client, output_dir,
2174 base::FilePath(),
2175 ExtensionCreator::kOverwriteCRX));
2176 packer->Start();
2178 // The packer will post a notification task to the current thread's message
2179 // loop when it is finished. We manually run the loop here so that we
2180 // block and catch the notification; otherwise, the process would exit.
2181 // This call to |Run()| is matched by a call to |Quit()| in the
2182 // |PackExtensionTestClient|'s notification handling code.
2183 base::MessageLoop::current()->Run();
2185 if (HasFatalFailure())
2186 return;
2188 InstallCRX(expected_crx_path, INSTALL_NEW);
2192 TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
2193 InitializeEmptyExtensionService();
2195 base::ScopedTempDir extension_temp_dir;
2196 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
2197 base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
2198 ASSERT_TRUE(
2199 base::CopyDirectory(data_dir()
2200 .AppendASCII("good")
2201 .AppendASCII("Extensions")
2202 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2203 .AppendASCII("1.0.0.0"),
2204 input_directory,
2205 /*recursive=*/true));
2207 base::ScopedTempDir output_temp_dir;
2208 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
2209 base::FilePath output_directory = output_temp_dir.path();
2211 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2212 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2214 // Pack the extension once to get a private key.
2215 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2216 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2217 privkey_path, ExtensionCreator::kNoRunFlags))
2218 << creator->error_message();
2219 ASSERT_TRUE(base::PathExists(crx_path));
2220 ASSERT_TRUE(base::PathExists(privkey_path));
2222 base::DeleteFile(crx_path, false);
2223 // Move the pem file into the extension.
2224 base::Move(privkey_path,
2225 input_directory.AppendASCII("privkey.pem"));
2227 // This pack should fail because of the contained private key.
2228 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2229 privkey_path, ExtensionCreator::kNoRunFlags));
2230 EXPECT_THAT(creator->error_message(),
2231 testing::ContainsRegex(
2232 "extension includes the key file.*privkey.pem"));
2235 // Test Packaging and installing an extension using an openssl generated key.
2236 // The openssl is generated with the following:
2237 // > openssl genrsa -out privkey.pem 1024
2238 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
2239 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
2240 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
2241 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
2242 InitializeEmptyExtensionService();
2243 base::FilePath input_directory =
2244 data_dir()
2245 .AppendASCII("good")
2246 .AppendASCII("Extensions")
2247 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2248 .AppendASCII("1.0.0.0");
2249 base::FilePath privkey_path(
2250 data_dir().AppendASCII("openssl_privkey_asn1.pem"));
2251 ASSERT_TRUE(base::PathExists(privkey_path));
2253 base::ScopedTempDir temp_dir;
2254 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2255 base::FilePath output_directory = temp_dir.path();
2257 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2259 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2260 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
2261 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2263 InstallCRX(crx_path, INSTALL_NEW);
2266 #if defined(THREAD_SANITIZER)
2267 // Flaky under Tsan. http://crbug.com/377702
2268 #define MAYBE_InstallTheme DISABLED_InstallTheme
2269 #else
2270 #define MAYBE_InstallTheme InstallTheme
2271 #endif
2273 TEST_F(ExtensionServiceTest, MAYBE_InstallTheme) {
2274 InitializeEmptyExtensionService();
2275 service()->Init();
2277 // A theme.
2278 base::FilePath path = data_dir().AppendASCII("theme.crx");
2279 InstallCRX(path, INSTALL_NEW);
2280 int pref_count = 0;
2281 ValidatePrefKeyCount(++pref_count);
2282 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2283 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2285 // A theme when extensions are disabled. Themes can be installed, even when
2286 // extensions are disabled.
2287 service()->set_extensions_enabled(false);
2288 path = data_dir().AppendASCII("theme2.crx");
2289 InstallCRX(path, INSTALL_NEW);
2290 ValidatePrefKeyCount(++pref_count);
2291 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
2292 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
2294 // A theme with extension elements. Themes cannot have extension elements,
2295 // so any such elements (like content scripts) should be ignored.
2296 service()->set_extensions_enabled(true);
2298 path = data_dir().AppendASCII("theme_with_extension.crx");
2299 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2300 ValidatePrefKeyCount(++pref_count);
2301 ASSERT_TRUE(extension);
2302 EXPECT_TRUE(extension->is_theme());
2303 EXPECT_EQ(
2305 extensions::ContentScriptsInfo::GetContentScripts(extension).size());
2308 // A theme with image resources missing (misspelt path).
2309 path = data_dir().AppendASCII("theme_missing_image.crx");
2310 InstallCRX(path, INSTALL_FAILED);
2311 ValidatePrefKeyCount(pref_count);
2314 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
2315 // Load.
2316 InitializeEmptyExtensionService();
2317 service()->Init();
2319 base::FilePath extension_path = data_dir().AppendASCII("theme_i18n");
2321 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2322 base::RunLoop().RunUntilIdle();
2323 EXPECT_EQ(0u, GetErrors().size());
2324 ASSERT_EQ(1u, loaded_.size());
2325 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2326 const Extension* theme = registry()->enabled_extensions().begin()->get();
2327 EXPECT_EQ("name", theme->name());
2328 EXPECT_EQ("description", theme->description());
2330 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a
2331 // temporary directory, but it automatically installs to the extension's
2332 // directory, and we don't want to copy the whole extension for a unittest.
2333 base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
2334 ASSERT_TRUE(base::PathExists(theme_file));
2335 ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive.
2338 #if defined(OS_POSIX)
2339 TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
2340 base::FilePath source_data_dir =
2341 data_dir().AppendASCII("unpacked").AppendASCII("symlinks_allowed");
2343 // Paths to test data files.
2344 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2345 ASSERT_TRUE(base::PathExists(source_manifest));
2346 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2347 ASSERT_TRUE(base::PathExists(source_icon));
2349 // Set up the temporary extension directory.
2350 base::ScopedTempDir temp;
2351 ASSERT_TRUE(temp.CreateUniqueTempDir());
2352 base::FilePath extension_path = temp.path();
2353 base::FilePath manifest = extension_path.Append(
2354 extensions::kManifestFilename);
2355 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2356 base::CopyFile(source_manifest, manifest);
2357 base::CreateSymbolicLink(source_icon, icon_symlink);
2359 // Load extension.
2360 InitializeEmptyExtensionService();
2361 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2362 base::RunLoop().RunUntilIdle();
2364 EXPECT_TRUE(GetErrors().empty());
2365 ASSERT_EQ(1u, loaded_.size());
2366 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2368 #endif
2370 TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
2371 InitializeEmptyExtensionService();
2372 base::FilePath extension_path = data_dir().AppendASCII("underscore_name");
2373 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2374 base::RunLoop().RunUntilIdle();
2375 EXPECT_EQ(1u, GetErrors().size());
2376 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2379 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
2380 InitializeEmptyExtensionService();
2381 service()->Init();
2383 base::FilePath theme_path = data_dir().AppendASCII("theme_i18n");
2385 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
2387 EXPECT_EQ(0u, GetErrors().size());
2388 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2389 EXPECT_EQ("name", theme->name());
2390 EXPECT_EQ("description", theme->description());
2393 TEST_F(ExtensionServiceTest, InstallApps) {
2394 InitializeEmptyExtensionService();
2396 // An empty app.
2397 const Extension* app =
2398 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2399 int pref_count = 0;
2400 ValidatePrefKeyCount(++pref_count);
2401 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2402 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2403 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
2405 // Another app with non-overlapping extent. Should succeed.
2406 PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2407 ValidatePrefKeyCount(++pref_count);
2409 // A third app whose extent overlaps the first. Should fail.
2410 PackAndInstallCRX(data_dir().AppendASCII("app3"), INSTALL_FAILED);
2411 ValidatePrefKeyCount(pref_count);
2414 // Tests that file access is OFF by default.
2415 TEST_F(ExtensionServiceTest, DefaultFileAccess) {
2416 InitializeEmptyExtensionService();
2417 const Extension* extension = PackAndInstallCRX(
2418 data_dir().AppendASCII("permissions").AppendASCII("files"), INSTALL_NEW);
2419 EXPECT_EQ(0u, GetErrors().size());
2420 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2421 EXPECT_FALSE(
2422 ExtensionPrefs::Get(profile())->AllowFileAccess(extension->id()));
2425 TEST_F(ExtensionServiceTest, UpdateApps) {
2426 InitializeEmptyExtensionService();
2427 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2429 // First install v1 of a hosted app.
2430 const Extension* extension =
2431 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2432 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2433 std::string id = extension->id();
2434 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2436 // Now try updating to v2.
2437 UpdateExtension(id,
2438 extensions_path.AppendASCII("v2.crx"),
2439 ENABLED);
2440 ASSERT_EQ(std::string("2"),
2441 service()->GetExtensionById(id, false)->version()->GetString());
2444 // Verifies that the NTP page and launch ordinals are kept when updating apps.
2445 TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
2446 InitializeEmptyExtensionService();
2447 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2448 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2450 // First install v1 of a hosted app.
2451 const Extension* extension =
2452 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2453 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2454 std::string id = extension->id();
2455 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2457 // Modify the ordinals so we can distinguish them from the defaults.
2458 syncer::StringOrdinal new_page_ordinal =
2459 sorting->GetPageOrdinal(id).CreateAfter();
2460 syncer::StringOrdinal new_launch_ordinal =
2461 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2463 sorting->SetPageOrdinal(id, new_page_ordinal);
2464 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2466 // Now try updating to v2.
2467 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2468 ASSERT_EQ(std::string("2"),
2469 service()->GetExtensionById(id, false)->version()->GetString());
2471 // Verify that the ordinals match.
2472 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2473 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
2476 // Ensures that the CWS has properly initialized ordinals.
2477 TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
2478 InitializeEmptyExtensionService();
2479 service()->component_loader()->Add(
2480 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
2481 service()->Init();
2483 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2484 EXPECT_TRUE(
2485 sorting->GetPageOrdinal(extensions::kWebStoreAppId).IsValid());
2486 EXPECT_TRUE(
2487 sorting->GetAppLaunchOrdinal(extensions::kWebStoreAppId).IsValid());
2490 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
2491 InitializeEmptyExtensionService();
2492 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2494 int pref_count = 0;
2496 // Install app1 with unlimited storage.
2497 const Extension* extension =
2498 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2499 ValidatePrefKeyCount(++pref_count);
2500 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2501 const std::string id1 = extension->id();
2502 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2503 APIPermission::kUnlimitedStorage));
2504 EXPECT_TRUE(extension->web_extent().MatchesURL(
2505 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2506 const GURL origin1(
2507 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2508 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2509 origin1));
2511 // Install app2 from the same origin with unlimited storage.
2512 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2513 ValidatePrefKeyCount(++pref_count);
2514 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2515 const std::string id2 = extension->id();
2516 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2517 APIPermission::kUnlimitedStorage));
2518 EXPECT_TRUE(extension->web_extent().MatchesURL(
2519 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2520 const GURL origin2(
2521 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2522 EXPECT_EQ(origin1, origin2);
2523 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2524 origin2));
2526 // Uninstall one of them, unlimited storage should still be granted
2527 // to the origin.
2528 UninstallExtension(id1, false);
2529 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2530 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2531 origin1));
2533 // Uninstall the other, unlimited storage should be revoked.
2534 UninstallExtension(id2, false);
2535 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2536 EXPECT_FALSE(
2537 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2538 origin2));
2541 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
2542 InitializeEmptyExtensionService();
2543 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2545 int pref_count = 0;
2547 const Extension* extension =
2548 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2549 ValidatePrefKeyCount(++pref_count);
2550 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2551 EXPECT_TRUE(extension->is_app());
2552 const std::string id1 = extension->id();
2553 const GURL origin1(
2554 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2555 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2556 origin1));
2558 // App 4 has a different origin (maps.google.com).
2559 extension = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
2560 ValidatePrefKeyCount(++pref_count);
2561 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2562 const std::string id2 = extension->id();
2563 const GURL origin2(
2564 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2565 ASSERT_NE(origin1, origin2);
2566 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2567 origin2));
2569 UninstallExtension(id1, false);
2570 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2572 UninstallExtension(id2, false);
2574 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2575 EXPECT_FALSE(
2576 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2577 origin1));
2578 EXPECT_FALSE(
2579 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2580 origin2));
2583 // Test that when an extension version is reinstalled, nothing happens.
2584 TEST_F(ExtensionServiceTest, Reinstall) {
2585 InitializeEmptyExtensionService();
2587 // A simple extension that should install without error.
2588 base::FilePath path = data_dir().AppendASCII("good.crx");
2589 InstallCRX(path, INSTALL_NEW);
2591 ValidatePrefKeyCount(1);
2592 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2593 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2595 // Reinstall the same version, it should overwrite the previous one.
2596 InstallCRX(path, INSTALL_UPDATED);
2598 ValidatePrefKeyCount(1);
2599 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2600 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2603 // Test that we can determine if extensions came from the
2604 // Chrome web store.
2605 TEST_F(ExtensionServiceTest, FromWebStore) {
2606 InitializeEmptyExtensionService();
2608 // A simple extension that should install without error.
2609 base::FilePath path = data_dir().AppendASCII("good.crx");
2610 // Not from web store.
2611 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2612 std::string id = extension->id();
2614 ValidatePrefKeyCount(1);
2615 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
2616 ASSERT_FALSE(extension->from_webstore());
2618 // Test install from web store.
2619 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
2621 ValidatePrefKeyCount(1);
2622 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2624 // Reload so extension gets reinitialized with new value.
2625 service()->ReloadExtensionsForTest();
2626 extension = service()->GetExtensionById(id, false);
2627 ASSERT_TRUE(extension->from_webstore());
2629 // Upgrade to version 2.0
2630 path = data_dir().AppendASCII("good2.crx");
2631 UpdateExtension(good_crx, path, ENABLED);
2632 ValidatePrefKeyCount(1);
2633 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2636 // Test upgrading a signed extension.
2637 TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
2638 InitializeEmptyExtensionService();
2640 base::FilePath path = data_dir().AppendASCII("good.crx");
2641 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2642 std::string id = extension->id();
2644 ASSERT_EQ("1.0.0.0", extension->version()->GetString());
2645 ASSERT_EQ(0u, GetErrors().size());
2647 // Upgrade to version 1.0.0.1.
2648 // Also test that the extension's old and new title are correctly retrieved.
2649 path = data_dir().AppendASCII("good2.crx");
2650 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
2651 extension = service()->GetExtensionById(id, false);
2653 ASSERT_EQ("1.0.0.1", extension->version()->GetString());
2654 ASSERT_EQ("My updated extension 1", extension->name());
2655 ASSERT_EQ(0u, GetErrors().size());
2658 // Test upgrading a signed extension with a bad signature.
2659 TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
2660 InitializeEmptyExtensionService();
2662 base::FilePath path = data_dir().AppendASCII("good.crx");
2663 InstallCRX(path, INSTALL_NEW);
2665 // Try upgrading with a bad signature. This should fail during the unpack,
2666 // because the key will not match the signature.
2667 path = data_dir().AppendASCII("bad_signature.crx");
2668 InstallCRX(path, INSTALL_FAILED);
2671 // Test a normal update via the UpdateExtension API
2672 TEST_F(ExtensionServiceTest, UpdateExtension) {
2673 InitializeEmptyExtensionService();
2675 base::FilePath path = data_dir().AppendASCII("good.crx");
2677 const Extension* good = InstallCRX(path, INSTALL_NEW);
2678 ASSERT_EQ("1.0.0.0", good->VersionString());
2679 ASSERT_EQ(good_crx, good->id());
2681 path = data_dir().AppendASCII("good2.crx");
2682 UpdateExtension(good_crx, path, ENABLED);
2683 ASSERT_EQ(
2684 "1.0.0.1",
2685 service()->GetExtensionById(good_crx, false)->version()->GetString());
2688 // Extensions should not be updated during browser shutdown.
2689 TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
2690 InitializeEmptyExtensionService();
2692 // Install an extension.
2693 base::FilePath path = data_dir().AppendASCII("good.crx");
2694 const Extension* good = InstallCRX(path, INSTALL_NEW);
2695 ASSERT_EQ(good_crx, good->id());
2697 // Simulate shutdown.
2698 service()->set_browser_terminating_for_test(true);
2700 // Update should fail and extension should not be updated.
2701 path = data_dir().AppendASCII("good2.crx");
2702 bool updated = service()->UpdateExtension(
2703 extensions::CRXFileInfo(good_crx, path), true, NULL);
2704 ASSERT_FALSE(updated);
2705 ASSERT_EQ(
2706 "1.0.0.0",
2707 service()->GetExtensionById(good_crx, false)->version()->GetString());
2710 // Test updating a not-already-installed extension - this should fail
2711 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
2712 InitializeEmptyExtensionService();
2714 base::FilePath path = data_dir().AppendASCII("good.crx");
2715 UpdateExtension(good_crx, path, UPDATED);
2716 base::RunLoop().RunUntilIdle();
2718 ASSERT_EQ(0u, registry()->enabled_extensions().size());
2719 ASSERT_FALSE(installed_);
2720 ASSERT_EQ(0u, loaded_.size());
2723 // Makes sure you can't downgrade an extension via UpdateExtension
2724 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
2725 InitializeEmptyExtensionService();
2727 base::FilePath path = data_dir().AppendASCII("good2.crx");
2729 const Extension* good = InstallCRX(path, INSTALL_NEW);
2730 ASSERT_EQ("1.0.0.1", good->VersionString());
2731 ASSERT_EQ(good_crx, good->id());
2733 // Change path from good2.crx -> good.crx
2734 path = data_dir().AppendASCII("good.crx");
2735 UpdateExtension(good_crx, path, FAILED);
2736 ASSERT_EQ(
2737 "1.0.0.1",
2738 service()->GetExtensionById(good_crx, false)->version()->GetString());
2741 // Make sure calling update with an identical version does nothing
2742 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
2743 InitializeEmptyExtensionService();
2745 base::FilePath path = data_dir().AppendASCII("good.crx");
2747 const Extension* good = InstallCRX(path, INSTALL_NEW);
2748 ASSERT_EQ(good_crx, good->id());
2749 UpdateExtension(good_crx, path, FAILED_SILENTLY);
2752 // Tests that updating an extension does not clobber old state.
2753 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
2754 InitializeEmptyExtensionService();
2756 base::FilePath path = data_dir().AppendASCII("good.crx");
2758 const Extension* good = InstallCRX(path, INSTALL_NEW);
2759 ASSERT_EQ("1.0.0.0", good->VersionString());
2760 ASSERT_EQ(good_crx, good->id());
2762 // Disable it and allow it to run in incognito. These settings should carry
2763 // over to the updated version.
2764 service()->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
2765 extensions::util::SetIsIncognitoEnabled(good->id(), profile(), true);
2767 path = data_dir().AppendASCII("good2.crx");
2768 UpdateExtension(good_crx, path, INSTALLED);
2769 ASSERT_EQ(1u, registry()->disabled_extensions().size());
2770 const Extension* good2 = service()->GetExtensionById(good_crx, true);
2771 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2772 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good2->id(), profile()));
2773 EXPECT_EQ(Extension::DISABLE_USER_ACTION,
2774 ExtensionPrefs::Get(profile())->GetDisableReasons(good2->id()));
2777 // Tests that updating preserves extension location.
2778 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
2779 InitializeEmptyExtensionService();
2781 base::FilePath path = data_dir().AppendASCII("good.crx");
2783 const Extension* good =
2784 InstallCRXWithLocation(path, Manifest::EXTERNAL_PREF, INSTALL_NEW);
2786 ASSERT_EQ("1.0.0.0", good->VersionString());
2787 ASSERT_EQ(good_crx, good->id());
2789 path = data_dir().AppendASCII("good2.crx");
2790 UpdateExtension(good_crx, path, ENABLED);
2791 const Extension* good2 = service()->GetExtensionById(good_crx, false);
2792 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2793 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
2796 // Makes sure that LOAD extension types can downgrade.
2797 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
2798 InitializeEmptyExtensionService();
2800 base::ScopedTempDir temp;
2801 ASSERT_TRUE(temp.CreateUniqueTempDir());
2803 // We'll write the extension manifest dynamically to a temporary path
2804 // to make it easier to change the version number.
2805 base::FilePath extension_path = temp.path();
2806 base::FilePath manifest_path =
2807 extension_path.Append(extensions::kManifestFilename);
2808 ASSERT_FALSE(base::PathExists(manifest_path));
2810 // Start with version 2.0.
2811 base::DictionaryValue manifest;
2812 manifest.SetString("version", "2.0");
2813 manifest.SetString("name", "LOAD Downgrade Test");
2814 manifest.SetInteger("manifest_version", 2);
2816 JSONFileValueSerializer serializer(manifest_path);
2817 ASSERT_TRUE(serializer.Serialize(manifest));
2819 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2820 base::RunLoop().RunUntilIdle();
2822 EXPECT_EQ(0u, GetErrors().size());
2823 ASSERT_EQ(1u, loaded_.size());
2824 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2825 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2826 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2828 // Now set the version number to 1.0, reload the extensions and verify that
2829 // the downgrade was accepted.
2830 manifest.SetString("version", "1.0");
2831 ASSERT_TRUE(serializer.Serialize(manifest));
2833 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2834 base::RunLoop().RunUntilIdle();
2836 EXPECT_EQ(0u, GetErrors().size());
2837 ASSERT_EQ(1u, loaded_.size());
2838 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2839 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2840 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2843 #if !defined(OS_POSIX) || defined(OS_MACOSX)
2844 // LOAD extensions with plugins require approval.
2845 // Only run this on platforms that support NPAPI plugins.
2846 TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
2847 base::FilePath extension_with_plugin_path = good1_path();
2848 base::FilePath extension_no_plugin_path = good2_path();
2850 InitPluginService();
2851 InitializeEmptyExtensionService();
2852 service()->set_show_extensions_prompts(true);
2854 // Start by canceling any install prompts.
2855 scoped_ptr<extensions::ScopedTestDialogAutoConfirm> auto_confirm(
2856 new extensions::ScopedTestDialogAutoConfirm(
2857 extensions::ScopedTestDialogAutoConfirm::CANCEL));
2859 // The extension that has a plugin should not install.
2860 extensions::UnpackedInstaller::Create(service())
2861 ->Load(extension_with_plugin_path);
2862 base::RunLoop().RunUntilIdle();
2863 EXPECT_EQ(0u, GetErrors().size());
2864 EXPECT_EQ(0u, loaded_.size());
2865 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2866 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2868 // But the extension with no plugin should since there's no prompt.
2869 ExtensionErrorReporter::GetInstance()->ClearErrors();
2870 extensions::UnpackedInstaller::Create(service())
2871 ->Load(extension_no_plugin_path);
2872 base::RunLoop().RunUntilIdle();
2873 EXPECT_EQ(0u, GetErrors().size());
2874 EXPECT_EQ(1u, loaded_.size());
2875 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2876 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2877 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2879 // The plugin extension should install if we accept the dialog.
2880 auto_confirm.reset();
2881 auto_confirm.reset(new extensions::ScopedTestDialogAutoConfirm(
2882 extensions::ScopedTestDialogAutoConfirm::ACCEPT));
2884 ExtensionErrorReporter::GetInstance()->ClearErrors();
2885 extensions::UnpackedInstaller::Create(service())
2886 ->Load(extension_with_plugin_path);
2887 base::RunLoop().RunUntilIdle();
2888 EXPECT_EQ(0u, GetErrors().size());
2889 EXPECT_EQ(2u, loaded_.size());
2890 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2891 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2892 EXPECT_TRUE(registry()->enabled_extensions().Contains(good1));
2893 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2895 // Make sure the granted permissions have been setup.
2896 scoped_refptr<const PermissionSet> permissions(
2897 ExtensionPrefs::Get(profile())->GetGrantedPermissions(good1));
2898 EXPECT_FALSE(permissions->IsEmpty());
2899 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
2900 EXPECT_FALSE(permissions->apis().empty());
2901 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
2903 // We should be able to reload the extension without getting another prompt.
2904 loaded_.clear();
2905 auto_confirm.reset();
2906 auto_confirm.reset(new extensions::ScopedTestDialogAutoConfirm(
2907 extensions::ScopedTestDialogAutoConfirm::CANCEL));
2909 service()->ReloadExtension(good1);
2910 base::RunLoop().RunUntilIdle();
2911 EXPECT_EQ(1u, loaded_.size());
2912 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2913 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2915 #endif // !defined(OS_POSIX) || defined(OS_MACOSX)
2917 namespace {
2919 bool IsExtension(const Extension* extension) {
2920 return extension->GetType() == Manifest::TYPE_EXTENSION;
2923 #if defined(ENABLE_BLACKLIST_TESTS)
2924 std::set<std::string> StringSet(const std::string& s) {
2925 std::set<std::string> set;
2926 set.insert(s);
2927 return set;
2929 std::set<std::string> StringSet(const std::string& s1, const std::string& s2) {
2930 std::set<std::string> set = StringSet(s1);
2931 set.insert(s2);
2932 return set;
2934 #endif // defined(ENABLE_BLACKLIST_TESTS)
2936 } // namespace
2938 // Test adding a pending extension.
2939 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
2940 InitializeEmptyExtensionService();
2942 const std::string kFakeId(all_zero);
2943 const GURL kFakeUpdateURL("http:://fake.update/url");
2944 const bool kFakeRemoteInstall(false);
2945 const bool kFakeInstalledByCustodian(false);
2947 EXPECT_TRUE(
2948 service()->pending_extension_manager()->AddFromSync(
2949 kFakeId,
2950 kFakeUpdateURL,
2951 base::Version(),
2952 &IsExtension,
2953 kFakeRemoteInstall,
2954 kFakeInstalledByCustodian));
2956 const extensions::PendingExtensionInfo* pending_extension_info;
2957 ASSERT_TRUE((pending_extension_info =
2958 service()->pending_extension_manager()->GetById(kFakeId)));
2959 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
2960 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
2961 // Use
2962 // EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install())
2963 // instead of
2964 // EXPECT_EQ(kFakeRemoteInstall, pending_extension_info->remote_install())
2965 // as gcc 4.7 issues the following warning on EXPECT_EQ(false, x), which is
2966 // turned into an error with -Werror=conversion-null:
2967 // converting 'false' to pointer type for argument 1 of
2968 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)'
2969 // https://code.google.com/p/googletest/issues/detail?id=458
2970 EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install());
2973 namespace {
2974 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2975 const char kGoodUpdateURL[] = "http://good.update/url";
2976 const char kGoodVersion[] = "1";
2977 const bool kGoodIsFromSync = true;
2978 const bool kGoodRemoteInstall = false;
2979 const bool kGoodInstalledByCustodian = false;
2980 } // namespace
2982 // Test installing a pending extension (this goes through
2983 // ExtensionService::UpdateExtension).
2984 TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
2985 InitializeEmptyExtensionService();
2986 EXPECT_TRUE(
2987 service()->pending_extension_manager()->AddFromSync(
2988 kGoodId,
2989 GURL(kGoodUpdateURL),
2990 base::Version(kGoodVersion),
2991 &IsExtension,
2992 kGoodRemoteInstall,
2993 kGoodInstalledByCustodian));
2994 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2996 base::FilePath path = data_dir().AppendASCII("good.crx");
2997 UpdateExtension(kGoodId, path, ENABLED);
2999 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3001 const Extension* extension = service()->GetExtensionById(kGoodId, true);
3002 EXPECT_TRUE(extension);
3005 TEST_F(ExtensionServiceTest, UpdatePendingExtensionWrongVersion) {
3006 InitializeEmptyExtensionService();
3007 base::Version other_version("0.1");
3008 ASSERT_TRUE(other_version.IsValid());
3009 ASSERT_FALSE(other_version.Equals(base::Version(kGoodVersion)));
3010 EXPECT_TRUE(
3011 service()->pending_extension_manager()->AddFromSync(
3012 kGoodId,
3013 GURL(kGoodUpdateURL),
3014 other_version,
3015 &IsExtension,
3016 kGoodRemoteInstall,
3017 kGoodInstalledByCustodian));
3018 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3020 base::FilePath path = data_dir().AppendASCII("good.crx");
3021 // After installation, the extension should be disabled, because it's missing
3022 // permissions.
3023 UpdateExtension(kGoodId, path, DISABLED);
3025 EXPECT_TRUE(
3026 ExtensionPrefs::Get(profile())->DidExtensionEscalatePermissions(kGoodId));
3028 // It should still have been installed though.
3029 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3031 const Extension* extension = service()->GetExtensionById(kGoodId, true);
3032 EXPECT_TRUE(extension);
3035 namespace {
3037 bool IsTheme(const Extension* extension) {
3038 return extension->is_theme();
3041 } // namespace
3043 // Test updating a pending theme.
3044 // Disabled due to ASAN failure. http://crbug.com/108320
3045 TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
3046 InitializeEmptyExtensionService();
3047 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3048 theme_crx, GURL(), base::Version(), &IsTheme, false, false));
3049 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3051 base::FilePath path = data_dir().AppendASCII("theme.crx");
3052 UpdateExtension(theme_crx, path, ENABLED);
3054 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3056 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3057 ASSERT_TRUE(extension);
3059 EXPECT_FALSE(
3060 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3061 EXPECT_TRUE(service()->IsExtensionEnabled(theme_crx));
3064 #if defined(OS_CHROMEOS)
3065 // Always fails on ChromeOS: http://crbug.com/79737
3066 #define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
3067 #else
3068 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
3069 #endif
3070 // Test updating a pending CRX as if the source is an external extension
3071 // with an update URL. In this case we don't know if the CRX is a theme
3072 // or not.
3073 TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
3074 InitializeEmptyExtensionService();
3075 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3076 theme_crx,
3077 std::string(),
3078 GURL(),
3079 Manifest::EXTERNAL_PREF_DOWNLOAD,
3080 Extension::NO_FLAGS,
3081 false));
3083 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3085 base::FilePath path = data_dir().AppendASCII("theme.crx");
3086 UpdateExtension(theme_crx, path, ENABLED);
3088 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3090 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3091 ASSERT_TRUE(extension);
3093 EXPECT_FALSE(
3094 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3095 EXPECT_TRUE(service()->IsExtensionEnabled(extension->id()));
3096 EXPECT_FALSE(
3097 extensions::util::IsIncognitoEnabled(extension->id(), profile()));
3100 // Test updating a pending CRX as if the source is an external extension
3101 // with an update URL. The external update should overwrite a sync update,
3102 // but a sync update should not overwrite a non-sync update.
3103 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
3104 InitializeEmptyExtensionService();
3106 // Add a crx to be installed from the update mechanism.
3107 EXPECT_TRUE(
3108 service()->pending_extension_manager()->AddFromSync(
3109 kGoodId,
3110 GURL(kGoodUpdateURL),
3111 base::Version(),
3112 &IsExtension,
3113 kGoodRemoteInstall,
3114 kGoodInstalledByCustodian));
3116 // Check that there is a pending crx, with is_from_sync set to true.
3117 const extensions::PendingExtensionInfo* pending_extension_info;
3118 ASSERT_TRUE((pending_extension_info =
3119 service()->pending_extension_manager()->GetById(kGoodId)));
3120 EXPECT_TRUE(pending_extension_info->is_from_sync());
3122 // Add a crx to be updated, with the same ID, from a non-sync source.
3123 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3124 kGoodId,
3125 std::string(),
3126 GURL(kGoodUpdateURL),
3127 Manifest::EXTERNAL_PREF_DOWNLOAD,
3128 Extension::NO_FLAGS,
3129 false));
3131 // Check that there is a pending crx, with is_from_sync set to false.
3132 ASSERT_TRUE((pending_extension_info =
3133 service()->pending_extension_manager()->GetById(kGoodId)));
3134 EXPECT_FALSE(pending_extension_info->is_from_sync());
3135 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3136 pending_extension_info->install_source());
3138 // Add a crx to be installed from the update mechanism.
3139 EXPECT_FALSE(
3140 service()->pending_extension_manager()->AddFromSync(
3141 kGoodId,
3142 GURL(kGoodUpdateURL),
3143 base::Version(),
3144 &IsExtension,
3145 kGoodRemoteInstall,
3146 kGoodInstalledByCustodian));
3148 // Check that the external, non-sync update was not overridden.
3149 ASSERT_TRUE((pending_extension_info =
3150 service()->pending_extension_manager()->GetById(kGoodId)));
3151 EXPECT_FALSE(pending_extension_info->is_from_sync());
3152 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3153 pending_extension_info->install_source());
3156 // Updating a theme should fail if the updater is explicitly told that
3157 // the CRX is not a theme.
3158 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
3159 InitializeEmptyExtensionService();
3160 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3161 theme_crx, GURL(), base::Version(), &IsExtension, false, false));
3163 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3165 base::FilePath path = data_dir().AppendASCII("theme.crx");
3166 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
3168 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3170 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3171 ASSERT_FALSE(extension);
3174 // TODO(akalin): Test updating a pending extension non-silently once
3175 // we can mock out ExtensionInstallUI and inject our version into
3176 // UpdateExtension().
3178 // Test updating a pending extension which fails the should-install test.
3179 TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
3180 InitializeEmptyExtensionService();
3181 // Add pending extension with a flipped is_theme.
3182 EXPECT_TRUE(
3183 service()->pending_extension_manager()->AddFromSync(
3184 kGoodId,
3185 GURL(kGoodUpdateURL),
3186 base::Version(),
3187 &IsTheme,
3188 kGoodRemoteInstall,
3189 kGoodInstalledByCustodian));
3190 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3192 base::FilePath path = data_dir().AppendASCII("good.crx");
3193 UpdateExtension(kGoodId, path, UPDATED);
3195 // TODO(akalin): Figure out how to check that the extensions
3196 // directory is cleaned up properly in OnExtensionInstalled().
3198 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3201 // TODO(akalin): Figure out how to test that installs of pending
3202 // unsyncable extensions are blocked.
3204 // Test updating a pending extension for one that is not pending.
3205 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
3206 InitializeEmptyExtensionService();
3208 base::FilePath path = data_dir().AppendASCII("good.crx");
3209 UpdateExtension(kGoodId, path, UPDATED);
3211 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3214 // Test updating a pending extension for one that is already
3215 // installed.
3216 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
3217 InitializeEmptyExtensionService();
3219 base::FilePath path = data_dir().AppendASCII("good.crx");
3220 const Extension* good = InstallCRX(path, INSTALL_NEW);
3221 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3223 EXPECT_FALSE(good->is_theme());
3225 // Use AddExtensionImpl() as AddFrom*() would balk.
3226 service()->pending_extension_manager()->AddExtensionImpl(
3227 good->id(),
3228 std::string(),
3229 extensions::ManifestURL::GetUpdateURL(good),
3230 Version(),
3231 &IsExtension,
3232 kGoodIsFromSync,
3233 Manifest::INTERNAL,
3234 Extension::NO_FLAGS,
3235 false,
3236 kGoodRemoteInstall);
3237 UpdateExtension(good->id(), path, ENABLED);
3239 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3242 #if defined(ENABLE_BLACKLIST_TESTS)
3243 // Tests blacklisting then unblacklisting extensions after the service has been
3244 // initialized.
3245 TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
3246 extensions::TestBlacklist test_blacklist;
3247 // A profile with 3 extensions installed: good0, good1, and good2.
3248 InitializeGoodInstalledExtensionService();
3249 test_blacklist.Attach(service()->blacklist_);
3250 service()->Init();
3252 const extensions::ExtensionSet& enabled_extensions =
3253 registry()->enabled_extensions();
3254 const extensions::ExtensionSet& blacklisted_extensions =
3255 registry()->blacklisted_extensions();
3257 EXPECT_TRUE(enabled_extensions.Contains(good0) &&
3258 !blacklisted_extensions.Contains(good0));
3259 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3260 !blacklisted_extensions.Contains(good1));
3261 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3262 !blacklisted_extensions.Contains(good2));
3264 EXPECT_FALSE(IsPrefExist(good0, "blacklist"));
3265 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3266 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3267 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3269 // Blacklist good0 and good1 (and an invalid extension ID).
3270 test_blacklist.SetBlacklistState(
3271 good0, extensions::BLACKLISTED_MALWARE, true);
3272 test_blacklist.SetBlacklistState(
3273 good1, extensions::BLACKLISTED_MALWARE, true);
3274 test_blacklist.SetBlacklistState(
3275 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3276 base::RunLoop().RunUntilIdle();
3278 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3279 blacklisted_extensions.Contains(good0));
3280 EXPECT_TRUE(!enabled_extensions.Contains(good1) &&
3281 blacklisted_extensions.Contains(good1));
3282 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3283 !blacklisted_extensions.Contains(good2));
3285 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3286 EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true));
3287 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3288 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3290 // Un-blacklist good1 and blacklist good2.
3291 test_blacklist.Clear(false);
3292 test_blacklist.SetBlacklistState(
3293 good0, extensions::BLACKLISTED_MALWARE, true);
3294 test_blacklist.SetBlacklistState(
3295 good2, extensions::BLACKLISTED_MALWARE, true);
3296 test_blacklist.SetBlacklistState(
3297 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3298 base::RunLoop().RunUntilIdle();
3300 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3301 blacklisted_extensions.Contains(good0));
3302 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3303 !blacklisted_extensions.Contains(good1));
3304 EXPECT_TRUE(!enabled_extensions.Contains(good2) &&
3305 blacklisted_extensions.Contains(good2));
3307 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3308 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3309 EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true));
3310 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3312 #endif // defined(ENABLE_BLACKLIST_TESTS)
3314 #if defined(ENABLE_BLACKLIST_TESTS)
3315 // Tests trying to install a blacklisted extension.
3316 TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
3317 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3318 new FakeSafeBrowsingDatabaseManager(true));
3319 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3321 InitializeEmptyExtensionService();
3322 service()->Init();
3324 // After blacklisting good_crx, we cannot install it.
3325 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
3326 base::RunLoop().RunUntilIdle();
3328 base::FilePath path = data_dir().AppendASCII("good.crx");
3329 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3330 // decide to install this silently. Somebody should fix these tests, all
3331 // 6,000 lines of them. Hah!
3332 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
3333 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3335 #endif // defined(ENABLE_BLACKLIST_TESTS)
3337 #if defined(ENABLE_BLACKLIST_TESTS)
3338 // Unload blacklisted extension on policy change.
3339 TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
3340 extensions::TestBlacklist test_blacklist;
3342 // A profile with no extensions installed.
3343 InitializeEmptyExtensionServiceWithTestingPrefs();
3344 test_blacklist.Attach(service()->blacklist_);
3346 base::FilePath path = data_dir().AppendASCII("good.crx");
3348 const Extension* good = InstallCRX(path, INSTALL_NEW);
3349 EXPECT_EQ(good_crx, good->id());
3350 UpdateExtension(good_crx, path, FAILED_SILENTLY);
3351 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3354 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3355 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3358 test_blacklist.SetBlacklistState(
3359 good_crx, extensions::BLACKLISTED_MALWARE, true);
3360 base::RunLoop().RunUntilIdle();
3362 // The good_crx is blacklisted and the whitelist doesn't negate it.
3363 ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true));
3364 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3366 #endif // defined(ENABLE_BLACKLIST_TESTS)
3368 #if defined(ENABLE_BLACKLIST_TESTS)
3369 // Tests that a blacklisted extension is eventually unloaded on startup, if it
3370 // wasn't already.
3371 TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
3372 extensions::TestBlacklist test_blacklist;
3374 // A profile with 3 extensions installed: good0, good1, and good2.
3375 InitializeGoodInstalledExtensionService();
3376 test_blacklist.Attach(service()->blacklist_);
3378 // Blacklist good1 before the service initializes.
3379 test_blacklist.SetBlacklistState(
3380 good1, extensions::BLACKLISTED_MALWARE, false);
3382 // Load extensions.
3383 service()->Init();
3384 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet
3386 base::RunLoop().RunUntilIdle();
3388 ASSERT_EQ(1u, registry()->blacklisted_extensions().size());
3389 ASSERT_EQ(2u, registry()->enabled_extensions().size());
3391 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
3392 ASSERT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3393 ASSERT_TRUE(registry()->enabled_extensions().Contains(good2));
3395 #endif // defined(ENABLE_BLACKLIST_TESTS)
3397 #if defined(ENABLE_BLACKLIST_TESTS)
3398 // Tests extensions blacklisted in prefs on startup; one still blacklisted by
3399 // safe browsing, the other not. The not-blacklisted one should recover.
3400 TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) {
3401 extensions::TestBlacklist test_blacklist;
3403 InitializeGoodInstalledExtensionService();
3404 test_blacklist.Attach(service()->blacklist_);
3405 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good0, true);
3406 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good1, true);
3408 test_blacklist.SetBlacklistState(
3409 good1, extensions::BLACKLISTED_MALWARE, false);
3411 // Extension service hasn't loaded yet, but IsExtensionEnabled reads out of
3412 // prefs. Ensure it takes into account the blacklist state (crbug.com/373842).
3413 EXPECT_FALSE(service()->IsExtensionEnabled(good0));
3414 EXPECT_FALSE(service()->IsExtensionEnabled(good1));
3415 EXPECT_TRUE(service()->IsExtensionEnabled(good2));
3417 service()->Init();
3419 EXPECT_EQ(2u, registry()->blacklisted_extensions().size());
3420 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3422 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good0));
3423 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3424 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3426 // Give time for the blacklist to update.
3427 base::RunLoop().RunUntilIdle();
3429 EXPECT_EQ(1u, registry()->blacklisted_extensions().size());
3430 EXPECT_EQ(2u, registry()->enabled_extensions().size());
3432 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3433 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3434 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3436 #endif // defined(ENABLE_BLACKLIST_TESTS)
3438 #if defined(ENABLE_BLACKLIST_TESTS)
3439 // Extension is added to blacklist with BLACKLISTED_POTENTIALLY_UNWANTED state
3440 // after it is installed. It is then successfully re-enabled by the user.
3441 TEST_F(ExtensionServiceTest, GreylistedExtensionDisabled) {
3442 extensions::TestBlacklist test_blacklist;
3443 // A profile with 3 extensions installed: good0, good1, and good2.
3444 InitializeGoodInstalledExtensionService();
3445 test_blacklist.Attach(service()->blacklist_);
3446 service()->Init();
3448 const extensions::ExtensionSet& enabled_extensions =
3449 registry()->enabled_extensions();
3450 const extensions::ExtensionSet& disabled_extensions =
3451 registry()->disabled_extensions();
3453 EXPECT_TRUE(enabled_extensions.Contains(good0));
3454 EXPECT_TRUE(enabled_extensions.Contains(good1));
3455 EXPECT_TRUE(enabled_extensions.Contains(good2));
3457 // Blacklist good0 and good1 (and an invalid extension ID).
3458 test_blacklist.SetBlacklistState(
3459 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3460 test_blacklist.SetBlacklistState(
3461 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3462 test_blacklist.SetBlacklistState(
3463 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3464 base::RunLoop().RunUntilIdle();
3466 EXPECT_FALSE(enabled_extensions.Contains(good0));
3467 EXPECT_TRUE(disabled_extensions.Contains(good0));
3468 EXPECT_FALSE(enabled_extensions.Contains(good1));
3469 EXPECT_TRUE(disabled_extensions.Contains(good1));
3470 EXPECT_TRUE(enabled_extensions.Contains(good2));
3471 EXPECT_FALSE(disabled_extensions.Contains(good2));
3473 ValidateIntegerPref(
3474 good0, "blacklist_state", extensions::BLACKLISTED_CWS_POLICY_VIOLATION);
3475 ValidateIntegerPref(
3476 good1, "blacklist_state", extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
3478 // Now user enables good0.
3479 service()->EnableExtension(good0);
3481 EXPECT_TRUE(enabled_extensions.Contains(good0));
3482 EXPECT_FALSE(disabled_extensions.Contains(good0));
3483 EXPECT_FALSE(enabled_extensions.Contains(good1));
3484 EXPECT_TRUE(disabled_extensions.Contains(good1));
3486 // Remove extensions from blacklist.
3487 test_blacklist.SetBlacklistState(
3488 good0, extensions::NOT_BLACKLISTED, true);
3489 test_blacklist.SetBlacklistState(
3490 good1, extensions::NOT_BLACKLISTED, true);
3491 base::RunLoop().RunUntilIdle();
3493 // All extensions are enabled.
3494 EXPECT_TRUE(enabled_extensions.Contains(good0));
3495 EXPECT_FALSE(disabled_extensions.Contains(good0));
3496 EXPECT_TRUE(enabled_extensions.Contains(good1));
3497 EXPECT_FALSE(disabled_extensions.Contains(good1));
3498 EXPECT_TRUE(enabled_extensions.Contains(good2));
3499 EXPECT_FALSE(disabled_extensions.Contains(good2));
3501 #endif // defined(ENABLE_BLACKLIST_TESTS)
3503 #if defined(ENABLE_BLACKLIST_TESTS)
3504 // When extension is removed from greylist, do not re-enable it if it is
3505 // disabled by user.
3506 TEST_F(ExtensionServiceTest, GreylistDontEnableManuallyDisabled) {
3507 extensions::TestBlacklist test_blacklist;
3508 // A profile with 3 extensions installed: good0, good1, and good2.
3509 InitializeGoodInstalledExtensionService();
3510 test_blacklist.Attach(service()->blacklist_);
3511 service()->Init();
3513 const extensions::ExtensionSet& enabled_extensions =
3514 registry()->enabled_extensions();
3515 const extensions::ExtensionSet& disabled_extensions =
3516 registry()->disabled_extensions();
3518 // Manually disable.
3519 service()->DisableExtension(good0,
3520 extensions::Extension::DISABLE_USER_ACTION);
3522 test_blacklist.SetBlacklistState(
3523 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3524 test_blacklist.SetBlacklistState(
3525 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3526 test_blacklist.SetBlacklistState(
3527 good2, extensions::BLACKLISTED_SECURITY_VULNERABILITY, true);
3528 base::RunLoop().RunUntilIdle();
3530 // All extensions disabled.
3531 EXPECT_FALSE(enabled_extensions.Contains(good0));
3532 EXPECT_TRUE(disabled_extensions.Contains(good0));
3533 EXPECT_FALSE(enabled_extensions.Contains(good1));
3534 EXPECT_TRUE(disabled_extensions.Contains(good1));
3535 EXPECT_FALSE(enabled_extensions.Contains(good2));
3536 EXPECT_TRUE(disabled_extensions.Contains(good2));
3538 // Greylisted extension can be enabled.
3539 service()->EnableExtension(good1);
3540 EXPECT_TRUE(enabled_extensions.Contains(good1));
3541 EXPECT_FALSE(disabled_extensions.Contains(good1));
3543 // good1 is now manually disabled.
3544 service()->DisableExtension(good1,
3545 extensions::Extension::DISABLE_USER_ACTION);
3546 EXPECT_FALSE(enabled_extensions.Contains(good1));
3547 EXPECT_TRUE(disabled_extensions.Contains(good1));
3549 // Remove extensions from blacklist.
3550 test_blacklist.SetBlacklistState(
3551 good0, extensions::NOT_BLACKLISTED, true);
3552 test_blacklist.SetBlacklistState(
3553 good1, extensions::NOT_BLACKLISTED, true);
3554 test_blacklist.SetBlacklistState(
3555 good2, extensions::NOT_BLACKLISTED, true);
3556 base::RunLoop().RunUntilIdle();
3558 // good0 and good1 remain disabled.
3559 EXPECT_FALSE(enabled_extensions.Contains(good0));
3560 EXPECT_TRUE(disabled_extensions.Contains(good0));
3561 EXPECT_FALSE(enabled_extensions.Contains(good1));
3562 EXPECT_TRUE(disabled_extensions.Contains(good1));
3563 EXPECT_TRUE(enabled_extensions.Contains(good2));
3564 EXPECT_FALSE(disabled_extensions.Contains(good2));
3566 #endif // defined(ENABLE_BLACKLIST_TESTS)
3568 #if defined(ENABLE_BLACKLIST_TESTS)
3569 // Blacklisted extension with unknown state are not enabled/disabled.
3570 TEST_F(ExtensionServiceTest, GreylistUnknownDontChange) {
3571 extensions::TestBlacklist test_blacklist;
3572 // A profile with 3 extensions installed: good0, good1, and good2.
3573 InitializeGoodInstalledExtensionService();
3574 test_blacklist.Attach(service()->blacklist_);
3575 service()->Init();
3577 const extensions::ExtensionSet& enabled_extensions =
3578 registry()->enabled_extensions();
3579 const extensions::ExtensionSet& disabled_extensions =
3580 registry()->disabled_extensions();
3582 test_blacklist.SetBlacklistState(
3583 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3584 test_blacklist.SetBlacklistState(
3585 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3586 base::RunLoop().RunUntilIdle();
3588 EXPECT_FALSE(enabled_extensions.Contains(good0));
3589 EXPECT_TRUE(disabled_extensions.Contains(good0));
3590 EXPECT_FALSE(enabled_extensions.Contains(good1));
3591 EXPECT_TRUE(disabled_extensions.Contains(good1));
3592 EXPECT_TRUE(enabled_extensions.Contains(good2));
3593 EXPECT_FALSE(disabled_extensions.Contains(good2));
3595 test_blacklist.SetBlacklistState(
3596 good0, extensions::NOT_BLACKLISTED, true);
3597 test_blacklist.SetBlacklistState(
3598 good1, extensions::BLACKLISTED_UNKNOWN, true);
3599 test_blacklist.SetBlacklistState(
3600 good2, extensions::BLACKLISTED_UNKNOWN, true);
3601 base::RunLoop().RunUntilIdle();
3603 // good0 re-enabled, other remain as they were.
3604 EXPECT_TRUE(enabled_extensions.Contains(good0));
3605 EXPECT_FALSE(disabled_extensions.Contains(good0));
3606 EXPECT_FALSE(enabled_extensions.Contains(good1));
3607 EXPECT_TRUE(disabled_extensions.Contains(good1));
3608 EXPECT_TRUE(enabled_extensions.Contains(good2));
3609 EXPECT_FALSE(disabled_extensions.Contains(good2));
3612 // Tests that blacklisted extensions cannot be reloaded, both those loaded
3613 // before and after extension service startup.
3614 TEST_F(ExtensionServiceTest, ReloadBlacklistedExtension) {
3615 extensions::TestBlacklist test_blacklist;
3617 InitializeGoodInstalledExtensionService();
3618 test_blacklist.Attach(service()->blacklist_);
3620 test_blacklist.SetBlacklistState(
3621 good1, extensions::BLACKLISTED_MALWARE, false);
3622 service()->Init();
3623 test_blacklist.SetBlacklistState(
3624 good2, extensions::BLACKLISTED_MALWARE, false);
3625 base::RunLoop().RunUntilIdle();
3627 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3628 EXPECT_EQ(StringSet(good1, good2),
3629 registry()->blacklisted_extensions().GetIDs());
3631 service()->ReloadExtension(good1);
3632 service()->ReloadExtension(good2);
3633 base::RunLoop().RunUntilIdle();
3635 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3636 EXPECT_EQ(StringSet(good1, good2),
3637 registry()->blacklisted_extensions().GetIDs());
3639 #endif // defined(ENABLE_BLACKLIST_TESTS)
3641 // Tests blocking then unblocking enabled extensions after the service has been
3642 // initialized.
3643 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledExtension) {
3644 InitializeGoodInstalledExtensionService();
3645 service()->Init();
3647 AssertExtensionBlocksAndUnblocks(true, good0);
3650 // Tests blocking then unblocking disabled extensions after the service has been
3651 // initialized.
3652 TEST_F(ExtensionServiceTest, BlockAndUnblockDisabledExtension) {
3653 InitializeGoodInstalledExtensionService();
3654 service()->Init();
3656 service()->DisableExtension(good0, Extension::DISABLE_RELOAD);
3658 AssertExtensionBlocksAndUnblocks(true, good0);
3661 // Tests blocking then unblocking terminated extensions after the service has
3662 // been initialized.
3663 TEST_F(ExtensionServiceTest, BlockAndUnblockTerminatedExtension) {
3664 InitializeGoodInstalledExtensionService();
3665 service()->Init();
3667 TerminateExtension(good0);
3669 AssertExtensionBlocksAndUnblocks(true, good0);
3672 // Tests blocking then unblocking policy-forced extensions after the service has
3673 // been initialized.
3674 TEST_F(ExtensionServiceTest, BlockAndUnblockPolicyExtension) {
3675 InitializeEmptyExtensionServiceWithTestingPrefs();
3678 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3679 // // Blacklist everything.
3680 // pref.SetBlacklistedByDefault(true);
3681 // Mark good.crx for force-installation.
3682 pref.SetIndividualExtensionAutoInstalled(
3683 good_crx, "http://example.com/update_url", true);
3686 // Have policy force-install an extension.
3687 MockExtensionProvider* provider =
3688 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3689 AddMockExternalProvider(provider);
3690 provider->UpdateOrAddExtension(
3691 good_crx, "1.0.0.0", data_dir().AppendASCII("good_crx"));
3693 // Reloading extensions should find our externally registered extension
3694 // and install it.
3695 content::WindowedNotificationObserver observer(
3696 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3697 content::NotificationService::AllSources());
3698 service()->CheckForExternalUpdates();
3699 observer.Wait();
3701 AssertExtensionBlocksAndUnblocks(false, good_crx);
3705 #if defined(ENABLE_BLACKLIST_TESTS)
3706 // Tests blocking then unblocking extensions that are blacklisted both before
3707 // and after Init().
3708 TEST_F(ExtensionServiceTest, BlockAndUnblockBlacklistedExtension) {
3709 extensions::TestBlacklist test_blacklist;
3711 InitializeGoodInstalledExtensionService();
3712 test_blacklist.Attach(service()->blacklist_);
3714 test_blacklist.SetBlacklistState(
3715 good0, extensions::BLACKLISTED_MALWARE, true);
3716 base::RunLoop().RunUntilIdle();
3718 service()->Init();
3720 test_blacklist.SetBlacklistState(
3721 good1, extensions::BLACKLISTED_MALWARE, true);
3722 base::RunLoop().RunUntilIdle();
3724 // Blacklisted extensions stay blacklisted.
3725 AssertExtensionBlocksAndUnblocks(false, good0);
3726 AssertExtensionBlocksAndUnblocks(false, good1);
3728 service()->BlockAllExtensions();
3730 // Remove an extension from the blacklist while the service is blocked.
3731 test_blacklist.SetBlacklistState(
3732 good0, extensions::NOT_BLACKLISTED, true);
3733 // Add an extension to the blacklist while the service is blocked.
3734 test_blacklist.SetBlacklistState(
3735 good2, extensions::BLACKLISTED_MALWARE, true);
3736 base::RunLoop().RunUntilIdle();
3738 // Go directly to blocked, do not pass go, do not collect $200.
3739 ASSERT_TRUE(IsBlocked(good0));
3740 // Get on the blacklist - even if you were blocked!
3741 ASSERT_FALSE(IsBlocked(good2));
3743 #endif // defined(ENABLE_BLACKLIST_TESTS)
3745 // Tests blocking then unblocking enabled component extensions after the service
3746 // has been initialized.
3747 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledComponentExtension) {
3748 InitializeEmptyExtensionServiceWithTestingPrefs();
3750 // Install a component extension.
3751 base::FilePath path = data_dir()
3752 .AppendASCII("good")
3753 .AppendASCII("Extensions")
3754 .AppendASCII(good0)
3755 .AppendASCII("1.0.0.0");
3756 std::string manifest;
3757 ASSERT_TRUE(base::ReadFileToString(
3758 path.Append(extensions::kManifestFilename), &manifest));
3759 service()->component_loader()->Add(manifest, path);
3760 service()->Init();
3762 // Component extension should never block.
3763 AssertExtensionBlocksAndUnblocks(false, good0);
3766 // Tests blocking then unblocking a theme after the service has been
3767 // initialized.
3768 TEST_F(ExtensionServiceTest, BlockAndUnblockTheme) {
3769 InitializeEmptyExtensionService();
3770 service()->Init();
3772 base::FilePath path = data_dir().AppendASCII("theme.crx");
3773 InstallCRX(path, INSTALL_NEW);
3775 AssertExtensionBlocksAndUnblocks(true, theme_crx);
3778 // Tests that blocking extensions before Init() results in loading blocked
3779 // extensions.
3780 TEST_F(ExtensionServiceTest, WillNotLoadExtensionsWhenBlocked) {
3781 InitializeGoodInstalledExtensionService();
3783 service()->BlockAllExtensions();
3785 service()->Init();
3787 ASSERT_TRUE(IsBlocked(good0));
3788 ASSERT_TRUE(IsBlocked(good0));
3789 ASSERT_TRUE(IsBlocked(good0));
3792 // Tests that IsEnabledExtension won't crash on an uninstalled extension.
3793 TEST_F(ExtensionServiceTest, IsEnabledExtensionBlockedAndNotInstalled) {
3794 InitializeEmptyExtensionService();
3796 service()->BlockAllExtensions();
3798 service()->IsExtensionEnabled(theme_crx);
3801 // Will not install extension blacklisted by policy.
3802 TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
3803 InitializeEmptyExtensionServiceWithTestingPrefs();
3805 // Blacklist everything.
3807 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3808 pref.SetBlacklistedByDefault(true);
3811 // Blacklist prevents us from installing good_crx.
3812 base::FilePath path = data_dir().AppendASCII("good.crx");
3813 InstallCRX(path, INSTALL_FAILED);
3814 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3816 // Now whitelist this particular extension.
3818 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3819 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3822 // Ensure we can now install good_crx.
3823 InstallCRX(path, INSTALL_NEW);
3824 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3827 // Extension blacklisted by policy get unloaded after installing.
3828 TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
3829 InitializeEmptyExtensionServiceWithTestingPrefs();
3831 // Install good_crx.
3832 base::FilePath path = data_dir().AppendASCII("good.crx");
3833 InstallCRX(path, INSTALL_NEW);
3834 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3837 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3838 // Blacklist this extension.
3839 pref.SetIndividualExtensionInstallationAllowed(good_crx, false);
3842 // Extension should not be running now.
3843 base::RunLoop().RunUntilIdle();
3844 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3847 // Tests that component extensions are not blacklisted by policy.
3848 TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
3849 InitializeEmptyExtensionServiceWithTestingPrefs();
3851 // Blacklist everything.
3853 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3854 pref.SetBlacklistedByDefault(true);
3857 // Install a component extension.
3858 base::FilePath path = data_dir()
3859 .AppendASCII("good")
3860 .AppendASCII("Extensions")
3861 .AppendASCII(good0)
3862 .AppendASCII("1.0.0.0");
3863 std::string manifest;
3864 ASSERT_TRUE(base::ReadFileToString(
3865 path.Append(extensions::kManifestFilename), &manifest));
3866 service()->component_loader()->Add(manifest, path);
3867 service()->Init();
3869 // Extension should be installed despite blacklist.
3870 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3871 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3873 // Poke external providers and make sure the extension is still present.
3874 service()->CheckForExternalUpdates();
3875 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3876 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3878 // Extension should not be uninstalled on blacklist changes.
3880 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3881 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3883 base::RunLoop().RunUntilIdle();
3884 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3885 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3888 // Tests that policy-installed extensions are not blacklisted by policy.
3889 TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
3890 InitializeEmptyExtensionServiceWithTestingPrefs();
3893 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3894 // Blacklist everything.
3895 pref.SetBlacklistedByDefault(true);
3896 // Mark good.crx for force-installation.
3897 pref.SetIndividualExtensionAutoInstalled(
3898 good_crx, "http://example.com/update_url", true);
3901 // Have policy force-install an extension.
3902 MockExtensionProvider* provider =
3903 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3904 AddMockExternalProvider(provider);
3905 provider->UpdateOrAddExtension(
3906 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
3908 // Reloading extensions should find our externally registered extension
3909 // and install it.
3910 content::WindowedNotificationObserver observer(
3911 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3912 content::NotificationService::AllSources());
3913 service()->CheckForExternalUpdates();
3914 observer.Wait();
3916 // Extension should be installed despite blacklist.
3917 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3918 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3920 // Blacklist update should not uninstall the extension.
3922 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3923 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3925 base::RunLoop().RunUntilIdle();
3926 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3927 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3930 // Tests that extensions cannot be installed if the policy provider prohibits
3931 // it. This functionality is implemented in CrxInstaller::ConfirmInstall().
3932 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
3933 InitializeEmptyExtensionService();
3935 GetManagementPolicy()->UnregisterAllProviders();
3936 extensions::TestManagementPolicyProvider provider_(
3937 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3938 GetManagementPolicy()->RegisterProvider(&provider_);
3940 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_FAILED);
3941 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3944 // Tests that extensions cannot be loaded from prefs if the policy provider
3945 // prohibits it. This functionality is implemented in InstalledLoader::Load().
3946 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
3947 InitializeEmptyExtensionService();
3949 // Create a fake extension to be loaded as though it were read from prefs.
3950 base::FilePath path =
3951 data_dir().AppendASCII("management").AppendASCII("simple_extension");
3952 base::DictionaryValue manifest;
3953 manifest.SetString(keys::kName, "simple_extension");
3954 manifest.SetString(keys::kVersion, "1");
3955 // UNPACKED is for extensions loaded from a directory. We use it here, even
3956 // though we're testing loading from prefs, so that we don't need to provide
3957 // an extension key.
3958 extensions::ExtensionInfo extension_info(
3959 &manifest, std::string(), path, Manifest::UNPACKED);
3961 // Ensure we can load it with no management policy in place.
3962 GetManagementPolicy()->UnregisterAllProviders();
3963 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3964 extensions::InstalledLoader(service()).Load(extension_info, false);
3965 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3967 const Extension* extension =
3968 (registry()->enabled_extensions().begin())->get();
3969 EXPECT_TRUE(
3970 service()->UninstallExtension(extension->id(),
3971 extensions::UNINSTALL_REASON_FOR_TESTING,
3972 base::Bind(&base::DoNothing),
3973 NULL));
3974 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3976 // Ensure we cannot load it if management policy prohibits installation.
3977 extensions::TestManagementPolicyProvider provider_(
3978 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3979 GetManagementPolicy()->RegisterProvider(&provider_);
3981 extensions::InstalledLoader(service()).Load(extension_info, false);
3982 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3985 // Tests disabling an extension when prohibited by the ManagementPolicy.
3986 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
3987 InitializeEmptyExtensionService();
3989 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3990 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3991 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3993 GetManagementPolicy()->UnregisterAllProviders();
3994 extensions::TestManagementPolicyProvider provider(
3995 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3996 GetManagementPolicy()->RegisterProvider(&provider);
3998 // Attempt to disable it.
3999 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4001 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4002 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4003 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4006 // Tests uninstalling an extension when prohibited by the ManagementPolicy.
4007 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
4008 InitializeEmptyExtensionService();
4010 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4011 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4012 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4014 GetManagementPolicy()->UnregisterAllProviders();
4015 extensions::TestManagementPolicyProvider provider(
4016 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
4017 GetManagementPolicy()->RegisterProvider(&provider);
4019 // Attempt to uninstall it.
4020 EXPECT_FALSE(
4021 service()->UninstallExtension(good_crx,
4022 extensions::UNINSTALL_REASON_FOR_TESTING,
4023 base::Bind(&base::DoNothing),
4024 NULL));
4026 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4027 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4030 // Tests that previously installed extensions that are now prohibited from
4031 // being installed are removed.
4032 TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
4033 InitializeEmptyExtensionService();
4035 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4036 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
4037 EXPECT_EQ(2u, registry()->enabled_extensions().size());
4038 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4040 GetManagementPolicy()->UnregisterAllProviders();
4041 extensions::TestManagementPolicyProvider provider(
4042 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
4043 GetManagementPolicy()->RegisterProvider(&provider);
4045 // Run the policy check.
4046 service()->CheckManagementPolicy();
4047 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4048 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4051 // Tests that previously disabled extensions that are now required to be
4052 // enabled are re-enabled on reinstall.
4053 TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
4054 InitializeEmptyExtensionService();
4056 // Install, then disable, an extension.
4057 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4058 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4059 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4060 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4062 // Register an ExtensionManagementPolicy that requires the extension to remain
4063 // enabled.
4064 GetManagementPolicy()->UnregisterAllProviders();
4065 extensions::TestManagementPolicyProvider provider(
4066 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
4067 GetManagementPolicy()->RegisterProvider(&provider);
4069 // Reinstall the extension.
4070 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_UPDATED);
4071 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4072 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4075 // Tests that extensions disabled by management policy can be installed but
4076 // will get disabled after installing.
4077 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsEnableOnInstalled) {
4078 InitializeEmptyExtensionService();
4080 // Register an ExtensionManagementPolicy that disables all extensions, with
4081 // a specified Extension::DisableReason.
4082 GetManagementPolicy()->UnregisterAllProviders();
4083 extensions::TestManagementPolicyProvider provider(
4084 extensions::TestManagementPolicyProvider::MUST_REMAIN_DISABLED);
4085 provider.SetDisableReason(Extension::DISABLE_NOT_VERIFIED);
4086 GetManagementPolicy()->RegisterProvider(&provider);
4088 // Attempts to install an extensions, it should be installed but disabled.
4089 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4090 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4091 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_WITHOUT_LOAD);
4092 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4093 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4095 // Verifies that the disable reason is set properly.
4096 EXPECT_EQ(Extension::DISABLE_NOT_VERIFIED,
4097 service()->extension_prefs_->GetDisableReasons(kGoodId));
4100 // Tests that extensions with conflicting required permissions by enterprise
4101 // policy cannot be installed.
4102 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionNewExtensionInstall) {
4103 InitializeEmptyExtensionServiceWithTestingPrefs();
4104 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4107 // Update policy to block one of the required permissions of target.
4108 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4109 pref.AddBlockedPermission("*", "tabs");
4112 // The extension should be failed to install.
4113 PackAndInstallCRX(path, INSTALL_FAILED);
4116 // Update policy to block one of the optional permissions instead.
4117 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4118 pref.ClearBlockedPermissions("*");
4119 pref.AddBlockedPermission("*", "history");
4122 // The extension should succeed to install this time.
4123 std::string id = PackAndInstallCRX(path, INSTALL_NEW)->id();
4125 // Uninstall the extension and update policy to block some arbitrary
4126 // unknown permission.
4127 UninstallExtension(id, false);
4129 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4130 pref.ClearBlockedPermissions("*");
4131 pref.AddBlockedPermission("*", "unknown.permission.for.testing");
4134 // The extension should succeed to install as well.
4135 PackAndInstallCRX(path, INSTALL_NEW);
4138 // Tests that extension supposed to be force installed but with conflicting
4139 // required permissions cannot be installed.
4140 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionConflictsWithForceInstall) {
4141 InitializeEmptyExtensionServiceWithTestingPrefs();
4143 // Pack the crx file.
4144 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4145 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4146 base::ScopedTempDir temp_dir;
4147 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4148 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
4150 PackCRX(path, pem_path, crx_path);
4153 // Block one of the required permissions.
4154 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4155 pref.AddBlockedPermission("*", "tabs");
4158 // Use MockExtensionProvider to simulate force installing extension.
4159 MockExtensionProvider* provider =
4160 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4161 AddMockExternalProvider(provider);
4162 provider->UpdateOrAddExtension(permissions_blocklist, "1.0", crx_path);
4165 // Attempts to force install this extension.
4166 content::WindowedNotificationObserver observer(
4167 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4168 content::NotificationService::AllSources());
4169 service()->CheckForExternalUpdates();
4170 observer.Wait();
4173 // The extension should not be installed.
4174 ASSERT_FALSE(service()->GetInstalledExtension(permissions_blocklist));
4176 // Remove this extension from pending extension manager as we would like to
4177 // give another attempt later.
4178 service()->pending_extension_manager()->Remove(permissions_blocklist);
4181 // Clears the permission block list.
4182 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4183 pref.ClearBlockedPermissions("*");
4187 // Attempts to force install this extension again.
4188 content::WindowedNotificationObserver observer(
4189 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4190 content::NotificationService::AllSources());
4191 service()->CheckForExternalUpdates();
4192 observer.Wait();
4195 const Extension* installed =
4196 service()->GetInstalledExtension(permissions_blocklist);
4197 ASSERT_TRUE(installed);
4198 EXPECT_EQ(installed->location(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4201 // Tests that newer versions of an extension with conflicting required
4202 // permissions by enterprise policy cannot be updated to.
4203 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionExtensionUpdate) {
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 // Install 'permissions_blocklist'.
4211 const Extension* installed = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
4212 EXPECT_EQ(installed->id(), permissions_blocklist);
4215 // Block one of the required permissions of 'permissions_blocklist2'.
4216 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4217 pref.AddBlockedPermission("*", "downloads");
4220 // Install 'permissions_blocklist' again, should be updated.
4221 const Extension* updated = PackAndInstallCRX(path, pem_path, INSTALL_UPDATED);
4222 EXPECT_EQ(updated->id(), permissions_blocklist);
4224 std::string old_version = updated->VersionString();
4226 // Attempts to update to 'permissions_blocklist2' should fail.
4227 PackAndInstallCRX(path2, pem_path, INSTALL_FAILED);
4229 // Verify that the old version is still enabled.
4230 updated = service()->GetExtensionById(permissions_blocklist, false);
4231 ASSERT_TRUE(updated);
4232 EXPECT_EQ(old_version, updated->VersionString());
4235 // Tests that policy update with additional permissions blocked revoke
4236 // conflicting granted optional permissions and unload extensions with
4237 // conflicting required permissions, including the force installed ones.
4238 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionPolicyUpdate) {
4239 InitializeEmptyExtensionServiceWithTestingPrefs();
4241 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4242 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4243 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4245 // Pack the crx file.
4246 base::ScopedTempDir temp_dir;
4247 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4248 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
4250 PackCRX(path2, pem_path, crx_path);
4252 // Install two arbitary extensions with specified manifest.
4253 std::string ext1 = PackAndInstallCRX(path, INSTALL_NEW)->id();
4254 std::string ext2 = PackAndInstallCRX(path2, INSTALL_NEW)->id();
4255 ASSERT_NE(ext1, permissions_blocklist);
4256 ASSERT_NE(ext2, permissions_blocklist);
4257 ASSERT_NE(ext1, ext2);
4259 // Force install another extension with known id and same manifest as 'ext2'.
4260 std::string ext2_forced = permissions_blocklist;
4261 MockExtensionProvider* provider =
4262 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4263 AddMockExternalProvider(provider);
4264 provider->UpdateOrAddExtension(ext2_forced, "2.0", crx_path);
4266 content::WindowedNotificationObserver observer(
4267 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4268 content::NotificationService::AllSources());
4269 service()->CheckForExternalUpdates();
4270 observer.Wait();
4272 extensions::ExtensionRegistry* registry =
4273 extensions::ExtensionRegistry::Get(profile());
4275 // Verify all three extensions are installed and enabled.
4276 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext1));
4277 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2));
4278 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2_forced));
4280 // Grant all optional permissions to each extension.
4281 GrantAllOptionalPermissions(ext1);
4282 GrantAllOptionalPermissions(ext2);
4283 GrantAllOptionalPermissions(ext2_forced);
4285 scoped_refptr<const PermissionSet> active_permissions(
4286 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1));
4287 EXPECT_TRUE(active_permissions->HasAPIPermission(
4288 extensions::APIPermission::kDownloads));
4290 // Set policy to block 'downloads' permission.
4292 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4293 pref.AddBlockedPermission("*", "downloads");
4296 base::RunLoop().RunUntilIdle();
4298 // 'ext1' should still be enabled, but with 'downloads' permission revoked.
4299 EXPECT_TRUE(registry->enabled_extensions().GetByID(ext1));
4300 active_permissions =
4301 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1);
4302 EXPECT_FALSE(active_permissions->HasAPIPermission(
4303 extensions::APIPermission::kDownloads));
4305 // 'ext2' should be disabled because one of its required permissions is
4306 // blocked.
4307 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2));
4309 // 'ext2_forced' should be handled the same as 'ext2'
4310 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2_forced));
4313 // Flaky on windows; http://crbug.com/309833
4314 #if defined(OS_WIN)
4315 #define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
4316 #else
4317 #define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
4318 #endif
4319 TEST_F(ExtensionServiceTest, MAYBE_ExternalExtensionAutoAcknowledgement) {
4320 InitializeEmptyExtensionService();
4321 service()->set_extensions_enabled(true);
4324 // Register and install an external extension.
4325 MockExtensionProvider* provider =
4326 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
4327 AddMockExternalProvider(provider);
4328 provider->UpdateOrAddExtension(
4329 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
4332 // Have policy force-install an extension.
4333 MockExtensionProvider* provider = new MockExtensionProvider(
4334 service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4335 AddMockExternalProvider(provider);
4336 provider->UpdateOrAddExtension(
4337 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
4340 // Providers are set up. Let them run.
4341 int count = 2;
4342 content::WindowedNotificationObserver observer(
4343 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4344 base::Bind(&WaitForCountNotificationsCallback, &count));
4345 service()->CheckForExternalUpdates();
4347 observer.Wait();
4349 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4350 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4351 EXPECT_TRUE(service()->GetExtensionById(page_action, false));
4352 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4353 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
4354 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
4357 #if !defined(OS_CHROMEOS)
4358 // This tests if default apps are installed correctly.
4359 TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
4360 InitializeEmptyExtensionService();
4361 service()->set_extensions_enabled(true);
4364 std::string json_data =
4366 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
4367 " \"external_crx\": \"good.crx\","
4368 " \"external_version\": \"1.0.0.0\","
4369 " \"is_bookmark_app\": false"
4370 " }"
4371 "}";
4372 default_apps::Provider* provider = new default_apps::Provider(
4373 profile(),
4374 service(),
4375 new extensions::ExternalTestingLoader(json_data, data_dir()),
4376 Manifest::INTERNAL,
4377 Manifest::INVALID_LOCATION,
4378 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4380 AddMockExternalProvider(provider);
4383 ASSERT_EQ(0u, registry()->enabled_extensions().size());
4384 content::WindowedNotificationObserver observer(
4385 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4386 content::NotificationService::AllSources());
4387 service()->CheckForExternalUpdates();
4388 observer.Wait();
4390 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4391 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4392 const Extension* extension = service()->GetExtensionById(good_crx, false);
4393 EXPECT_TRUE(extension->from_webstore());
4394 EXPECT_TRUE(extension->was_installed_by_default());
4396 #endif
4398 // Tests disabling extensions
4399 TEST_F(ExtensionServiceTest, DisableExtension) {
4400 InitializeEmptyExtensionService();
4402 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4403 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4404 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4406 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4407 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4408 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4409 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4411 // Disable it.
4412 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4414 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4415 EXPECT_FALSE(service()->GetExtensionById(good_crx, false));
4416 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4417 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4418 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4419 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4422 TEST_F(ExtensionServiceTest, TerminateExtension) {
4423 InitializeEmptyExtensionService();
4425 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4426 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4427 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4428 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4429 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4431 TerminateExtension(good_crx);
4433 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4434 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4435 EXPECT_EQ(1u, registry()->terminated_extensions().size());
4436 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4439 TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
4440 InitializeEmptyExtensionService();
4442 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4443 TerminateExtension(good_crx);
4444 EXPECT_TRUE(registry()->GetExtensionById(
4445 good_crx, extensions::ExtensionRegistry::TERMINATED));
4447 // Disable it.
4448 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4450 EXPECT_FALSE(registry()->GetExtensionById(
4451 good_crx, extensions::ExtensionRegistry::TERMINATED));
4452 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4454 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4455 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4456 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4457 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4460 // Tests disabling all extensions (simulating --disable-extensions flag).
4461 TEST_F(ExtensionServiceTest, DisableAllExtensions) {
4462 InitializeEmptyExtensionService();
4464 base::FilePath path = data_dir().AppendASCII("good.crx");
4465 InstallCRX(path, INSTALL_NEW);
4467 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4468 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4470 // Disable extensions.
4471 service()->set_extensions_enabled(false);
4472 service()->ReloadExtensionsForTest();
4474 // There shouldn't be extensions in either list.
4475 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4476 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4478 // This shouldn't do anything when all extensions are disabled.
4479 service()->EnableExtension(good_crx);
4480 service()->ReloadExtensionsForTest();
4482 // There still shouldn't be extensions in either list.
4483 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4484 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4486 // And then re-enable the extensions.
4487 service()->set_extensions_enabled(true);
4488 service()->ReloadExtensionsForTest();
4490 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4491 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4494 // Tests reloading extensions.
4495 TEST_F(ExtensionServiceTest, ReloadExtensions) {
4496 InitializeEmptyExtensionService();
4498 // Simple extension that should install without error.
4499 base::FilePath path = data_dir().AppendASCII("good.crx");
4500 InstallCRX(path, INSTALL_NEW,
4501 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4502 const char* const extension_id = good_crx;
4503 service()->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
4505 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4506 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4508 service()->ReloadExtensionsForTest();
4510 // The creation flags should not change when reloading the extension.
4511 const Extension* extension = service()->GetExtensionById(good_crx, true);
4512 EXPECT_TRUE(extension->from_webstore());
4513 EXPECT_TRUE(extension->was_installed_by_default());
4514 EXPECT_FALSE(extension->from_bookmark());
4516 // Extension counts shouldn't change.
4517 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4518 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4520 service()->EnableExtension(extension_id);
4522 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4523 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4525 // Need to clear |loaded_| manually before reloading as the
4526 // EnableExtension() call above inserted into it and
4527 // UnloadAllExtensions() doesn't send out notifications.
4528 loaded_.clear();
4529 service()->ReloadExtensionsForTest();
4531 // Extension counts shouldn't change.
4532 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4533 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4536 // Tests reloading an extension.
4537 TEST_F(ExtensionServiceTest, ReloadExtension) {
4538 InitializeEmptyExtensionService();
4540 // Simple extension that should install without error.
4541 const char extension_id[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
4542 base::FilePath ext = data_dir()
4543 .AppendASCII("good")
4544 .AppendASCII("Extensions")
4545 .AppendASCII(extension_id)
4546 .AppendASCII("1.0.0.0");
4547 extensions::UnpackedInstaller::Create(service())->Load(ext);
4548 base::RunLoop().RunUntilIdle();
4550 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4551 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4553 service()->ReloadExtension(extension_id);
4555 // Extension should be disabled now, waiting to be reloaded.
4556 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4557 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4558 EXPECT_EQ(Extension::DISABLE_RELOAD,
4559 ExtensionPrefs::Get(profile())->GetDisableReasons(extension_id));
4561 // Reloading again should not crash.
4562 service()->ReloadExtension(extension_id);
4564 // Finish reloading
4565 base::RunLoop().RunUntilIdle();
4567 // Extension should be enabled again.
4568 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4569 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4572 TEST_F(ExtensionServiceTest, UninstallExtension) {
4573 InitializeEmptyExtensionService();
4574 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4575 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4576 UninstallExtension(good_crx, false);
4577 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4578 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4581 TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
4582 InitializeEmptyExtensionService();
4583 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4584 TerminateExtension(good_crx);
4585 UninstallExtension(good_crx, false);
4586 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4589 // Tests the uninstaller helper.
4590 TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
4591 InitializeEmptyExtensionService();
4592 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4593 UninstallExtension(good_crx, true);
4594 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4597 TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
4598 InitializeEmptyExtensionService();
4599 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4600 TerminateExtension(good_crx);
4601 UninstallExtension(good_crx, true);
4602 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4605 // An extension disabled because of unsupported requirements should re-enabled
4606 // if updated to a version with supported requirements as long as there are no
4607 // other disable reasons.
4608 TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
4609 InitializeEmptyExtensionService();
4610 BlackListWebGL();
4612 base::FilePath path = data_dir().AppendASCII("requirements");
4613 base::FilePath pem_path =
4614 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4615 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4616 pem_path,
4617 INSTALL_NEW);
4618 std::string id = extension_v1->id();
4619 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4621 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4623 PackCRX(path.AppendASCII("v2_bad_requirements"),
4624 pem_path,
4625 v2_bad_requirements_crx);
4626 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4627 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4629 base::FilePath v3_good_crx = GetTemporaryFile();
4631 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4632 UpdateExtension(id, v3_good_crx, ENABLED);
4633 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4636 // Extensions disabled through user action should stay disabled.
4637 TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
4638 InitializeEmptyExtensionService();
4639 BlackListWebGL();
4641 base::FilePath path = data_dir().AppendASCII("requirements");
4642 base::FilePath pem_path =
4643 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4644 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4645 pem_path,
4646 INSTALL_NEW);
4647 std::string id = extension_v1->id();
4648 service()->DisableExtension(id, Extension::DISABLE_USER_ACTION);
4649 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4651 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4653 PackCRX(path.AppendASCII("v2_bad_requirements"),
4654 pem_path,
4655 v2_bad_requirements_crx);
4656 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4657 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4659 base::FilePath v3_good_crx = GetTemporaryFile();
4661 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4662 UpdateExtension(id, v3_good_crx, INSTALLED);
4663 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4666 // The extension should not re-enabled because it was disabled from a
4667 // permission increase.
4668 TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
4669 InitializeEmptyExtensionService();
4670 BlackListWebGL();
4672 base::FilePath path = data_dir().AppendASCII("requirements");
4673 base::FilePath pem_path =
4674 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4675 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4676 pem_path,
4677 INSTALL_NEW);
4678 std::string id = extension_v1->id();
4679 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4681 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
4683 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
4684 pem_path,
4685 v2_bad_requirements_and_permissions_crx);
4686 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
4687 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4689 base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
4691 PackCRX(path.AppendASCII("v3_bad_permissions"),
4692 pem_path,
4693 v3_bad_permissions_crx);
4694 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
4695 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4698 // Unpacked extensions are not allowed to be installed if they have unsupported
4699 // requirements.
4700 TEST_F(ExtensionServiceTest, UnpackedRequirements) {
4701 InitializeEmptyExtensionService();
4702 BlackListWebGL();
4704 base::FilePath path =
4705 data_dir().AppendASCII("requirements").AppendASCII("v2_bad_requirements");
4706 extensions::UnpackedInstaller::Create(service())->Load(path);
4707 base::RunLoop().RunUntilIdle();
4708 EXPECT_EQ(1u, GetErrors().size());
4709 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4712 class ExtensionCookieCallback {
4713 public:
4714 ExtensionCookieCallback()
4715 : result_(false),
4716 weak_factory_(base::MessageLoop::current()) {}
4718 void SetCookieCallback(bool result) {
4719 base::ThreadTaskRunnerHandle::Get()->PostTask(
4720 FROM_HERE,
4721 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4722 result_ = result;
4725 void GetAllCookiesCallback(const net::CookieList& list) {
4726 base::ThreadTaskRunnerHandle::Get()->PostTask(
4727 FROM_HERE,
4728 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4729 list_ = list;
4731 net::CookieList list_;
4732 bool result_;
4733 base::WeakPtrFactory<base::MessageLoop> weak_factory_;
4736 // Verifies extension state is removed upon uninstall.
4737 TEST_F(ExtensionServiceTest, ClearExtensionData) {
4738 InitializeEmptyExtensionService();
4739 ExtensionCookieCallback callback;
4741 // Load a test extension.
4742 base::FilePath path = data_dir();
4743 path = path.AppendASCII("good.crx");
4744 const Extension* extension = InstallCRX(path, INSTALL_NEW);
4745 ASSERT_TRUE(extension);
4746 GURL ext_url(extension->url());
4747 std::string origin_id = storage::GetIdentifierFromOrigin(ext_url);
4749 // Set a cookie for the extension.
4750 net::CookieMonster* cookie_monster = profile()
4751 ->GetRequestContextForExtensions()
4752 ->GetURLRequestContext()
4753 ->cookie_store()
4754 ->GetCookieMonster();
4755 ASSERT_TRUE(cookie_monster);
4756 net::CookieOptions options;
4757 cookie_monster->SetCookieWithOptionsAsync(
4758 ext_url, "dummy=value", options,
4759 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4760 base::Unretained(&callback)));
4761 base::RunLoop().RunUntilIdle();
4762 EXPECT_TRUE(callback.result_);
4764 cookie_monster->GetAllCookiesForURLAsync(
4765 ext_url,
4766 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4767 base::Unretained(&callback)));
4768 base::RunLoop().RunUntilIdle();
4769 EXPECT_EQ(1U, callback.list_.size());
4771 // Open a database.
4772 storage::DatabaseTracker* db_tracker =
4773 BrowserContext::GetDefaultStoragePartition(profile())
4774 ->GetDatabaseTracker();
4775 base::string16 db_name = base::UTF8ToUTF16("db");
4776 base::string16 description = base::UTF8ToUTF16("db_description");
4777 int64 size;
4778 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4779 db_tracker->DatabaseClosed(origin_id, db_name);
4780 std::vector<storage::OriginInfo> origins;
4781 db_tracker->GetAllOriginsInfo(&origins);
4782 EXPECT_EQ(1U, origins.size());
4783 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4785 // Create local storage. We only simulate this by creating the backing files.
4786 // Note: This test depends on details of how the dom_storage library
4787 // stores data in the host file system.
4788 base::FilePath lso_dir_path =
4789 profile()->GetPath().AppendASCII("Local Storage");
4790 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4791 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4792 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4793 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4794 EXPECT_TRUE(base::PathExists(lso_file_path));
4796 // Create indexed db. Similarly, it is enough to only simulate this by
4797 // creating the directory on the disk.
4798 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4799 profile())->GetIndexedDBContext();
4800 idb_context->SetTaskRunnerForTesting(
4801 base::MessageLoop::current()->task_runner().get());
4802 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4803 EXPECT_TRUE(base::CreateDirectory(idb_path));
4804 EXPECT_TRUE(base::DirectoryExists(idb_path));
4806 // Uninstall the extension.
4807 base::RunLoop run_loop;
4808 ASSERT_TRUE(
4809 service()->UninstallExtension(good_crx,
4810 extensions::UNINSTALL_REASON_FOR_TESTING,
4811 run_loop.QuitClosure(),
4812 NULL));
4813 // The data deletion happens on the IO thread.
4814 run_loop.Run();
4816 // Check that the cookie is gone.
4817 cookie_monster->GetAllCookiesForURLAsync(
4818 ext_url,
4819 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4820 base::Unretained(&callback)));
4821 base::RunLoop().RunUntilIdle();
4822 EXPECT_EQ(0U, callback.list_.size());
4824 // The database should have vanished as well.
4825 origins.clear();
4826 db_tracker->GetAllOriginsInfo(&origins);
4827 EXPECT_EQ(0U, origins.size());
4829 // Check that the LSO file has been removed.
4830 EXPECT_FALSE(base::PathExists(lso_file_path));
4832 // Check if the indexed db has disappeared too.
4833 EXPECT_FALSE(base::DirectoryExists(idb_path));
4836 // Verifies app state is removed upon uninstall.
4837 TEST_F(ExtensionServiceTest, ClearAppData) {
4838 InitializeEmptyExtensionService();
4839 ExtensionCookieCallback callback;
4841 int pref_count = 0;
4843 // Install app1 with unlimited storage.
4844 const Extension* extension =
4845 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
4846 ValidatePrefKeyCount(++pref_count);
4847 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4848 const std::string id1 = extension->id();
4849 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4850 APIPermission::kUnlimitedStorage));
4851 const GURL origin1(
4852 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4853 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4854 origin1));
4855 std::string origin_id = storage::GetIdentifierFromOrigin(origin1);
4857 // Install app2 from the same origin with unlimited storage.
4858 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
4859 ValidatePrefKeyCount(++pref_count);
4860 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4861 const std::string id2 = extension->id();
4862 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4863 APIPermission::kUnlimitedStorage));
4864 EXPECT_TRUE(extension->web_extent().MatchesURL(
4865 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
4866 const GURL origin2(
4867 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4868 EXPECT_EQ(origin1, origin2);
4869 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4870 origin2));
4872 // Set a cookie for the extension.
4873 net::CookieMonster* cookie_monster = profile()
4874 ->GetRequestContext()
4875 ->GetURLRequestContext()
4876 ->cookie_store()
4877 ->GetCookieMonster();
4878 ASSERT_TRUE(cookie_monster);
4879 net::CookieOptions options;
4880 cookie_monster->SetCookieWithOptionsAsync(
4881 origin1, "dummy=value", options,
4882 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4883 base::Unretained(&callback)));
4884 base::RunLoop().RunUntilIdle();
4885 EXPECT_TRUE(callback.result_);
4887 cookie_monster->GetAllCookiesForURLAsync(
4888 origin1,
4889 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4890 base::Unretained(&callback)));
4891 base::RunLoop().RunUntilIdle();
4892 EXPECT_EQ(1U, callback.list_.size());
4894 // Open a database.
4895 storage::DatabaseTracker* db_tracker =
4896 BrowserContext::GetDefaultStoragePartition(profile())
4897 ->GetDatabaseTracker();
4898 base::string16 db_name = base::UTF8ToUTF16("db");
4899 base::string16 description = base::UTF8ToUTF16("db_description");
4900 int64 size;
4901 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4902 db_tracker->DatabaseClosed(origin_id, db_name);
4903 std::vector<storage::OriginInfo> origins;
4904 db_tracker->GetAllOriginsInfo(&origins);
4905 EXPECT_EQ(1U, origins.size());
4906 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4908 // Create local storage. We only simulate this by creating the backing files.
4909 // Note: This test depends on details of how the dom_storage library
4910 // stores data in the host file system.
4911 base::FilePath lso_dir_path =
4912 profile()->GetPath().AppendASCII("Local Storage");
4913 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4914 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4915 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4916 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4917 EXPECT_TRUE(base::PathExists(lso_file_path));
4919 // Create indexed db. Similarly, it is enough to only simulate this by
4920 // creating the directory on the disk.
4921 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4922 profile())->GetIndexedDBContext();
4923 idb_context->SetTaskRunnerForTesting(
4924 base::MessageLoop::current()->task_runner().get());
4925 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4926 EXPECT_TRUE(base::CreateDirectory(idb_path));
4927 EXPECT_TRUE(base::DirectoryExists(idb_path));
4929 // Uninstall one of them, unlimited storage should still be granted
4930 // to the origin.
4931 UninstallExtension(id1, false);
4932 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4933 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4934 origin1));
4936 // Check that the cookie is still there.
4937 cookie_monster->GetAllCookiesForURLAsync(
4938 origin1,
4939 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4940 base::Unretained(&callback)));
4941 base::RunLoop().RunUntilIdle();
4942 EXPECT_EQ(1U, callback.list_.size());
4944 // Now uninstall the other. Storage should be cleared for the apps.
4945 UninstallExtension(id2, false);
4946 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4947 EXPECT_FALSE(
4948 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4949 origin1));
4951 // Check that the cookie is gone.
4952 cookie_monster->GetAllCookiesForURLAsync(
4953 origin1,
4954 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4955 base::Unretained(&callback)));
4956 base::RunLoop().RunUntilIdle();
4957 EXPECT_EQ(0U, callback.list_.size());
4959 // The database should have vanished as well.
4960 origins.clear();
4961 db_tracker->GetAllOriginsInfo(&origins);
4962 EXPECT_EQ(0U, origins.size());
4964 // Check that the LSO file has been removed.
4965 EXPECT_FALSE(base::PathExists(lso_file_path));
4967 // Check if the indexed db has disappeared too.
4968 EXPECT_FALSE(base::DirectoryExists(idb_path));
4971 // Tests loading single extensions (like --load-extension)
4972 // Flaky crashes. http://crbug.com/231806
4973 TEST_F(ExtensionServiceTest, DISABLED_LoadExtension) {
4974 InitializeEmptyExtensionService();
4976 base::FilePath ext1 = data_dir()
4977 .AppendASCII("good")
4978 .AppendASCII("Extensions")
4979 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4980 .AppendASCII("1.0.0.0");
4981 extensions::UnpackedInstaller::Create(service())->Load(ext1);
4982 base::RunLoop().RunUntilIdle();
4983 EXPECT_EQ(0u, GetErrors().size());
4984 ASSERT_EQ(1u, loaded_.size());
4985 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
4986 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4988 ValidatePrefKeyCount(1);
4990 base::FilePath no_manifest =
4991 data_dir()
4992 .AppendASCII("bad")
4993 // .AppendASCII("Extensions")
4994 .AppendASCII("cccccccccccccccccccccccccccccccc")
4995 .AppendASCII("1");
4996 extensions::UnpackedInstaller::Create(service())->Load(no_manifest);
4997 base::RunLoop().RunUntilIdle();
4998 EXPECT_EQ(1u, GetErrors().size());
4999 ASSERT_EQ(1u, loaded_.size());
5000 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5002 // Test uninstall.
5003 std::string id = loaded_[0]->id();
5004 EXPECT_FALSE(unloaded_id_.length());
5005 service()->UninstallExtension(id,
5006 extensions::UNINSTALL_REASON_FOR_TESTING,
5007 base::Bind(&base::DoNothing),
5008 NULL);
5009 base::RunLoop().RunUntilIdle();
5010 EXPECT_EQ(id, unloaded_id_);
5011 ASSERT_EQ(0u, loaded_.size());
5012 EXPECT_EQ(0u, registry()->enabled_extensions().size());
5015 // Tests that we generate IDs when they are not specified in the manifest for
5016 // --load-extension.
5017 TEST_F(ExtensionServiceTest, GenerateID) {
5018 InitializeEmptyExtensionService();
5020 base::FilePath no_id_ext = data_dir().AppendASCII("no_id");
5021 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
5022 base::RunLoop().RunUntilIdle();
5023 EXPECT_EQ(0u, GetErrors().size());
5024 ASSERT_EQ(1u, loaded_.size());
5025 ASSERT_TRUE(crx_file::id_util::IdIsValid(loaded_[0]->id()));
5026 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
5028 ValidatePrefKeyCount(1);
5030 std::string previous_id = loaded_[0]->id();
5032 // If we reload the same path, we should get the same extension ID.
5033 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
5034 base::RunLoop().RunUntilIdle();
5035 ASSERT_EQ(1u, loaded_.size());
5036 ASSERT_EQ(previous_id, loaded_[0]->id());
5039 TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
5040 InitializeEmptyExtensionService();
5042 base::FilePath bad_locale =
5043 data_dir().AppendASCII("unpacked").AppendASCII("bad_messages_file");
5044 extensions::UnpackedInstaller::Create(service())->Load(bad_locale);
5045 base::RunLoop().RunUntilIdle();
5046 EXPECT_EQ(1u, GetErrors().size());
5047 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
5048 .AppendASCII("ms")
5049 .AppendASCII("messages.json");
5050 EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
5051 testing::HasSubstr(
5052 base::UTF16ToUTF8(ms_messages_file.LossyDisplayName())),
5053 testing::HasSubstr("Dictionary keys must be quoted.")));
5054 ASSERT_EQ(0u, loaded_.size());
5057 void ExtensionServiceTest::TestExternalProvider(
5058 MockExtensionProvider* provider, Manifest::Location location) {
5059 // Verify that starting with no providers loads no extensions.
5060 service()->Init();
5061 ASSERT_EQ(0u, loaded_.size());
5063 provider->set_visit_count(0);
5065 // Register a test extension externally using the mock registry provider.
5066 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5068 // Add the extension.
5069 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5071 // Reloading extensions should find our externally registered extension
5072 // and install it.
5073 content::WindowedNotificationObserver observer(
5074 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5075 content::NotificationService::AllSources());
5076 service()->CheckForExternalUpdates();
5077 observer.Wait();
5079 ASSERT_EQ(0u, GetErrors().size());
5080 ASSERT_EQ(1u, loaded_.size());
5081 ASSERT_EQ(location, loaded_[0]->location());
5082 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
5083 ValidatePrefKeyCount(1);
5084 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5085 ValidateIntegerPref(good_crx, "location", location);
5087 // Reload extensions without changing anything. The extension should be
5088 // loaded again.
5089 loaded_.clear();
5090 service()->ReloadExtensionsForTest();
5091 base::RunLoop().RunUntilIdle();
5092 ASSERT_EQ(0u, GetErrors().size());
5093 ASSERT_EQ(1u, loaded_.size());
5094 ValidatePrefKeyCount(1);
5095 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5096 ValidateIntegerPref(good_crx, "location", location);
5098 // Now update the extension with a new version. We should get upgraded.
5099 source_path = source_path.DirName().AppendASCII("good2.crx");
5100 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5102 loaded_.clear();
5103 content::WindowedNotificationObserver observer_2(
5104 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5105 content::NotificationService::AllSources());
5106 service()->CheckForExternalUpdates();
5107 observer_2.Wait();
5108 ASSERT_EQ(0u, GetErrors().size());
5109 ASSERT_EQ(1u, loaded_.size());
5110 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
5111 ValidatePrefKeyCount(1);
5112 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5113 ValidateIntegerPref(good_crx, "location", location);
5115 // Uninstall the extension and reload. Nothing should happen because the
5116 // preference should prevent us from reinstalling.
5117 std::string id = loaded_[0]->id();
5118 bool no_uninstall =
5119 GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL);
5120 service()->UninstallExtension(id,
5121 extensions::UNINSTALL_REASON_FOR_TESTING,
5122 base::Bind(&base::DoNothing),
5123 NULL);
5124 base::RunLoop().RunUntilIdle();
5126 base::FilePath install_path = extensions_install_dir().AppendASCII(id);
5127 if (no_uninstall) {
5128 // Policy controlled extensions should not have been touched by uninstall.
5129 ASSERT_TRUE(base::PathExists(install_path));
5130 } else {
5131 // The extension should also be gone from the install directory.
5132 ASSERT_FALSE(base::PathExists(install_path));
5133 loaded_.clear();
5134 service()->CheckForExternalUpdates();
5135 base::RunLoop().RunUntilIdle();
5136 ASSERT_EQ(0u, loaded_.size());
5137 ValidatePrefKeyCount(1);
5138 ValidateIntegerPref(good_crx, "state",
5139 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
5140 ValidateIntegerPref(good_crx, "location", location);
5142 // Now clear the preference and reinstall.
5143 SetPrefInteg(good_crx, "state", Extension::ENABLED);
5145 loaded_.clear();
5146 content::WindowedNotificationObserver observer(
5147 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5148 content::NotificationService::AllSources());
5149 service()->CheckForExternalUpdates();
5150 observer.Wait();
5151 ASSERT_EQ(1u, loaded_.size());
5153 ValidatePrefKeyCount(1);
5154 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5155 ValidateIntegerPref(good_crx, "location", location);
5157 if (GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL)) {
5158 EXPECT_EQ(2, provider->visit_count());
5159 } else {
5160 // Now test an externally triggered uninstall (deleting the registry key or
5161 // the pref entry).
5162 provider->RemoveExtension(good_crx);
5164 loaded_.clear();
5165 service()->OnExternalProviderReady(provider);
5166 base::RunLoop().RunUntilIdle();
5167 ASSERT_EQ(0u, loaded_.size());
5168 ValidatePrefKeyCount(0);
5170 // The extension should also be gone from the install directory.
5171 ASSERT_FALSE(base::PathExists(install_path));
5173 // Now test the case where user uninstalls and then the extension is removed
5174 // from the external provider.
5175 content::WindowedNotificationObserver observer(
5176 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5177 content::NotificationService::AllSources());
5178 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5179 service()->CheckForExternalUpdates();
5180 observer.Wait();
5182 ASSERT_EQ(1u, loaded_.size());
5183 ASSERT_EQ(0u, GetErrors().size());
5185 // User uninstalls.
5186 loaded_.clear();
5187 service()->UninstallExtension(id,
5188 extensions::UNINSTALL_REASON_FOR_TESTING,
5189 base::Bind(&base::DoNothing),
5190 NULL);
5191 base::RunLoop().RunUntilIdle();
5192 ASSERT_EQ(0u, loaded_.size());
5194 // Then remove the extension from the extension provider.
5195 provider->RemoveExtension(good_crx);
5197 // Should still be at 0.
5198 loaded_.clear();
5199 extensions::InstalledLoader(service()).LoadAllExtensions();
5200 base::RunLoop().RunUntilIdle();
5201 ASSERT_EQ(0u, loaded_.size());
5202 ValidatePrefKeyCount(1);
5204 EXPECT_EQ(5, provider->visit_count());
5208 // Tests the external installation feature
5209 #if defined(OS_WIN)
5210 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
5211 // This should all work, even when normal extension installation is disabled.
5212 InitializeEmptyExtensionService();
5213 service()->set_extensions_enabled(false);
5215 // Now add providers. Extension system takes ownership of the objects.
5216 MockExtensionProvider* reg_provider =
5217 new MockExtensionProvider(service(), Manifest::EXTERNAL_REGISTRY);
5218 AddMockExternalProvider(reg_provider);
5219 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
5221 #endif
5223 TEST_F(ExtensionServiceTest, ExternalInstallPref) {
5224 InitializeEmptyExtensionService();
5226 // Now add providers. Extension system takes ownership of the objects.
5227 MockExtensionProvider* pref_provider =
5228 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
5230 AddMockExternalProvider(pref_provider);
5231 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
5234 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
5235 // This should all work, even when normal extension installation is disabled.
5236 InitializeEmptyExtensionService();
5237 service()->set_extensions_enabled(false);
5239 // TODO(skerner): The mock provider is not a good model of a provider
5240 // that works with update URLs, because it adds file and version info.
5241 // Extend the mock to work with update URLs. This test checks the
5242 // behavior that is common to all external extension visitors. The
5243 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5244 // what the visitor does results in an extension being downloaded and
5245 // installed.
5246 MockExtensionProvider* pref_provider =
5247 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF_DOWNLOAD);
5248 AddMockExternalProvider(pref_provider);
5249 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
5252 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
5253 // This should all work, even when normal extension installation is disabled.
5254 InitializeEmptyExtensionService();
5255 service()->set_extensions_enabled(false);
5257 // TODO(skerner): The mock provider is not a good model of a provider
5258 // that works with update URLs, because it adds file and version info.
5259 // Extend the mock to work with update URLs. This test checks the
5260 // behavior that is common to all external extension visitors. The
5261 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5262 // what the visitor does results in an extension being downloaded and
5263 // installed.
5264 MockExtensionProvider* pref_provider =
5265 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
5266 AddMockExternalProvider(pref_provider);
5267 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
5270 // Tests that external extensions get uninstalled when the external extension
5271 // providers can't account for them.
5272 TEST_F(ExtensionServiceTest, ExternalUninstall) {
5273 // Start the extensions service with one external extension already installed.
5274 base::FilePath source_install_dir =
5275 data_dir().AppendASCII("good").AppendASCII("Extensions");
5276 base::FilePath pref_path = source_install_dir
5277 .DirName()
5278 .AppendASCII("PreferencesExternal");
5280 // This initializes the extensions service with no ExternalProviders.
5281 InitializeInstalledExtensionService(pref_path, source_install_dir);
5282 service()->set_extensions_enabled(false);
5284 service()->Init();
5286 ASSERT_EQ(0u, GetErrors().size());
5287 ASSERT_EQ(0u, loaded_.size());
5289 // Verify that it's not the disabled extensions flag causing it not to load.
5290 service()->set_extensions_enabled(true);
5291 service()->ReloadExtensionsForTest();
5292 base::RunLoop().RunUntilIdle();
5294 ASSERT_EQ(0u, GetErrors().size());
5295 ASSERT_EQ(0u, loaded_.size());
5298 // Test that running multiple update checks simultaneously does not
5299 // keep the update from succeeding.
5300 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
5301 InitializeEmptyExtensionService();
5303 MockExtensionProvider* provider =
5304 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
5305 AddMockExternalProvider(provider);
5307 // Verify that starting with no providers loads no extensions.
5308 service()->Init();
5309 ASSERT_EQ(0u, loaded_.size());
5311 // Start two checks for updates.
5312 provider->set_visit_count(0);
5313 service()->CheckForExternalUpdates();
5314 service()->CheckForExternalUpdates();
5315 base::RunLoop().RunUntilIdle();
5317 // Two calls should cause two checks for external extensions.
5318 EXPECT_EQ(2, provider->visit_count());
5319 EXPECT_EQ(0u, GetErrors().size());
5320 EXPECT_EQ(0u, loaded_.size());
5322 // Register a test extension externally using the mock registry provider.
5323 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5324 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5326 // Two checks for external updates should find the extension, and install it
5327 // once.
5328 content::WindowedNotificationObserver observer(
5329 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5330 content::NotificationService::AllSources());
5331 provider->set_visit_count(0);
5332 service()->CheckForExternalUpdates();
5333 service()->CheckForExternalUpdates();
5334 observer.Wait();
5335 EXPECT_EQ(2, provider->visit_count());
5336 ASSERT_EQ(0u, GetErrors().size());
5337 ASSERT_EQ(1u, loaded_.size());
5338 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
5339 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
5340 ValidatePrefKeyCount(1);
5341 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5342 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
5344 provider->RemoveExtension(good_crx);
5345 provider->set_visit_count(0);
5346 service()->CheckForExternalUpdates();
5347 service()->CheckForExternalUpdates();
5348 base::RunLoop().RunUntilIdle();
5350 // Two calls should cause two checks for external extensions.
5351 // Because the external source no longer includes good_crx,
5352 // good_crx will be uninstalled. So, expect that no extensions
5353 // are loaded.
5354 EXPECT_EQ(2, provider->visit_count());
5355 EXPECT_EQ(0u, GetErrors().size());
5356 EXPECT_EQ(0u, loaded_.size());
5359 TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
5360 InitializeEmptyExtensionService();
5362 // Test some valid extension records.
5363 // Set a base path to avoid erroring out on relative paths.
5364 // Paths starting with // are absolute on every platform we support.
5365 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5366 ASSERT_TRUE(base_path.IsAbsolute());
5367 MockProviderVisitor visitor(base_path);
5368 std::string json_data =
5370 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5371 " \"external_crx\": \"RandomExtension.crx\","
5372 " \"external_version\": \"1.0\""
5373 " },"
5374 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5375 " \"external_crx\": \"RandomExtension2.crx\","
5376 " \"external_version\": \"2.0\""
5377 " },"
5378 " \"cccccccccccccccccccccccccccccccc\": {"
5379 " \"external_update_url\": \"http:\\\\foo.com/update\","
5380 " \"install_parameter\": \"id\""
5381 " }"
5382 "}";
5383 EXPECT_EQ(3, visitor.Visit(json_data));
5385 // Simulate an external_extensions.json file that contains seven invalid
5386 // records:
5387 // - One that is missing the 'external_crx' key.
5388 // - One that is missing the 'external_version' key.
5389 // - One that is specifying .. in the path.
5390 // - One that specifies both a file and update URL.
5391 // - One that specifies no file or update URL.
5392 // - One that has an update URL that is not well formed.
5393 // - One that contains a malformed version.
5394 // - One that has an invalid id.
5395 // - One that has a non-dictionary value.
5396 // - One that has an integer 'external_version' instead of a string.
5397 // The final extension is valid, and we check that it is read to make sure
5398 // failures don't stop valid records from being read.
5399 json_data =
5401 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5402 " \"external_version\": \"1.0\""
5403 " },"
5404 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5405 " \"external_crx\": \"RandomExtension.crx\""
5406 " },"
5407 " \"cccccccccccccccccccccccccccccccc\": {"
5408 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
5409 " \"external_version\": \"2.0\""
5410 " },"
5411 " \"dddddddddddddddddddddddddddddddd\": {"
5412 " \"external_crx\": \"RandomExtension2.crx\","
5413 " \"external_version\": \"2.0\","
5414 " \"external_update_url\": \"http:\\\\foo.com/update\""
5415 " },"
5416 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
5417 " },"
5418 " \"ffffffffffffffffffffffffffffffff\": {"
5419 " \"external_update_url\": \"This string is not a valid URL\""
5420 " },"
5421 " \"gggggggggggggggggggggggggggggggg\": {"
5422 " \"external_crx\": \"RandomExtension3.crx\","
5423 " \"external_version\": \"This is not a valid version!\""
5424 " },"
5425 " \"This is not a valid id!\": {},"
5426 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
5427 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
5428 " \"external_crx\": \"RandomExtension4.crx\","
5429 " \"external_version\": 1.0"
5430 " },"
5431 " \"pppppppppppppppppppppppppppppppp\": {"
5432 " \"external_crx\": \"RandomValidExtension.crx\","
5433 " \"external_version\": \"1.0\""
5434 " }"
5435 "}";
5436 EXPECT_EQ(1, visitor.Visit(json_data));
5438 // Check that if a base path is not provided, use of a relative
5439 // path fails.
5440 base::FilePath empty;
5441 MockProviderVisitor visitor_no_relative_paths(empty);
5443 // Use absolute paths. Expect success.
5444 json_data =
5446 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5447 " \"external_crx\": \"//RandomExtension1.crx\","
5448 " \"external_version\": \"3.0\""
5449 " },"
5450 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5451 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
5452 " \"external_version\": \"3.0\""
5453 " }"
5454 "}";
5455 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
5457 // Use a relative path. Expect that it will error out.
5458 json_data =
5460 " \"cccccccccccccccccccccccccccccccc\": {"
5461 " \"external_crx\": \"RandomExtension2.crx\","
5462 " \"external_version\": \"3.0\""
5463 " }"
5464 "}";
5465 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
5467 // Test supported_locales.
5468 json_data =
5470 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5471 " \"external_crx\": \"RandomExtension.crx\","
5472 " \"external_version\": \"1.0\","
5473 " \"supported_locales\": [ \"en\" ]"
5474 " },"
5475 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5476 " \"external_crx\": \"RandomExtension2.crx\","
5477 " \"external_version\": \"2.0\","
5478 " \"supported_locales\": [ \"en-GB\" ]"
5479 " },"
5480 " \"cccccccccccccccccccccccccccccccc\": {"
5481 " \"external_crx\": \"RandomExtension2.crx\","
5482 " \"external_version\": \"3.0\","
5483 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
5484 " }"
5485 "}";
5487 ScopedBrowserLocale guard("en-US");
5488 EXPECT_EQ(2, visitor.Visit(json_data));
5491 // Test keep_if_present.
5492 json_data =
5494 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5495 " \"external_crx\": \"RandomExtension.crx\","
5496 " \"external_version\": \"1.0\","
5497 " \"keep_if_present\": true"
5498 " }"
5499 "}";
5501 EXPECT_EQ(0, visitor.Visit(json_data));
5504 // Test is_bookmark_app.
5505 MockProviderVisitor from_bookmark_visitor(
5506 base_path, Extension::FROM_BOOKMARK);
5507 json_data =
5509 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5510 " \"external_crx\": \"RandomExtension.crx\","
5511 " \"external_version\": \"1.0\","
5512 " \"is_bookmark_app\": true"
5513 " }"
5514 "}";
5515 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
5517 // Test is_from_webstore.
5518 MockProviderVisitor from_webstore_visitor(
5519 base_path, Extension::FROM_WEBSTORE);
5520 json_data =
5522 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5523 " \"external_crx\": \"RandomExtension.crx\","
5524 " \"external_version\": \"1.0\","
5525 " \"is_from_webstore\": true"
5526 " }"
5527 "}";
5528 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
5530 // Test was_installed_by_eom.
5531 MockProviderVisitor was_installed_by_eom_visitor(
5532 base_path, Extension::WAS_INSTALLED_BY_OEM);
5533 json_data =
5535 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5536 " \"external_crx\": \"RandomExtension.crx\","
5537 " \"external_version\": \"1.0\","
5538 " \"was_installed_by_oem\": true"
5539 " }"
5540 "}";
5541 EXPECT_EQ(1, was_installed_by_eom_visitor.Visit(json_data));
5543 // Test min_profile_created_by_version.
5544 MockProviderVisitor min_profile_created_by_version_visitor(base_path);
5545 json_data =
5547 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5548 " \"external_crx\": \"RandomExtension.crx\","
5549 " \"external_version\": \"1.0\","
5550 " \"min_profile_created_by_version\": \"42.0.0.1\""
5551 " },"
5552 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5553 " \"external_crx\": \"RandomExtension2.crx\","
5554 " \"external_version\": \"1.0\","
5555 " \"min_profile_created_by_version\": \"43.0.0.1\""
5556 " },"
5557 " \"cccccccccccccccccccccccccccccccc\": {"
5558 " \"external_crx\": \"RandomExtension3.crx\","
5559 " \"external_version\": \"3.0\","
5560 " \"min_profile_created_by_version\": \"44.0.0.1\""
5561 " }"
5562 "}";
5563 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5564 prefs::kProfileCreatedByVersion, "40.0.0.1");
5565 EXPECT_EQ(0, min_profile_created_by_version_visitor.Visit(json_data));
5566 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5567 prefs::kProfileCreatedByVersion, "43.0.0.1");
5568 EXPECT_EQ(2, min_profile_created_by_version_visitor.Visit(json_data));
5569 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5570 prefs::kProfileCreatedByVersion, "45.0.0.1");
5571 EXPECT_EQ(3, min_profile_created_by_version_visitor.Visit(json_data));
5574 TEST_F(ExtensionServiceTest, DoNotInstallForEnterprise) {
5575 InitializeEmptyExtensionService();
5577 const base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5578 ASSERT_TRUE(base_path.IsAbsolute());
5579 MockProviderVisitor visitor(base_path);
5580 policy::ProfilePolicyConnector* const connector =
5581 policy::ProfilePolicyConnectorFactory::GetForBrowserContext(
5582 visitor.profile());
5583 connector->OverrideIsManagedForTesting(true);
5584 EXPECT_TRUE(connector->IsManaged());
5586 std::string json_data =
5588 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5589 " \"external_crx\": \"RandomExtension.crx\","
5590 " \"external_version\": \"1.0\","
5591 " \"do_not_install_for_enterprise\": true"
5592 " },"
5593 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5594 " \"external_crx\": \"RandomExtension2.crx\","
5595 " \"external_version\": \"1.0\""
5596 " }"
5597 "}";
5598 EXPECT_EQ(1, visitor.Visit(json_data));
5601 // Test loading good extensions from the profile directory.
5602 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
5603 // Ensure we're testing in "en" and leave global state untouched.
5604 extension_l10n_util::ScopedLocaleForTest testLocale("en");
5606 // Initialize the test dir with a good Preferences/extensions.
5607 base::FilePath source_install_dir = data_dir().AppendASCII("l10n");
5608 base::FilePath pref_path =
5609 source_install_dir.Append(chrome::kPreferencesFilename);
5610 InitializeInstalledExtensionService(pref_path, source_install_dir);
5612 service()->Init();
5614 ASSERT_EQ(3u, loaded_.size());
5616 // This was equal to "sr" on load.
5617 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
5619 // These are untouched by re-localization.
5620 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
5621 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
5623 // This one starts with Serbian name, and gets re-localized into English.
5624 EXPECT_EQ("My name is simple.", loaded_[0]->name());
5626 // These are untouched by re-localization.
5627 EXPECT_EQ("My name is simple.", loaded_[1]->name());
5628 EXPECT_EQ("no l10n", loaded_[2]->name());
5631 class ExtensionsReadyRecorder : public content::NotificationObserver {
5632 public:
5633 ExtensionsReadyRecorder() : ready_(false) {
5634 registrar_.Add(this,
5635 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
5636 content::NotificationService::AllSources());
5639 void set_ready(bool value) { ready_ = value; }
5640 bool ready() { return ready_; }
5642 private:
5643 void Observe(int type,
5644 const content::NotificationSource& source,
5645 const content::NotificationDetails& details) override {
5646 switch (type) {
5647 case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED:
5648 ready_ = true;
5649 break;
5650 default:
5651 NOTREACHED();
5655 content::NotificationRegistrar registrar_;
5656 bool ready_;
5659 // Test that we get enabled/disabled correctly for all the pref/command-line
5660 // combinations. We don't want to derive from the ExtensionServiceTest class
5661 // for this test, so we use ExtensionServiceTestSimple.
5663 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
5664 // enabled or not.
5665 class ExtensionServiceTestSimple : public testing::Test {
5666 content::TestBrowserThreadBundle thread_bundle_;
5669 TEST_F(ExtensionServiceTestSimple, Enabledness) {
5670 // Make sure the PluginService singleton is destroyed at the end of the test.
5671 base::ShadowingAtExitManager at_exit_manager;
5672 #if defined(ENABLE_PLUGINS)
5673 content::PluginService::GetInstance()->Init();
5674 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
5675 #endif
5677 ExtensionErrorReporter::Init(false); // no noisy errors
5678 ExtensionsReadyRecorder recorder;
5679 scoped_ptr<TestingProfile> profile(new TestingProfile());
5680 #if defined OS_CHROMEOS
5681 chromeos::ScopedTestDeviceSettingsService device_settings_service;
5682 chromeos::ScopedTestCrosSettings cros_settings;
5683 scoped_ptr<chromeos::ScopedTestUserManager> user_manager(
5684 new chromeos::ScopedTestUserManager);
5685 #endif
5686 scoped_ptr<base::CommandLine> command_line;
5687 base::FilePath install_dir = profile->GetPath()
5688 .AppendASCII(extensions::kInstallDirectoryName);
5690 // By default, we are enabled.
5691 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5692 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
5693 ExtensionSystem::Get(profile.get()))->
5694 CreateExtensionService(
5695 command_line.get(),
5696 install_dir,
5697 false);
5698 EXPECT_TRUE(service->extensions_enabled());
5699 service->Init();
5700 base::RunLoop().RunUntilIdle();
5701 EXPECT_TRUE(recorder.ready());
5702 #if defined OS_CHROMEOS
5703 user_manager.reset();
5704 #endif
5706 // If either the command line or pref is set, we are disabled.
5707 recorder.set_ready(false);
5708 profile.reset(new TestingProfile());
5709 command_line->AppendSwitch(switches::kDisableExtensions);
5710 service = static_cast<extensions::TestExtensionSystem*>(
5711 ExtensionSystem::Get(profile.get()))->
5712 CreateExtensionService(
5713 command_line.get(),
5714 install_dir,
5715 false);
5716 EXPECT_FALSE(service->extensions_enabled());
5717 service->Init();
5718 base::RunLoop().RunUntilIdle();
5719 EXPECT_TRUE(recorder.ready());
5721 recorder.set_ready(false);
5722 profile.reset(new TestingProfile());
5723 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5724 service = static_cast<extensions::TestExtensionSystem*>(
5725 ExtensionSystem::Get(profile.get()))->
5726 CreateExtensionService(
5727 command_line.get(),
5728 install_dir,
5729 false);
5730 EXPECT_FALSE(service->extensions_enabled());
5731 service->Init();
5732 base::RunLoop().RunUntilIdle();
5733 EXPECT_TRUE(recorder.ready());
5735 recorder.set_ready(false);
5736 profile.reset(new TestingProfile());
5737 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5738 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5739 service = static_cast<extensions::TestExtensionSystem*>(
5740 ExtensionSystem::Get(profile.get()))->
5741 CreateExtensionService(
5742 command_line.get(),
5743 install_dir,
5744 false);
5745 EXPECT_FALSE(service->extensions_enabled());
5746 service->Init();
5747 base::RunLoop().RunUntilIdle();
5748 EXPECT_TRUE(recorder.ready());
5750 // Explicitly delete all the resources used in this test.
5751 profile.reset();
5752 service = NULL;
5753 // Execute any pending deletion tasks.
5754 base::RunLoop().RunUntilIdle();
5757 // Test loading extensions that require limited and unlimited storage quotas.
5758 TEST_F(ExtensionServiceTest, StorageQuota) {
5759 InitializeEmptyExtensionService();
5761 base::FilePath extensions_path = data_dir().AppendASCII("storage_quota");
5763 base::FilePath limited_quota_ext =
5764 extensions_path.AppendASCII("limited_quota")
5765 .AppendASCII("1.0");
5767 // The old permission name for unlimited quota was "unlimited_storage", but
5768 // we changed it to "unlimitedStorage". This tests both versions.
5769 base::FilePath unlimited_quota_ext =
5770 extensions_path.AppendASCII("unlimited_quota")
5771 .AppendASCII("1.0");
5772 base::FilePath unlimited_quota_ext2 =
5773 extensions_path.AppendASCII("unlimited_quota")
5774 .AppendASCII("2.0");
5775 extensions::UnpackedInstaller::Create(service())->Load(limited_quota_ext);
5776 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext);
5777 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext2);
5778 base::RunLoop().RunUntilIdle();
5780 ASSERT_EQ(3u, loaded_.size());
5781 EXPECT_TRUE(profile());
5782 EXPECT_FALSE(profile()->IsOffTheRecord());
5783 EXPECT_FALSE(
5784 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5785 loaded_[0]->url()));
5786 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5787 loaded_[1]->url()));
5788 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5789 loaded_[2]->url()));
5792 // Tests ComponentLoader::Add().
5793 TEST_F(ExtensionServiceTest, ComponentExtensions) {
5794 InitializeEmptyExtensionService();
5796 // Component extensions should work even when extensions are disabled.
5797 service()->set_extensions_enabled(false);
5799 base::FilePath path = data_dir()
5800 .AppendASCII("good")
5801 .AppendASCII("Extensions")
5802 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
5803 .AppendASCII("1.0.0.0");
5805 std::string manifest;
5806 ASSERT_TRUE(base::ReadFileToString(
5807 path.Append(extensions::kManifestFilename), &manifest));
5809 service()->component_loader()->Add(manifest, path);
5810 service()->Init();
5812 // Note that we do not pump messages -- the extension should be loaded
5813 // immediately.
5815 EXPECT_EQ(0u, GetErrors().size());
5816 ASSERT_EQ(1u, loaded_.size());
5817 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
5818 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5820 // Component extensions get a prefs entry on first install.
5821 ValidatePrefKeyCount(1);
5823 // Reload all extensions, and make sure it comes back.
5824 std::string extension_id = (*registry()->enabled_extensions().begin())->id();
5825 loaded_.clear();
5826 service()->ReloadExtensionsForTest();
5827 ASSERT_EQ(1u, registry()->enabled_extensions().size());
5828 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id());
5831 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
5832 InitializeEmptyExtensionService();
5834 bool flare_was_called = false;
5835 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5836 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5837 extension_sync_service()->SetSyncStartFlareForTesting(
5838 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5839 factory.GetWeakPtr(),
5840 &flare_was_called, // Safe due to WeakPtrFactory scope.
5841 &triggered_type)); // Safe due to WeakPtrFactory scope.
5843 // Install a component extension.
5844 std::string manifest;
5845 ASSERT_TRUE(base::ReadFileToString(
5846 good0_path().Append(extensions::kManifestFilename), &manifest));
5847 service()->component_loader()->Add(manifest, good0_path());
5848 ASSERT_FALSE(service()->is_ready());
5849 service()->Init();
5850 ASSERT_TRUE(service()->is_ready());
5852 // Extensions added before service is_ready() don't trigger sync startup.
5853 EXPECT_FALSE(flare_was_called);
5854 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5857 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
5858 InitializeGoodInstalledExtensionService();
5860 bool flare_was_called = false;
5861 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5862 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5863 extension_sync_service()->SetSyncStartFlareForTesting(
5864 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5865 factory.GetWeakPtr(),
5866 &flare_was_called, // Safe due to WeakPtrFactory scope.
5867 &triggered_type)); // Safe due to WeakPtrFactory scope.
5869 ASSERT_FALSE(service()->is_ready());
5870 service()->Init();
5871 ASSERT_EQ(3u, loaded_.size());
5872 ASSERT_TRUE(service()->is_ready());
5874 // Extensions added before service is_ready() don't trigger sync startup.
5875 EXPECT_FALSE(flare_was_called);
5876 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5879 TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
5880 InitializeEmptyExtensionService();
5881 service()->Init();
5882 ASSERT_TRUE(service()->is_ready());
5884 bool flare_was_called = false;
5885 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5886 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5887 extension_sync_service()->SetSyncStartFlareForTesting(
5888 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5889 factory.GetWeakPtr(),
5890 &flare_was_called, // Safe due to WeakPtrFactory scope.
5891 &triggered_type)); // Safe due to WeakPtrFactory scope.
5893 base::FilePath path = data_dir().AppendASCII("good.crx");
5894 InstallCRX(path, INSTALL_NEW);
5896 EXPECT_TRUE(flare_was_called);
5897 EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
5899 // Reset.
5900 flare_was_called = false;
5901 triggered_type = syncer::UNSPECIFIED;
5903 // Once sync starts, flare should no longer be invoked.
5904 extension_sync_service()->MergeDataAndStartSyncing(
5905 syncer::EXTENSIONS,
5906 syncer::SyncDataList(),
5907 scoped_ptr<syncer::SyncChangeProcessor>(
5908 new syncer::FakeSyncChangeProcessor),
5909 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5910 path = data_dir().AppendASCII("page_action.crx");
5911 InstallCRX(path, INSTALL_NEW);
5912 EXPECT_FALSE(flare_was_called);
5913 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5916 TEST_F(ExtensionServiceTest, DisableExtensionFromSync) {
5917 // Start the extensions service with one external extension already installed.
5918 base::FilePath source_install_dir =
5919 data_dir().AppendASCII("good").AppendASCII("Extensions");
5920 base::FilePath pref_path =
5921 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5923 InitializeInstalledExtensionService(pref_path, source_install_dir);
5925 // The user has enabled sync.
5926 ProfileSyncService* sync_service =
5927 ProfileSyncServiceFactory::GetForProfile(profile());
5928 sync_service->SetSyncSetupCompleted();
5930 service()->Init();
5931 ASSERT_TRUE(service()->is_ready());
5933 ASSERT_EQ(3u, loaded_.size());
5935 // We start enabled.
5936 const Extension* extension = service()->GetExtensionById(good0, true);
5937 ASSERT_TRUE(extension);
5938 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5940 // Sync starts up.
5941 extension_sync_service()->MergeDataAndStartSyncing(
5942 syncer::EXTENSIONS,
5943 syncer::SyncDataList(),
5944 make_scoped_ptr(new syncer::FakeSyncChangeProcessor),
5945 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5947 // Then sync data arrives telling us to disable |good0|.
5948 ExtensionSyncData disable_good_crx(*extension, false,
5949 Extension::DISABLE_USER_ACTION, false,
5950 false, ExtensionSyncData::BOOLEAN_UNSET);
5951 syncer::SyncChange sync_change(FROM_HERE,
5952 syncer::SyncChange::ACTION_UPDATE,
5953 disable_good_crx.GetSyncData());
5954 syncer::SyncChangeList list(1, sync_change);
5955 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5957 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5960 TEST_F(ExtensionServiceTest, IgnoreSyncChangesWhenLocalStateIsMoreRecent) {
5961 // Start the extension service with three extensions already installed.
5962 base::FilePath source_install_dir =
5963 data_dir().AppendASCII("good").AppendASCII("Extensions");
5964 base::FilePath pref_path =
5965 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5967 InitializeInstalledExtensionService(pref_path, source_install_dir);
5969 // The user has enabled sync.
5970 ProfileSyncService* sync_service =
5971 ProfileSyncServiceFactory::GetForProfile(profile());
5972 sync_service->SetSyncSetupCompleted();
5973 // Make sure ExtensionSyncService is created, so it'll be notified of changes.
5974 extension_sync_service();
5976 service()->Init();
5977 ASSERT_TRUE(service()->is_ready());
5978 ASSERT_EQ(3u, loaded_.size());
5980 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5981 ASSERT_TRUE(service()->IsExtensionEnabled(good2));
5983 // Disable and re-enable good0 before first sync data arrives.
5984 service()->DisableExtension(good0, Extension::DISABLE_USER_ACTION);
5985 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5986 service()->EnableExtension(good0);
5987 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5988 // Disable good2 before first sync data arrives (good1 is considered
5989 // non-syncable because it has plugin permission).
5990 service()->DisableExtension(good2, Extension::DISABLE_USER_ACTION);
5991 ASSERT_FALSE(service()->IsExtensionEnabled(good2));
5993 const Extension* extension0 = service()->GetExtensionById(good0, true);
5994 const Extension* extension2 = service()->GetExtensionById(good2, true);
5995 ASSERT_TRUE(extensions::sync_helper::IsSyncable(extension0));
5996 ASSERT_TRUE(extensions::sync_helper::IsSyncable(extension2));
5998 // Now sync data comes in that says to disable good0 and enable good2.
5999 ExtensionSyncData disable_good0(*extension0, false,
6000 Extension::DISABLE_USER_ACTION, false, false,
6001 ExtensionSyncData::BOOLEAN_UNSET);
6002 ExtensionSyncData enable_good2(*extension2, true, Extension::DISABLE_NONE,
6003 false, false,
6004 ExtensionSyncData::BOOLEAN_UNSET);
6005 syncer::SyncDataList sync_data;
6006 sync_data.push_back(disable_good0.GetSyncData());
6007 sync_data.push_back(enable_good2.GetSyncData());
6008 extension_sync_service()->MergeDataAndStartSyncing(
6009 syncer::EXTENSIONS,
6010 sync_data,
6011 make_scoped_ptr(new syncer::FakeSyncChangeProcessor),
6012 make_scoped_ptr(new syncer::SyncErrorFactoryMock));
6014 // Both sync changes should be ignored, since the local state was changed
6015 // before sync started, and so the local state is considered more recent.
6016 EXPECT_TRUE(service()->IsExtensionEnabled(good0));
6017 EXPECT_FALSE(service()->IsExtensionEnabled(good2));
6020 TEST_F(ExtensionServiceTest, GetSyncData) {
6021 InitializeEmptyExtensionService();
6022 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6023 const Extension* extension = service()->GetInstalledExtension(good_crx);
6024 ASSERT_TRUE(extension);
6026 extension_sync_service()->MergeDataAndStartSyncing(
6027 syncer::EXTENSIONS,
6028 syncer::SyncDataList(),
6029 scoped_ptr<syncer::SyncChangeProcessor>(
6030 new syncer::FakeSyncChangeProcessor),
6031 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6033 syncer::SyncDataList list =
6034 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6035 ASSERT_EQ(list.size(), 1U);
6036 scoped_ptr<ExtensionSyncData> data =
6037 ExtensionSyncData::CreateFromSyncData(list[0]);
6038 ASSERT_TRUE(data.get());
6039 EXPECT_EQ(extension->id(), data->id());
6040 EXPECT_FALSE(data->uninstalled());
6041 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
6042 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
6043 data->incognito_enabled());
6044 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6045 EXPECT_TRUE(data->version().Equals(*extension->version()));
6046 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
6047 data->update_url());
6048 EXPECT_EQ(extension->name(), data->name());
6051 TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
6052 InitializeEmptyExtensionService();
6053 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6054 TerminateExtension(good_crx);
6055 const Extension* extension = service()->GetInstalledExtension(good_crx);
6056 ASSERT_TRUE(extension);
6058 syncer::FakeSyncChangeProcessor processor;
6059 extension_sync_service()->MergeDataAndStartSyncing(
6060 syncer::EXTENSIONS,
6061 syncer::SyncDataList(),
6062 scoped_ptr<syncer::SyncChangeProcessor>(
6063 new syncer::FakeSyncChangeProcessor),
6064 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6066 syncer::SyncDataList list =
6067 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6068 ASSERT_EQ(list.size(), 1U);
6069 scoped_ptr<ExtensionSyncData> data =
6070 ExtensionSyncData::CreateFromSyncData(list[0]);
6071 ASSERT_TRUE(data.get());
6072 EXPECT_EQ(extension->id(), data->id());
6073 EXPECT_FALSE(data->uninstalled());
6074 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
6075 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
6076 data->incognito_enabled());
6077 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6078 EXPECT_TRUE(data->version().Equals(*extension->version()));
6079 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
6080 data->update_url());
6081 EXPECT_EQ(extension->name(), data->name());
6084 TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
6085 InitializeEmptyExtensionService();
6086 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6087 const Extension* extension = service()->GetInstalledExtension(good_crx);
6088 ASSERT_TRUE(extension);
6090 syncer::FakeSyncChangeProcessor processor;
6091 extension_sync_service()->MergeDataAndStartSyncing(
6092 syncer::APPS,
6093 syncer::SyncDataList(),
6094 scoped_ptr<syncer::SyncChangeProcessor>(
6095 new syncer::FakeSyncChangeProcessor),
6096 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6098 syncer::SyncDataList list =
6099 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6100 ASSERT_EQ(list.size(), 0U);
6103 TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
6104 InitializeEmptyExtensionService();
6105 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6106 const Extension* extension = service()->GetInstalledExtension(good_crx);
6107 ASSERT_TRUE(extension);
6109 syncer::FakeSyncChangeProcessor processor;
6110 extension_sync_service()->MergeDataAndStartSyncing(
6111 syncer::EXTENSIONS,
6112 syncer::SyncDataList(),
6113 scoped_ptr<syncer::SyncChangeProcessor>(
6114 new syncer::FakeSyncChangeProcessor),
6115 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
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_FALSE(data->incognito_enabled());
6126 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6129 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
6131 syncer::SyncDataList list =
6132 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6133 ASSERT_EQ(list.size(), 1U);
6134 scoped_ptr<ExtensionSyncData> data =
6135 ExtensionSyncData::CreateFromSyncData(list[0]);
6136 ASSERT_TRUE(data.get());
6137 EXPECT_FALSE(data->enabled());
6138 EXPECT_FALSE(data->incognito_enabled());
6139 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6142 extensions::util::SetIsIncognitoEnabled(good_crx, profile(), true);
6143 extensions::util::SetAllowedScriptingOnAllUrls(
6144 good_crx, profile(), false);
6146 syncer::SyncDataList list =
6147 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6148 ASSERT_EQ(list.size(), 1U);
6149 scoped_ptr<ExtensionSyncData> data =
6150 ExtensionSyncData::CreateFromSyncData(list[0]);
6151 ASSERT_TRUE(data.get());
6152 EXPECT_FALSE(data->enabled());
6153 EXPECT_TRUE(data->incognito_enabled());
6154 EXPECT_EQ(ExtensionSyncData::BOOLEAN_FALSE, data->all_urls_enabled());
6157 service()->EnableExtension(good_crx);
6158 extensions::util::SetAllowedScriptingOnAllUrls(
6159 good_crx, profile(), true);
6161 syncer::SyncDataList list =
6162 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6163 ASSERT_EQ(list.size(), 1U);
6164 scoped_ptr<ExtensionSyncData> data =
6165 ExtensionSyncData::CreateFromSyncData(list[0]);
6166 ASSERT_TRUE(data.get());
6167 EXPECT_TRUE(data->enabled());
6168 EXPECT_TRUE(data->incognito_enabled());
6169 EXPECT_EQ(ExtensionSyncData::BOOLEAN_TRUE, data->all_urls_enabled());
6173 TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
6174 InitializeEmptyExtensionService();
6175 InstallCRXWithLocation(
6176 data_dir().AppendASCII("good.crx"), Manifest::EXTERNAL_PREF, INSTALL_NEW);
6177 const Extension* extension = service()->GetInstalledExtension(good_crx);
6178 ASSERT_TRUE(extension);
6180 syncer::FakeSyncChangeProcessor processor;
6181 extension_sync_service()->MergeDataAndStartSyncing(
6182 syncer::EXTENSIONS,
6183 syncer::SyncDataList(),
6184 scoped_ptr<syncer::SyncChangeProcessor>(
6185 new syncer::FakeSyncChangeProcessor),
6186 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6188 UninstallExtension(good_crx, false);
6189 EXPECT_TRUE(
6190 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
6192 sync_pb::EntitySpecifics specifics;
6193 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6194 sync_pb::ExtensionSpecifics* extension_specifics =
6195 app_specifics->mutable_extension();
6196 extension_specifics->set_id(good_crx);
6197 extension_specifics->set_version("1.0");
6198 extension_specifics->set_enabled(true);
6200 syncer::SyncData sync_data =
6201 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6202 syncer::SyncChange sync_change(FROM_HERE,
6203 syncer::SyncChange::ACTION_UPDATE,
6204 sync_data);
6205 syncer::SyncChangeList list(1);
6206 list[0] = sync_change;
6208 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6209 EXPECT_TRUE(
6210 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
6213 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
6214 InitializeEmptyExtensionService();
6215 const Extension* app =
6216 PackAndInstallCRX(data_dir().AppendASCII("app"), INSTALL_NEW);
6217 ASSERT_TRUE(app);
6218 ASSERT_TRUE(app->is_app());
6220 syncer::FakeSyncChangeProcessor processor;
6221 extension_sync_service()->MergeDataAndStartSyncing(
6222 syncer::APPS,
6223 syncer::SyncDataList(),
6224 scoped_ptr<syncer::SyncChangeProcessor>(
6225 new syncer::FakeSyncChangeProcessor),
6226 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6228 syncer::StringOrdinal initial_ordinal =
6229 syncer::StringOrdinal::CreateInitialOrdinal();
6231 syncer::SyncDataList list =
6232 extension_sync_service()->GetAllSyncData(syncer::APPS);
6233 ASSERT_EQ(list.size(), 1U);
6235 scoped_ptr<ExtensionSyncData> app_sync_data =
6236 ExtensionSyncData::CreateFromSyncData(list[0]);
6237 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->app_launch_ordinal()));
6238 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6241 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
6242 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
6244 syncer::SyncDataList list =
6245 extension_sync_service()->GetAllSyncData(syncer::APPS);
6246 ASSERT_EQ(list.size(), 1U);
6248 scoped_ptr<ExtensionSyncData> app_sync_data =
6249 ExtensionSyncData::CreateFromSyncData(list[0]);
6250 ASSERT_TRUE(app_sync_data.get());
6251 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6252 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6255 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
6257 syncer::SyncDataList list =
6258 extension_sync_service()->GetAllSyncData(syncer::APPS);
6259 ASSERT_EQ(list.size(), 1U);
6261 scoped_ptr<ExtensionSyncData> app_sync_data =
6262 ExtensionSyncData::CreateFromSyncData(list[0]);
6263 ASSERT_TRUE(app_sync_data.get());
6264 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6265 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->page_ordinal()));
6269 // TODO (rdevlin.cronin): The OnExtensionMoved() method has been removed from
6270 // ExtensionService, so this test probably needs a new home. Unfortunately, it
6271 // relies pretty heavily on things like InitializeExtension[Sync]Service() and
6272 // PackAndInstallCRX(). When we clean up a bit more, this should move out.
6273 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
6274 InitializeEmptyExtensionService();
6275 const size_t kAppCount = 3;
6276 const Extension* apps[kAppCount];
6277 apps[0] = PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
6278 apps[1] = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
6279 apps[2] = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
6280 for (size_t i = 0; i < kAppCount; ++i) {
6281 ASSERT_TRUE(apps[i]);
6282 ASSERT_TRUE(apps[i]->is_app());
6285 syncer::FakeSyncChangeProcessor processor;
6286 extension_sync_service()->MergeDataAndStartSyncing(
6287 syncer::APPS,
6288 syncer::SyncDataList(),
6289 scoped_ptr<syncer::SyncChangeProcessor>(
6290 new syncer::FakeSyncChangeProcessor),
6291 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6293 ExtensionPrefs::Get(service()->GetBrowserContext())
6294 ->app_sorting()
6295 ->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
6297 syncer::SyncDataList list =
6298 extension_sync_service()->GetAllSyncData(syncer::APPS);
6299 ASSERT_EQ(list.size(), 3U);
6301 scoped_ptr<ExtensionSyncData> data[kAppCount];
6302 for (size_t i = 0; i < kAppCount; ++i) {
6303 data[i] = ExtensionSyncData::CreateFromSyncData(list[i]);
6304 ASSERT_TRUE(data[i].get());
6307 // The sync data is not always in the same order our apps were installed in,
6308 // so we do that sorting here so we can make sure the values are changed as
6309 // expected.
6310 syncer::StringOrdinal app_launch_ordinals[kAppCount];
6311 for (size_t i = 0; i < kAppCount; ++i) {
6312 for (size_t j = 0; j < kAppCount; ++j) {
6313 if (apps[i]->id() == data[j]->id())
6314 app_launch_ordinals[i] = data[j]->app_launch_ordinal();
6318 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
6319 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
6323 TEST_F(ExtensionServiceTest, GetSyncDataList) {
6324 InitializeEmptyExtensionService();
6325 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6326 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
6327 InstallCRX(data_dir().AppendASCII("theme.crx"), INSTALL_NEW);
6328 InstallCRX(data_dir().AppendASCII("theme2.crx"), INSTALL_NEW);
6330 syncer::FakeSyncChangeProcessor processor;
6331 extension_sync_service()->MergeDataAndStartSyncing(
6332 syncer::APPS,
6333 syncer::SyncDataList(),
6334 scoped_ptr<syncer::SyncChangeProcessor>(
6335 new syncer::FakeSyncChangeProcessor),
6336 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6337 extension_sync_service()->MergeDataAndStartSyncing(
6338 syncer::EXTENSIONS,
6339 syncer::SyncDataList(),
6340 scoped_ptr<syncer::SyncChangeProcessor>(
6341 new syncer::FakeSyncChangeProcessor),
6342 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6344 service()->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
6345 TerminateExtension(theme2_crx);
6347 EXPECT_EQ(0u, extension_sync_service()->GetAllSyncData(syncer::APPS).size());
6348 EXPECT_EQ(
6349 2u, extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS).size());
6352 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
6353 InitializeEmptyExtensionService();
6354 syncer::FakeSyncChangeProcessor processor;
6355 extension_sync_service()->MergeDataAndStartSyncing(
6356 syncer::EXTENSIONS,
6357 syncer::SyncDataList(),
6358 scoped_ptr<syncer::SyncChangeProcessor>(
6359 new syncer::FakeSyncChangeProcessor),
6360 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6362 sync_pb::EntitySpecifics specifics;
6363 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6364 ext_specifics->set_id(good_crx);
6365 ext_specifics->set_version("1.0");
6366 syncer::SyncData sync_data =
6367 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6368 syncer::SyncChange sync_change(FROM_HERE,
6369 syncer::SyncChange::ACTION_DELETE,
6370 sync_data);
6371 syncer::SyncChangeList list(1);
6372 list[0] = sync_change;
6374 // Should do nothing.
6375 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6376 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6378 // Install the extension.
6379 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6380 InstallCRX(extension_path, INSTALL_NEW);
6381 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6383 // Should uninstall the extension.
6384 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6385 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6387 // Should again do nothing.
6388 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6389 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6392 TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
6393 InitializeEmptyExtensionService();
6395 // Install the extension.
6396 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6397 InstallCRX(extension_path, INSTALL_NEW);
6398 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6400 sync_pb::EntitySpecifics specifics;
6401 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6402 sync_pb::ExtensionSpecifics* extension_specifics =
6403 app_specifics->mutable_extension();
6404 extension_specifics->set_id(good_crx);
6405 extension_specifics->set_version(
6406 service()->GetInstalledExtension(good_crx)->version()->GetString());
6409 extension_specifics->set_enabled(true);
6410 syncer::SyncData sync_data =
6411 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6412 syncer::SyncChange sync_change(FROM_HERE,
6413 syncer::SyncChange::ACTION_DELETE,
6414 sync_data);
6415 syncer::SyncChangeList list(1);
6416 list[0] = sync_change;
6418 // Should do nothing
6419 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6420 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6424 extension_specifics->set_enabled(false);
6425 syncer::SyncData sync_data =
6426 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6427 syncer::SyncChange sync_change(FROM_HERE,
6428 syncer::SyncChange::ACTION_UPDATE,
6429 sync_data);
6430 syncer::SyncChangeList list(1);
6431 list[0] = sync_change;
6433 // Should again do nothing.
6434 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6435 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
6439 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
6440 InitializeEmptyExtensionService();
6441 syncer::FakeSyncChangeProcessor processor;
6442 extension_sync_service()->MergeDataAndStartSyncing(
6443 syncer::EXTENSIONS,
6444 syncer::SyncDataList(),
6445 scoped_ptr<syncer::SyncChangeProcessor>(
6446 new syncer::FakeSyncChangeProcessor),
6447 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6449 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6450 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6451 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6452 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6453 good_crx, profile()));
6454 const bool kDefaultAllowedScripting =
6455 extensions::util::DefaultAllowedScriptingOnAllUrls();
6456 EXPECT_EQ(kDefaultAllowedScripting,
6457 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6459 sync_pb::EntitySpecifics specifics;
6460 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6461 ext_specifics->set_id(good_crx);
6462 ext_specifics->set_version(
6463 service()->GetInstalledExtension(good_crx)->version()->GetString());
6464 ext_specifics->set_enabled(false);
6467 syncer::SyncData sync_data =
6468 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6469 syncer::SyncChange sync_change(FROM_HERE,
6470 syncer::SyncChange::ACTION_UPDATE,
6471 sync_data);
6472 syncer::SyncChangeList list(1);
6473 list[0] = sync_change;
6474 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6475 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6476 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6477 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6478 good_crx, profile()));
6479 EXPECT_EQ(kDefaultAllowedScripting,
6480 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6484 ext_specifics->set_enabled(true);
6485 ext_specifics->set_incognito_enabled(true);
6486 syncer::SyncData sync_data =
6487 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6488 syncer::SyncChange sync_change(FROM_HERE,
6489 syncer::SyncChange::ACTION_UPDATE,
6490 sync_data);
6491 syncer::SyncChangeList list(1);
6492 list[0] = sync_change;
6493 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6494 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6495 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6499 ext_specifics->set_enabled(false);
6500 ext_specifics->set_incognito_enabled(true);
6501 syncer::SyncData sync_data =
6502 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6503 syncer::SyncChange sync_change(FROM_HERE,
6504 syncer::SyncChange::ACTION_UPDATE,
6505 sync_data);
6506 syncer::SyncChangeList list(1);
6507 list[0] = sync_change;
6508 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6509 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6510 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6514 ext_specifics->set_enabled(true);
6515 ext_specifics->set_all_urls_enabled(!kDefaultAllowedScripting);
6516 syncer::SyncData sync_data =
6517 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6518 syncer::SyncChange sync_change(FROM_HERE,
6519 syncer::SyncChange::ACTION_UPDATE,
6520 sync_data);
6521 syncer::SyncChangeList list(1);
6522 list[0] = sync_change;
6523 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6524 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6525 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6526 good_crx, profile()));
6527 EXPECT_EQ(!kDefaultAllowedScripting,
6528 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6532 ext_specifics->set_all_urls_enabled(kDefaultAllowedScripting);
6533 syncer::SyncData sync_data =
6534 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6535 syncer::SyncChange sync_change(FROM_HERE,
6536 syncer::SyncChange::ACTION_UPDATE,
6537 sync_data);
6538 syncer::SyncChangeList list(1);
6539 list[0] = sync_change;
6540 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6541 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6542 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6543 good_crx, profile()));
6544 EXPECT_EQ(kDefaultAllowedScripting,
6545 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6548 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6551 TEST_F(ExtensionServiceTest, ProcessSyncDataNewExtension) {
6552 InitializeEmptyExtensionService();
6553 syncer::FakeSyncChangeProcessor processor;
6554 extension_sync_service()->MergeDataAndStartSyncing(
6555 syncer::EXTENSIONS,
6556 syncer::SyncDataList(),
6557 scoped_ptr<syncer::SyncChangeProcessor>(
6558 new syncer::FakeSyncChangeProcessor),
6559 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6561 const base::FilePath path = data_dir().AppendASCII("good.crx");
6562 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6564 struct TestCase {
6565 const char* name; // For failure output only.
6566 bool sync_enabled; // The "enabled" flag coming in from Sync.
6567 // The disable reason(s) coming in from Sync, or -1 for "not set".
6568 int sync_disable_reasons;
6569 // The disable reason(s) that should be set on the installed extension.
6570 // This will usually be the same as |sync_disable_reasons|, but see the
6571 // "Legacy" case.
6572 int expect_disable_reasons;
6573 // Whether the extension's permissions should be auto-granted during
6574 // installation.
6575 bool expect_permissions_granted;
6576 } test_cases[] = {
6577 // Standard case: Extension comes in enabled; permissions should be granted
6578 // during installation.
6579 { "Standard", true, 0, 0, true },
6580 // If the extension comes in disabled, its permissions should still be
6581 // granted (the user already approved them on another machine).
6582 { "Disabled", false, Extension::DISABLE_USER_ACTION,
6583 Extension::DISABLE_USER_ACTION, true },
6584 // Legacy case (<M45): No disable reasons come in from Sync (see
6585 // crbug.com/484214). After installation, the reason should be set to
6586 // DISABLE_UNKNOWN_FROM_SYNC.
6587 { "Legacy", false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC, true },
6588 // If the extension came in disabled due to a permissions increase, then the
6589 // user has *not* approved the permissions, and they shouldn't be granted.
6590 // crbug.com/484214
6591 { "PermissionsIncrease", false, Extension::DISABLE_PERMISSIONS_INCREASE,
6592 Extension::DISABLE_PERMISSIONS_INCREASE, false },
6595 for (const TestCase& test_case : test_cases) {
6596 SCOPED_TRACE(test_case.name);
6598 sync_pb::EntitySpecifics specifics;
6599 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6600 ext_specifics->set_id(good_crx);
6601 ext_specifics->set_version(base::Version("1").GetString());
6602 ext_specifics->set_enabled(test_case.sync_enabled);
6603 if (test_case.sync_disable_reasons != -1)
6604 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6606 syncer::SyncData sync_data =
6607 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6608 syncer::SyncChange sync_change(FROM_HERE,
6609 syncer::SyncChange::ACTION_UPDATE,
6610 sync_data);
6611 syncer::SyncChangeList list(1, sync_change);
6612 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6614 ASSERT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
6615 UpdateExtension(good_crx, path, test_case.sync_enabled ? ENABLED
6616 : DISABLED);
6617 EXPECT_EQ(test_case.expect_disable_reasons,
6618 prefs->GetDisableReasons(good_crx));
6619 scoped_refptr<const PermissionSet> permissions(
6620 prefs->GetGrantedPermissions(good_crx));
6621 EXPECT_EQ(test_case.expect_permissions_granted, !permissions->IsEmpty());
6622 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6624 // Remove the extension again, so we can install it again for the next case.
6625 UninstallExtension(good_crx, false,
6626 test_case.sync_enabled ? Extension::ENABLED
6627 : Extension::DISABLED);
6631 TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
6632 InitializeExtensionServiceWithUpdater();
6633 syncer::FakeSyncChangeProcessor processor;
6634 extension_sync_service()->MergeDataAndStartSyncing(
6635 syncer::EXTENSIONS,
6636 syncer::SyncDataList(),
6637 scoped_ptr<syncer::SyncChangeProcessor>(
6638 new syncer::FakeSyncChangeProcessor),
6639 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6641 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6642 TerminateExtension(good_crx);
6643 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6644 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6646 sync_pb::EntitySpecifics specifics;
6647 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6648 ext_specifics->set_id(good_crx);
6649 ext_specifics->set_version(
6650 service()->GetInstalledExtension(good_crx)->version()->GetString());
6651 ext_specifics->set_enabled(false);
6652 ext_specifics->set_incognito_enabled(true);
6653 syncer::SyncData sync_data =
6654 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6655 syncer::SyncChange sync_change(FROM_HERE,
6656 syncer::SyncChange::ACTION_UPDATE,
6657 sync_data);
6658 syncer::SyncChangeList list(1);
6659 list[0] = sync_change;
6661 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6662 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6663 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6665 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6668 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
6669 InitializeExtensionServiceWithUpdater();
6670 syncer::FakeSyncChangeProcessor processor;
6671 extension_sync_service()->MergeDataAndStartSyncing(
6672 syncer::EXTENSIONS,
6673 syncer::SyncDataList(),
6674 scoped_ptr<syncer::SyncChangeProcessor>(
6675 new syncer::FakeSyncChangeProcessor),
6676 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6678 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6679 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6680 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6682 sync_pb::EntitySpecifics specifics;
6683 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6684 ext_specifics->set_id(good_crx);
6685 ext_specifics->set_enabled(true);
6687 const base::Version installed_version =
6688 *service()->GetInstalledExtension(good_crx)->version();
6691 ext_specifics->set_version(installed_version.GetString());
6692 syncer::SyncData sync_data =
6693 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6694 syncer::SyncChange sync_change(FROM_HERE,
6695 syncer::SyncChange::ACTION_UPDATE,
6696 sync_data);
6697 syncer::SyncChangeList list(1, sync_change);
6699 // Should do nothing if extension version == sync version.
6700 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6701 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6702 // Make sure the version we'll send back to sync didn't change.
6703 syncer::SyncDataList data =
6704 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6705 ASSERT_EQ(1u, data.size());
6706 scoped_ptr<ExtensionSyncData> extension_data =
6707 ExtensionSyncData::CreateFromSyncData(data[0]);
6708 ASSERT_TRUE(extension_data);
6709 EXPECT_TRUE(installed_version.Equals(extension_data->version()));
6712 // Should do nothing if extension version > sync version.
6714 ext_specifics->set_version("0.0.0.0");
6715 syncer::SyncData sync_data =
6716 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6717 syncer::SyncChange sync_change(FROM_HERE,
6718 syncer::SyncChange::ACTION_UPDATE,
6719 sync_data);
6720 syncer::SyncChangeList list(1, sync_change);
6722 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6723 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6724 // Make sure the version we'll send back to sync didn't change.
6725 syncer::SyncDataList data =
6726 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6727 ASSERT_EQ(1u, data.size());
6728 scoped_ptr<ExtensionSyncData> extension_data =
6729 ExtensionSyncData::CreateFromSyncData(data[0]);
6730 ASSERT_TRUE(extension_data);
6731 EXPECT_TRUE(installed_version.Equals(extension_data->version()));
6734 // Should kick off an update if extension version < sync version.
6736 const base::Version new_version("9.9.9.9");
6737 ext_specifics->set_version(new_version.GetString());
6738 syncer::SyncData sync_data =
6739 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6740 syncer::SyncChange sync_change(FROM_HERE,
6741 syncer::SyncChange::ACTION_UPDATE,
6742 sync_data);
6743 syncer::SyncChangeList list(1, sync_change);
6745 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6746 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6747 // Make sure that we'll send the NEW version back to sync, even though we
6748 // haven't actually updated yet. This is to prevent the data in sync from
6749 // flip-flopping back and forth until all clients are up to date.
6750 syncer::SyncDataList data =
6751 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6752 ASSERT_EQ(1u, data.size());
6753 scoped_ptr<ExtensionSyncData> extension_data =
6754 ExtensionSyncData::CreateFromSyncData(data[0]);
6755 ASSERT_TRUE(extension_data);
6756 EXPECT_TRUE(new_version.Equals(extension_data->version()));
6759 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6762 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
6763 InitializeExtensionServiceWithUpdater();
6764 syncer::FakeSyncChangeProcessor processor;
6765 extension_sync_service()->MergeDataAndStartSyncing(
6766 syncer::EXTENSIONS,
6767 syncer::SyncDataList(),
6768 scoped_ptr<syncer::SyncChangeProcessor>(
6769 new syncer::FakeSyncChangeProcessor),
6770 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6772 sync_pb::EntitySpecifics specifics;
6773 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6774 ext_specifics->set_id(good_crx);
6775 ext_specifics->set_enabled(false);
6776 ext_specifics->set_incognito_enabled(true);
6777 ext_specifics->set_update_url("http://www.google.com/");
6778 ext_specifics->set_version("1.2.3.4");
6779 syncer::SyncData sync_data =
6780 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6781 syncer::SyncChange sync_change(FROM_HERE,
6782 syncer::SyncChange::ACTION_UPDATE,
6783 sync_data);
6784 syncer::SyncChangeList list(1);
6785 list[0] = sync_change;
6787 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6788 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6789 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6790 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6791 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6792 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6794 const extensions::PendingExtensionInfo* info;
6795 EXPECT_TRUE(
6796 (info = service()->pending_extension_manager()->GetById(good_crx)));
6797 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
6798 EXPECT_TRUE(info->is_from_sync());
6799 EXPECT_EQ(Manifest::INTERNAL, info->install_source());
6800 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
6803 TEST_F(ExtensionServiceTest, ProcessSyncDataEnableDisable) {
6804 InitializeEmptyExtensionService();
6805 extension_sync_service()->MergeDataAndStartSyncing(
6806 syncer::EXTENSIONS,
6807 syncer::SyncDataList(),
6808 scoped_ptr<syncer::SyncChangeProcessor>(
6809 new syncer::FakeSyncChangeProcessor),
6810 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6812 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6814 struct TestCase {
6815 const char* name; // For failure output only.
6816 // Set of disable reasons before any Sync data comes in. If this is != 0,
6817 // the extension is disabled.
6818 int previous_disable_reasons;
6819 bool sync_enable; // The enabled flag coming in from Sync.
6820 // The disable reason(s) coming in from Sync, or -1 for "not set".
6821 int sync_disable_reasons;
6822 // The expected set of disable reasons after processing the Sync update. The
6823 // extension should be disabled iff this is != 0.
6824 int expect_disable_reasons;
6825 } test_cases[] = {
6826 { "NopEnable", 0, true, 0, 0 },
6827 { "NopDisable", Extension::DISABLE_USER_ACTION, false,
6828 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6829 { "Disable", 0, false, Extension::DISABLE_USER_ACTION,
6830 Extension::DISABLE_USER_ACTION },
6831 { "DisableLegacy", 0, false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC },
6832 { "AddDisableReason", Extension::DISABLE_REMOTE_INSTALL, false,
6833 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION,
6834 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION },
6835 { "AddDisableReasonLegacy", Extension::DISABLE_USER_ACTION, false, -1,
6836 Extension::DISABLE_USER_ACTION | Extension::DISABLE_UNKNOWN_FROM_SYNC},
6837 { "RemoveDisableReason",
6838 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION, false,
6839 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6840 { "Enable", Extension::DISABLE_USER_ACTION, true, 0, 0 },
6841 { "EnableLegacy", Extension::DISABLE_USER_ACTION, true, -1, 0 },
6844 for (const TestCase& test_case : test_cases) {
6845 SCOPED_TRACE(test_case.name);
6847 std::string id;
6848 std::string version;
6849 // Don't keep |extension| around longer than necessary.
6851 const Extension* extension =
6852 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6853 // The extension should now be installed and enabled.
6854 ASSERT_TRUE(extension);
6855 id = extension->id();
6856 version = extension->VersionString();
6858 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6860 // Disable it if the test case says so.
6861 if (test_case.previous_disable_reasons) {
6862 service()->DisableExtension(id, test_case.previous_disable_reasons);
6863 ASSERT_TRUE(registry()->disabled_extensions().Contains(id));
6866 // Now a sync update comes in.
6867 sync_pb::EntitySpecifics specifics;
6868 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6869 ext_specifics->set_id(id);
6870 ext_specifics->set_enabled(test_case.sync_enable);
6871 ext_specifics->set_version(version);
6872 if (test_case.sync_disable_reasons != -1)
6873 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6875 syncer::SyncData sync_data =
6876 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6877 syncer::SyncChange sync_change(FROM_HERE,
6878 syncer::SyncChange::ACTION_UPDATE,
6879 sync_data);
6880 syncer::SyncChangeList list(1, sync_change);
6881 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6883 // Check expectations.
6884 const bool expect_enabled = !test_case.expect_disable_reasons;
6885 EXPECT_EQ(expect_enabled, service()->IsExtensionEnabled(id));
6886 EXPECT_EQ(test_case.expect_disable_reasons, prefs->GetDisableReasons(id));
6888 // Remove the extension again, so we can install it again for the next case.
6889 UninstallExtension(id, false, expect_enabled ? Extension::ENABLED
6890 : Extension::DISABLED);
6894 TEST_F(ExtensionServiceTest, ProcessSyncDataPermissionApproval) {
6895 // This is the update URL specified in the test extension. Setting it here is
6896 // necessary to make it considered syncable.
6897 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6898 switches::kAppsGalleryUpdateURL,
6899 "http://localhost/autoupdate/updates.xml");
6901 InitializeEmptyExtensionService();
6902 extension_sync_service()->MergeDataAndStartSyncing(
6903 syncer::EXTENSIONS,
6904 syncer::SyncDataList(),
6905 scoped_ptr<syncer::SyncChangeProcessor>(
6906 new syncer::FakeSyncChangeProcessor),
6907 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6909 const base::FilePath base_path =
6910 data_dir().AppendASCII("permissions_increase");
6911 const base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
6912 const base::FilePath path_v1 = base_path.AppendASCII("v1");
6913 const base::FilePath path_v2 = base_path.AppendASCII("v2");
6915 base::ScopedTempDir crx_dir;
6916 ASSERT_TRUE(crx_dir.CreateUniqueTempDir());
6917 const base::FilePath crx_path_v1 = crx_dir.path().AppendASCII("temp1.crx");
6918 PackCRX(path_v1, pem_path, crx_path_v1);
6919 const base::FilePath crx_path_v2 = crx_dir.path().AppendASCII("temp2.crx");
6920 PackCRX(path_v2, pem_path, crx_path_v2);
6922 const std::string v1("1");
6923 const std::string v2("2");
6925 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6927 struct TestCase {
6928 const char* name; // For failure output only.
6929 const std::string& sync_version; // The version coming in from Sync.
6930 // The disable reason(s) coming in from Sync, or -1 for "not set".
6931 int sync_disable_reasons;
6932 // Whether the extension's permissions should be auto-granted.
6933 bool expect_permissions_granted;
6934 } test_cases[] = {
6935 // Sync tells us to re-enable an older version. No permissions should be
6936 // granted, since we can't be sure if the user actually approved the right
6937 // set of permissions. Note that the extension will get disabled again the
6938 // next time ExtensionService::CheckPermissionsIncrease runs because of the
6939 // extra permissions.
6940 { "OldVersion", v1, 0, false },
6941 // Legacy case: Sync tells us to re-enable the extension, but doesn't
6942 // specify disable reasons. No permissions should be granted.
6943 { "Legacy", v2, -1, false },
6944 // Sync tells us to re-enable the extension and explicitly removes the
6945 // disable reasons. Now the extension should have its permissions granted.
6946 { "GrantPermissions", v2, 0, true },
6949 for (const TestCase& test_case : test_cases) {
6950 SCOPED_TRACE(test_case.name);
6952 std::string id;
6953 // Don't keep |extension| around longer than necessary (it'll be destroyed
6954 // during updating).
6956 const Extension* extension = InstallCRX(crx_path_v1, INSTALL_NEW);
6957 // The extension should now be installed and enabled.
6958 ASSERT_TRUE(extension);
6959 ASSERT_EQ(v1, extension->VersionString());
6960 id = extension->id();
6962 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6964 scoped_refptr<const PermissionSet> granted_permissions_v1(
6965 prefs->GetGrantedPermissions(id));
6967 // Update to a new version with increased permissions.
6968 UpdateExtension(id, crx_path_v2, DISABLED);
6970 // Now the extension should be disabled due to a permissions increase.
6972 const Extension* extension =
6973 registry()->disabled_extensions().GetByID(id);
6974 ASSERT_TRUE(extension);
6975 ASSERT_EQ(v2, extension->VersionString());
6977 ASSERT_TRUE(prefs->HasDisableReason(
6978 id, Extension::DISABLE_PERMISSIONS_INCREASE));
6980 // No new permissions should have been granted.
6981 scoped_refptr<const PermissionSet> granted_permissions_v2(
6982 prefs->GetGrantedPermissions(id));
6983 ASSERT_EQ(*granted_permissions_v1, *granted_permissions_v2);
6985 // Now a sync update comes in.
6986 sync_pb::EntitySpecifics specifics;
6987 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6988 ext_specifics->set_id(id);
6989 ext_specifics->set_enabled(true);
6990 ext_specifics->set_version(test_case.sync_version);
6991 if (test_case.sync_disable_reasons != -1)
6992 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6994 syncer::SyncData sync_data =
6995 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6996 syncer::SyncChange sync_change(FROM_HERE,
6997 syncer::SyncChange::ACTION_UPDATE,
6998 sync_data);
6999 syncer::SyncChangeList list(1, sync_change);
7000 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
7002 // Check expectations.
7003 EXPECT_TRUE(registry()->GetExtensionById(id, ExtensionRegistry::ENABLED));
7004 scoped_refptr<const PermissionSet> granted_permissions(
7005 prefs->GetGrantedPermissions(id));
7006 if (test_case.expect_permissions_granted) {
7007 scoped_refptr<const PermissionSet> active_permissions(
7008 prefs->GetActivePermissions(id));
7009 EXPECT_EQ(*granted_permissions, *active_permissions);
7010 } else {
7011 EXPECT_EQ(*granted_permissions, *granted_permissions_v1);
7013 EXPECT_EQ(Extension::DISABLE_NONE, prefs->GetDisableReasons(id));
7015 // Remove the extension again, so we can install it again for the next case.
7016 UninstallExtension(id, false);
7020 #if defined(ENABLE_SUPERVISED_USERS)
7021 class ScopedSupervisedUserServiceDelegate
7022 : public SupervisedUserService::Delegate {
7023 public:
7024 explicit ScopedSupervisedUserServiceDelegate(SupervisedUserService* service)
7025 : service_(service) {
7026 service_->SetDelegate(this);
7028 ~ScopedSupervisedUserServiceDelegate() override {
7029 service_->SetDelegate(nullptr);
7032 // This prevents the legacy supervised user init code from running.
7033 bool SetActive(bool active) override { return true; }
7035 private:
7036 SupervisedUserService* service_;
7039 class MockPermissionRequestCreator : public PermissionRequestCreator {
7040 public:
7041 MockPermissionRequestCreator() {}
7042 ~MockPermissionRequestCreator() override {}
7044 bool IsEnabled() const override { return true; }
7046 void CreateURLAccessRequest(const GURL& url_requested,
7047 const SuccessCallback& callback) override {
7048 FAIL();
7051 MOCK_METHOD2(CreateExtensionUpdateRequest,
7052 void(const std::string& id,
7053 const SupervisedUserService::SuccessCallback& callback));
7055 private:
7056 DISALLOW_COPY_AND_ASSIGN(MockPermissionRequestCreator);
7059 TEST_F(ExtensionServiceTest, SupervisedUserInstallOnlyAllowedByCustodian) {
7060 ExtensionServiceInitParams params = CreateDefaultInitParams();
7061 params.profile_is_supervised = true;
7062 InitializeExtensionService(params);
7064 SupervisedUserService* supervised_user_service =
7065 SupervisedUserServiceFactory::GetForProfile(profile());
7066 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7067 supervised_user_service->Init();
7069 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7070 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7071 const Extension* extensions[] = {
7072 InstallCRX(path1, INSTALL_FAILED),
7073 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7076 // Only the extension with the "installed by custodian" flag should have been
7077 // installed and enabled.
7078 EXPECT_FALSE(extensions[0]);
7079 ASSERT_TRUE(extensions[1]);
7080 EXPECT_TRUE(registry()->enabled_extensions().Contains(extensions[1]->id()));
7083 TEST_F(ExtensionServiceTest, SupervisedUserPreinstalledExtension) {
7084 ExtensionServiceInitParams params = CreateDefaultInitParams();
7085 // Do *not* set the profile to supervised here!
7086 InitializeExtensionService(params);
7088 SupervisedUserService* supervised_user_service =
7089 SupervisedUserServiceFactory::GetForProfile(profile());
7090 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7091 supervised_user_service->Init();
7093 // Install an extension.
7094 base::FilePath path = data_dir().AppendASCII("good.crx");
7095 const Extension* extension = InstallCRX(path, INSTALL_NEW);
7096 std::string id = extension->id();
7098 // Now make the profile supervised.
7099 profile()->AsTestingProfile()->SetSupervisedUserId(
7100 supervised_users::kChildAccountSUID);
7102 // The extension should not be enabled anymore.
7103 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7106 TEST_F(ExtensionServiceTest, SupervisedUserUpdateWithoutPermissionIncrease) {
7107 ExtensionServiceInitParams params = CreateDefaultInitParams();
7108 params.profile_is_supervised = true;
7109 InitializeExtensionService(params);
7111 SupervisedUserService* supervised_user_service =
7112 SupervisedUserServiceFactory::GetForProfile(profile());
7113 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7114 supervised_user_service->Init();
7116 base::FilePath base_path = data_dir().AppendASCII("autoupdate");
7117 base::FilePath pem_path = base_path.AppendASCII("key.pem");
7119 base::FilePath path = base_path.AppendASCII("v1");
7120 const Extension* extension =
7121 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
7122 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7123 // The extension must now be installed and enabled.
7124 ASSERT_TRUE(extension);
7125 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7127 // Save the id, as the extension object will be destroyed during updating.
7128 std::string id = extension->id();
7130 std::string old_version = extension->VersionString();
7132 // Update to a new version.
7133 path = base_path.AppendASCII("v2");
7134 PackCRXAndUpdateExtension(id, path, pem_path, ENABLED);
7136 // The extension should still be there and enabled.
7137 extension = registry()->enabled_extensions().GetByID(id);
7138 ASSERT_TRUE(extension);
7139 // The version should have changed.
7140 EXPECT_NE(extension->VersionString(), old_version);
7143 // Helper class that allows us to parameterize the UpdateWithPermissionIncrease
7144 // test over |bool need_custodian_approval|.
7145 class ExtensionServiceTestSupervisedUserPermissionIncrease :
7146 public ExtensionServiceTest, public testing::WithParamInterface<bool> {};
7148 TEST_P(ExtensionServiceTestSupervisedUserPermissionIncrease,
7149 UpdateWithPermissionIncrease) {
7150 bool need_custodian_approval = GetParam();
7151 base::FieldTrialList field_trial_list(new base::MockEntropyProvider());
7152 base::FieldTrialList::CreateFieldTrial(
7153 "SupervisedUserExtensionPermissionIncrease",
7154 need_custodian_approval ? "NeedCustodianApproval" : "");
7156 ExtensionServiceInitParams params = CreateDefaultInitParams();
7157 params.profile_is_supervised = true;
7158 InitializeExtensionService(params);
7160 SupervisedUserService* supervised_user_service =
7161 SupervisedUserServiceFactory::GetForProfile(profile());
7162 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7163 supervised_user_service->Init();
7164 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
7165 supervised_user_service->AddPermissionRequestCreator(
7166 make_scoped_ptr(creator));
7168 base::FilePath base_path = data_dir().AppendASCII("permissions_increase");
7169 base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
7171 base::FilePath path = base_path.AppendASCII("v1");
7172 const Extension* extension =
7173 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
7174 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7175 // The extension must now be installed and enabled.
7176 ASSERT_TRUE(extension);
7177 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7179 // Save the id, as the extension object will be destroyed during updating.
7180 std::string id = extension->id();
7182 std::string old_version = extension->VersionString();
7184 // Update to a new version with increased permissions.
7185 EXPECT_CALL(*creator, CreateExtensionUpdateRequest(id + ":2", testing::_))
7186 .Times(need_custodian_approval ? 1 : 0);
7187 path = base_path.AppendASCII("v2");
7188 PackCRXAndUpdateExtension(id, path, pem_path, DISABLED);
7190 // The extension should still be there, but disabled.
7191 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7192 extension = registry()->disabled_extensions().GetByID(id);
7193 ASSERT_TRUE(extension);
7194 // The version should have changed.
7195 EXPECT_NE(extension->VersionString(), old_version);
7197 INSTANTIATE_TEST_CASE_P(NeedCustodianApproval,
7198 ExtensionServiceTestSupervisedUserPermissionIncrease,
7199 testing::Bool());
7201 TEST_F(ExtensionServiceTest,
7202 SupervisedUserSyncUninstallByCustodianSkipsPolicy) {
7203 InitializeEmptyExtensionService();
7204 extension_sync_service()->MergeDataAndStartSyncing(
7205 syncer::EXTENSIONS,
7206 syncer::SyncDataList(),
7207 scoped_ptr<syncer::SyncChangeProcessor>(
7208 new syncer::FakeSyncChangeProcessor),
7209 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
7211 // Install two extensions.
7212 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7213 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7214 const Extension* extensions[] = {
7215 InstallCRX(path1, INSTALL_NEW),
7216 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7219 // Add a policy provider that will disallow any changes.
7220 extensions::TestManagementPolicyProvider provider(
7221 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
7222 GetManagementPolicy()->RegisterProvider(&provider);
7224 // Create a sync deletion for each extension.
7225 syncer::SyncChangeList change_list;
7226 for (size_t i = 0; i < arraysize(extensions); i++) {
7227 const std::string& id = extensions[i]->id();
7228 sync_pb::EntitySpecifics specifics;
7229 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
7230 ext_specifics->set_id(id);
7231 ext_specifics->set_version("1.0");
7232 ext_specifics->set_installed_by_custodian(
7233 extensions[i]->was_installed_by_custodian());
7234 syncer::SyncData sync_data =
7235 syncer::SyncData::CreateLocalData(id, "Name", specifics);
7236 change_list.push_back(syncer::SyncChange(FROM_HERE,
7237 syncer::SyncChange::ACTION_DELETE,
7238 sync_data));
7241 // Save the extension ids, as uninstalling destroys the Extension instance.
7242 std::string extension_ids[] = {
7243 extensions[0]->id(),
7244 extensions[1]->id()
7247 // Now apply the uninstallations.
7248 extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
7250 // Uninstalling the extension without installed_by_custodian should have been
7251 // blocked by policy, so it should still be there.
7252 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_ids[0]));
7254 // But installed_by_custodian should result in bypassing the policy check.
7255 EXPECT_FALSE(
7256 registry()->GenerateInstalledExtensionsSet()->Contains(extension_ids[1]));
7258 #endif // defined(ENABLE_SUPERVISED_USERS)
7260 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
7261 InitializeEmptyExtensionService();
7263 base::FilePath path = data_dir().AppendASCII("good.crx");
7264 InstallCRX(path, INSTALL_NEW);
7265 ValidatePrefKeyCount(1u);
7266 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7267 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7269 extensions::PendingExtensionManager* pending =
7270 service()->pending_extension_manager();
7271 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7273 // Skip install when the location is the same.
7274 EXPECT_FALSE(
7275 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
7276 std::string(),
7277 GURL(kGoodUpdateURL),
7278 Manifest::INTERNAL,
7279 Extension::NO_FLAGS,
7280 false));
7281 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7283 // Install when the location has higher priority.
7284 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
7285 kGoodId,
7286 std::string(),
7287 GURL(kGoodUpdateURL),
7288 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7289 Extension::NO_FLAGS,
7290 false));
7291 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7293 // Try the low priority again. Should be rejected.
7294 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(
7295 kGoodId,
7296 std::string(),
7297 GURL(kGoodUpdateURL),
7298 Manifest::EXTERNAL_PREF_DOWNLOAD,
7299 Extension::NO_FLAGS,
7300 false));
7301 // The existing record should still be present in the pending extension
7302 // manager.
7303 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7305 pending->Remove(kGoodId);
7307 // Skip install when the location has the same priority as the installed
7308 // location.
7309 EXPECT_FALSE(
7310 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
7311 std::string(),
7312 GURL(kGoodUpdateURL),
7313 Manifest::INTERNAL,
7314 Extension::NO_FLAGS,
7315 false));
7317 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7320 TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
7321 Version older_version("0.1.0.0");
7322 Version newer_version("2.0.0.0");
7324 // We don't want the extension to be installed. A path that doesn't
7325 // point to a valid CRX ensures this.
7326 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
7328 const int kCreationFlags = 0;
7329 const bool kDontMarkAcknowledged = false;
7330 const bool kDontInstallImmediately = false;
7332 InitializeEmptyExtensionService();
7334 // The test below uses install source constants to test that
7335 // priority is enforced. It assumes a specific ranking of install
7336 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
7337 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
7338 // The following assertions verify these assumptions:
7339 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
7340 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
7341 Manifest::EXTERNAL_PREF));
7342 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
7343 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
7344 Manifest::INTERNAL));
7345 ASSERT_EQ(Manifest::EXTERNAL_PREF,
7346 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
7347 Manifest::INTERNAL));
7349 extensions::PendingExtensionManager* pending =
7350 service()->pending_extension_manager();
7351 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7354 // Simulate an external source adding the extension as INTERNAL.
7355 content::WindowedNotificationObserver observer(
7356 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7357 content::NotificationService::AllSources());
7358 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7359 kGoodId,
7360 &older_version,
7361 kInvalidPathToCrx,
7362 Manifest::INTERNAL,
7363 kCreationFlags,
7364 kDontMarkAcknowledged,
7365 kDontInstallImmediately));
7366 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7367 observer.Wait();
7368 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7372 // Simulate an external source adding the extension as EXTERNAL_PREF.
7373 content::WindowedNotificationObserver observer(
7374 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7375 content::NotificationService::AllSources());
7376 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7377 kGoodId,
7378 &older_version,
7379 kInvalidPathToCrx,
7380 Manifest::EXTERNAL_PREF,
7381 kCreationFlags,
7382 kDontMarkAcknowledged,
7383 kDontInstallImmediately));
7384 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7385 observer.Wait();
7386 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7389 // Simulate an external source adding as EXTERNAL_PREF again.
7390 // This is rejected because the version and the location are the same as
7391 // the previous installation, which is still pending.
7392 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7393 kGoodId,
7394 &older_version,
7395 kInvalidPathToCrx,
7396 Manifest::EXTERNAL_PREF,
7397 kCreationFlags,
7398 kDontMarkAcknowledged,
7399 kDontInstallImmediately));
7400 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7402 // Try INTERNAL again. Should fail.
7403 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7404 kGoodId,
7405 &older_version,
7406 kInvalidPathToCrx,
7407 Manifest::INTERNAL,
7408 kCreationFlags,
7409 kDontMarkAcknowledged,
7410 kDontInstallImmediately));
7411 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7414 // Now the registry adds the extension.
7415 content::WindowedNotificationObserver observer(
7416 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7417 content::NotificationService::AllSources());
7418 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7419 kGoodId,
7420 &older_version,
7421 kInvalidPathToCrx,
7422 Manifest::EXTERNAL_REGISTRY,
7423 kCreationFlags,
7424 kDontMarkAcknowledged,
7425 kDontInstallImmediately));
7426 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7427 observer.Wait();
7428 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7431 // Registry outranks both external pref and internal, so both fail.
7432 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7433 kGoodId,
7434 &older_version,
7435 kInvalidPathToCrx,
7436 Manifest::EXTERNAL_PREF,
7437 kCreationFlags,
7438 kDontMarkAcknowledged,
7439 kDontInstallImmediately));
7440 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7442 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7443 kGoodId,
7444 &older_version,
7445 kInvalidPathToCrx,
7446 Manifest::INTERNAL,
7447 kCreationFlags,
7448 kDontMarkAcknowledged,
7449 kDontInstallImmediately));
7450 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7452 pending->Remove(kGoodId);
7454 // Install the extension.
7455 base::FilePath path = data_dir().AppendASCII("good.crx");
7456 const Extension* ext = InstallCRX(path, INSTALL_NEW);
7457 ValidatePrefKeyCount(1u);
7458 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7459 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7461 // Now test the logic of OnExternalExtensionFileFound() when the extension
7462 // being added is already installed.
7464 // Tests assume |older_version| is less than the installed version, and
7465 // |newer_version| is greater. Verify this:
7466 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
7467 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
7469 // An external install for the same location should fail if the version is
7470 // older, or the same, and succeed if the version is newer.
7472 // Older than the installed version...
7473 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7474 kGoodId,
7475 &older_version,
7476 kInvalidPathToCrx,
7477 Manifest::INTERNAL,
7478 kCreationFlags,
7479 kDontMarkAcknowledged,
7480 kDontInstallImmediately));
7481 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7483 // Same version as the installed version...
7484 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7485 kGoodId,
7486 ext->version(),
7487 kInvalidPathToCrx,
7488 Manifest::INTERNAL,
7489 kCreationFlags,
7490 kDontMarkAcknowledged,
7491 kDontInstallImmediately));
7492 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7494 // Newer than the installed version...
7495 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7496 kGoodId,
7497 &newer_version,
7498 kInvalidPathToCrx,
7499 Manifest::INTERNAL,
7500 kCreationFlags,
7501 kDontMarkAcknowledged,
7502 kDontInstallImmediately));
7503 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7505 // An external install for a higher priority install source should succeed
7506 // if the version is greater. |older_version| is not...
7507 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7508 kGoodId,
7509 &older_version,
7510 kInvalidPathToCrx,
7511 Manifest::EXTERNAL_PREF,
7512 kCreationFlags,
7513 kDontMarkAcknowledged,
7514 kDontInstallImmediately));
7515 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7517 // |newer_version| is newer.
7518 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7519 kGoodId,
7520 &newer_version,
7521 kInvalidPathToCrx,
7522 Manifest::EXTERNAL_PREF,
7523 kCreationFlags,
7524 kDontMarkAcknowledged,
7525 kDontInstallImmediately));
7526 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7528 // An external install for an even higher priority install source should
7529 // succeed if the version is greater.
7530 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7531 kGoodId,
7532 &newer_version,
7533 kInvalidPathToCrx,
7534 Manifest::EXTERNAL_REGISTRY,
7535 kCreationFlags,
7536 kDontMarkAcknowledged,
7537 kDontInstallImmediately));
7538 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7540 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
7541 // adding from external pref will now fail.
7542 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7543 kGoodId,
7544 &newer_version,
7545 kInvalidPathToCrx,
7546 Manifest::EXTERNAL_PREF,
7547 kCreationFlags,
7548 kDontMarkAcknowledged,
7549 kDontInstallImmediately));
7550 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7553 TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
7554 Version kVersion123("1.2.3");
7555 Version kVersion124("1.2.4");
7556 Version kVersion125("1.2.5");
7557 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
7558 const int kCreationFlags = 0;
7559 const bool kDontMarkAcknowledged = false;
7560 const bool kDontInstallImmediately = false;
7562 InitializeEmptyExtensionService();
7564 extensions::PendingExtensionManager* pending =
7565 service()->pending_extension_manager();
7566 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7568 // An external provider starts installing from a local crx.
7569 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7570 kGoodId,
7571 &kVersion123,
7572 kInvalidPathToCrx,
7573 Manifest::EXTERNAL_PREF,
7574 kCreationFlags,
7575 kDontMarkAcknowledged,
7576 kDontInstallImmediately));
7577 const extensions::PendingExtensionInfo* info;
7578 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7579 EXPECT_TRUE(info->version().IsValid());
7580 EXPECT_TRUE(info->version().Equals(kVersion123));
7582 // Adding a newer version overrides the currently pending version.
7583 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7584 kGoodId,
7585 &kVersion124,
7586 kInvalidPathToCrx,
7587 Manifest::EXTERNAL_PREF,
7588 kCreationFlags,
7589 kDontMarkAcknowledged,
7590 kDontInstallImmediately));
7591 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7592 EXPECT_TRUE(info->version().IsValid());
7593 EXPECT_TRUE(info->version().Equals(kVersion124));
7595 // Adding an older version fails.
7596 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7597 kGoodId,
7598 &kVersion123,
7599 kInvalidPathToCrx,
7600 Manifest::EXTERNAL_PREF,
7601 kCreationFlags,
7602 kDontMarkAcknowledged,
7603 kDontInstallImmediately));
7604 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7605 EXPECT_TRUE(info->version().IsValid());
7606 EXPECT_TRUE(info->version().Equals(kVersion124));
7608 // Adding an older version fails even when coming from a higher-priority
7609 // location.
7610 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7611 kGoodId,
7612 &kVersion123,
7613 kInvalidPathToCrx,
7614 Manifest::EXTERNAL_REGISTRY,
7615 kCreationFlags,
7616 kDontMarkAcknowledged,
7617 kDontInstallImmediately));
7618 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7619 EXPECT_TRUE(info->version().IsValid());
7620 EXPECT_TRUE(info->version().Equals(kVersion124));
7622 // Adding the latest version from the webstore overrides a specific version.
7623 GURL kUpdateUrl("http://example.com/update");
7624 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
7625 kGoodId,
7626 std::string(),
7627 kUpdateUrl,
7628 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7629 Extension::NO_FLAGS,
7630 false));
7631 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7632 EXPECT_FALSE(info->version().IsValid());
7635 // This makes sure we can package and install CRX files that use whitelisted
7636 // permissions.
7637 TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
7638 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
7639 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
7640 extensions::switches::kWhitelistedExtensionID, test_id);
7642 InitializeEmptyExtensionService();
7643 base::FilePath path = data_dir().AppendASCII("permissions");
7644 base::FilePath pem_path = path
7645 .AppendASCII("whitelist.pem");
7646 path = path
7647 .AppendASCII("whitelist");
7649 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
7650 EXPECT_EQ(0u, GetErrors().size());
7651 ASSERT_EQ(1u, registry()->enabled_extensions().size());
7652 EXPECT_EQ(test_id, extension->id());
7655 // Test that when multiple sources try to install an extension,
7656 // we consistently choose the right one. To make tests easy to read,
7657 // methods that fake requests to install crx files in several ways
7658 // are provided.
7659 class ExtensionSourcePriorityTest : public ExtensionServiceTest {
7660 public:
7661 void SetUp() override {
7662 ExtensionServiceTest::SetUp();
7664 // All tests use a single extension. Put the id and path in member vars
7665 // that all methods can read.
7666 crx_id_ = kGoodId;
7667 crx_path_ = data_dir().AppendASCII("good.crx");
7670 // Fake an external source adding a URL to fetch an extension from.
7671 bool AddPendingExternalPrefUrl() {
7672 return service()->pending_extension_manager()->AddFromExternalUpdateUrl(
7673 crx_id_,
7674 std::string(),
7675 GURL(),
7676 Manifest::EXTERNAL_PREF_DOWNLOAD,
7677 Extension::NO_FLAGS,
7678 false);
7681 // Fake an external file from external_extensions.json.
7682 bool AddPendingExternalPrefFileInstall() {
7683 Version version("1.0.0.0");
7685 return service()->OnExternalExtensionFileFound(crx_id_,
7686 &version,
7687 crx_path_,
7688 Manifest::EXTERNAL_PREF,
7689 Extension::NO_FLAGS,
7690 false,
7691 false);
7694 // Fake a request from sync to install an extension.
7695 bool AddPendingSyncInstall() {
7696 return service()->pending_extension_manager()->AddFromSync(
7697 crx_id_,
7698 GURL(kGoodUpdateURL),
7699 base::Version(),
7700 &IsExtension,
7701 kGoodRemoteInstall,
7702 kGoodInstalledByCustodian);
7705 // Fake a policy install.
7706 bool AddPendingPolicyInstall() {
7707 // Get path to the CRX with id |kGoodId|.
7708 return service()->OnExternalExtensionUpdateUrlFound(
7709 crx_id_,
7710 std::string(),
7711 GURL(),
7712 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7713 Extension::NO_FLAGS,
7714 false);
7717 // Get the install source of a pending extension.
7718 Manifest::Location GetPendingLocation() {
7719 const extensions::PendingExtensionInfo* info;
7720 EXPECT_TRUE(
7721 (info = service()->pending_extension_manager()->GetById(crx_id_)));
7722 return info->install_source();
7725 // Is an extension pending from a sync request?
7726 bool GetPendingIsFromSync() {
7727 const extensions::PendingExtensionInfo* info;
7728 EXPECT_TRUE(
7729 (info = service()->pending_extension_manager()->GetById(crx_id_)));
7730 return info->is_from_sync();
7733 // Is the CRX id these tests use pending?
7734 bool IsCrxPending() {
7735 return service()->pending_extension_manager()->IsIdPending(crx_id_);
7738 // Is an extension installed?
7739 bool IsCrxInstalled() {
7740 return (service()->GetExtensionById(crx_id_, true) != NULL);
7743 protected:
7744 // All tests use a single extension. Making the id and path member
7745 // vars avoids pasing the same argument to every method.
7746 std::string crx_id_;
7747 base::FilePath crx_path_;
7750 // Test that a pending request for installation of an external CRX from
7751 // an update URL overrides a pending request to install the same extension
7752 // from sync.
7753 TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
7754 InitializeEmptyExtensionService();
7756 ASSERT_FALSE(IsCrxInstalled());
7758 // Install pending extension from sync.
7759 content::WindowedNotificationObserver observer(
7760 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7761 content::NotificationService::AllSources());
7762 EXPECT_TRUE(AddPendingSyncInstall());
7763 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
7764 EXPECT_TRUE(GetPendingIsFromSync());
7765 ASSERT_FALSE(IsCrxInstalled());
7767 // Install pending as external prefs json would.
7768 AddPendingExternalPrefFileInstall();
7769 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
7770 ASSERT_FALSE(IsCrxInstalled());
7772 // Another request from sync should be ignored.
7773 EXPECT_FALSE(AddPendingSyncInstall());
7774 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
7775 ASSERT_FALSE(IsCrxInstalled());
7777 observer.Wait();
7778 VerifyCrxInstall(crx_path_, INSTALL_NEW);
7779 ASSERT_TRUE(IsCrxInstalled());
7782 // Test that an install of an external CRX from an update overrides
7783 // an install of the same extension from sync.
7784 TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
7785 InitializeEmptyExtensionService();
7786 ASSERT_FALSE(IsCrxInstalled());
7788 EXPECT_TRUE(AddPendingSyncInstall());
7789 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
7790 EXPECT_TRUE(GetPendingIsFromSync());
7791 ASSERT_FALSE(IsCrxInstalled());
7793 ASSERT_TRUE(AddPendingExternalPrefUrl());
7794 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
7795 EXPECT_FALSE(GetPendingIsFromSync());
7796 ASSERT_FALSE(IsCrxInstalled());
7798 EXPECT_FALSE(AddPendingSyncInstall());
7799 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
7800 EXPECT_FALSE(GetPendingIsFromSync());
7801 ASSERT_FALSE(IsCrxInstalled());
7804 // Test that an external install request stops sync from installing
7805 // the same extension.
7806 TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
7807 InitializeEmptyExtensionService();
7808 ASSERT_FALSE(IsCrxInstalled());
7810 // External prefs starts an install.
7811 AddPendingExternalPrefFileInstall();
7813 // Crx installer was made, but has not yet run.
7814 ASSERT_FALSE(IsCrxInstalled());
7816 // Before the CRX installer runs, Sync requests that the same extension
7817 // be installed. Should fail, because an external source is pending.
7818 content::WindowedNotificationObserver observer(
7819 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7820 content::NotificationService::AllSources());
7821 ASSERT_FALSE(AddPendingSyncInstall());
7823 // Wait for the external source to install.
7824 observer.Wait();
7825 VerifyCrxInstall(crx_path_, INSTALL_NEW);
7826 ASSERT_TRUE(IsCrxInstalled());
7828 // Now that the extension is installed, sync request should fail
7829 // because the extension is already installed.
7830 ASSERT_FALSE(AddPendingSyncInstall());
7833 // Test that installing an external extension displays a GlobalError.
7834 TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
7835 FeatureSwitch::ScopedOverride prompt(
7836 FeatureSwitch::prompt_for_external_extensions(), true);
7838 InitializeEmptyExtensionService();
7839 MockExtensionProvider* provider =
7840 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7841 AddMockExternalProvider(provider);
7843 service()->external_install_manager()->UpdateExternalExtensionAlert();
7844 // Should return false, meaning there aren't any extensions that the user
7845 // needs to know about.
7846 EXPECT_FALSE(
7847 service()->external_install_manager()->HasExternalInstallError());
7849 // This is a normal extension, installed normally.
7850 // This should NOT trigger an alert.
7851 service()->set_extensions_enabled(true);
7852 base::FilePath path = data_dir().AppendASCII("good.crx");
7853 InstallCRX(path, INSTALL_NEW);
7855 service()->CheckForExternalUpdates();
7856 base::RunLoop().RunUntilIdle();
7857 EXPECT_FALSE(
7858 service()->external_install_manager()->HasExternalInstallError());
7860 // A hosted app, installed externally.
7861 // This should NOT trigger an alert.
7862 provider->UpdateOrAddExtension(
7863 hosted_app, "1.0.0.0", data_dir().AppendASCII("hosted_app.crx"));
7865 content::WindowedNotificationObserver observer(
7866 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7867 content::NotificationService::AllSources());
7868 service()->CheckForExternalUpdates();
7869 observer.Wait();
7870 EXPECT_FALSE(
7871 service()->external_install_manager()->HasExternalInstallError());
7873 // Another normal extension, but installed externally.
7874 // This SHOULD trigger an alert.
7875 provider->UpdateOrAddExtension(
7876 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7878 content::WindowedNotificationObserver observer2(
7879 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7880 content::NotificationService::AllSources());
7881 service()->CheckForExternalUpdates();
7882 observer2.Wait();
7883 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7886 // Test that external extensions are initially disabled, and that enabling
7887 // them clears the prompt.
7888 TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
7889 FeatureSwitch::ScopedOverride prompt(
7890 FeatureSwitch::prompt_for_external_extensions(), true);
7892 InitializeEmptyExtensionService();
7893 MockExtensionProvider* provider =
7894 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7895 AddMockExternalProvider(provider);
7897 provider->UpdateOrAddExtension(
7898 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7900 content::WindowedNotificationObserver observer(
7901 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7902 content::NotificationService::AllSources());
7903 service()->CheckForExternalUpdates();
7904 observer.Wait();
7905 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7906 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
7908 const Extension* extension =
7909 registry()->disabled_extensions().GetByID(page_action);
7910 EXPECT_TRUE(extension);
7911 EXPECT_EQ(page_action, extension->id());
7913 service()->EnableExtension(page_action);
7914 EXPECT_FALSE(
7915 service()->external_install_manager()->HasExternalInstallError());
7916 EXPECT_TRUE(service()->IsExtensionEnabled(page_action));
7919 // Test that installing multiple external extensions works.
7920 // Flaky on windows; http://crbug.com/295757 .
7921 // Causes race conditions with an in-process utility thread, so disable under
7922 // TSan: https://crbug.com/518957
7923 #if defined(OS_WIN) || defined(THREAD_SANITIZER)
7924 #define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
7925 #else
7926 #define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
7927 #endif
7928 TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
7929 FeatureSwitch::ScopedOverride prompt(
7930 FeatureSwitch::prompt_for_external_extensions(), true);
7932 InitializeEmptyExtensionService();
7933 MockExtensionProvider* provider =
7934 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7935 AddMockExternalProvider(provider);
7937 provider->UpdateOrAddExtension(
7938 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7939 provider->UpdateOrAddExtension(
7940 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
7941 provider->UpdateOrAddExtension(
7942 theme_crx, "2.0", data_dir().AppendASCII("theme.crx"));
7944 int count = 3;
7945 content::WindowedNotificationObserver observer(
7946 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7947 base::Bind(&WaitForCountNotificationsCallback, &count));
7948 service()->CheckForExternalUpdates();
7949 observer.Wait();
7950 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7951 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
7952 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
7953 EXPECT_FALSE(service()->IsExtensionEnabled(theme_crx));
7955 service()->EnableExtension(page_action);
7956 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7957 EXPECT_FALSE(service()
7958 ->external_install_manager()
7959 ->HasExternalInstallBubbleForTesting());
7961 service()->EnableExtension(theme_crx);
7962 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7963 EXPECT_FALSE(service()
7964 ->external_install_manager()
7965 ->HasExternalInstallBubbleForTesting());
7967 service()->EnableExtension(good_crx);
7968 EXPECT_FALSE(
7969 service()->external_install_manager()->HasExternalInstallError());
7970 EXPECT_FALSE(service()
7971 ->external_install_manager()
7972 ->HasExternalInstallBubbleForTesting());
7975 // Test that there is a bubble for external extensions that update
7976 // from the webstore if the profile is not new.
7977 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
7978 FeatureSwitch::ScopedOverride prompt(
7979 FeatureSwitch::prompt_for_external_extensions(), true);
7981 // This sets up the ExtensionPrefs used by our ExtensionService to be
7982 // post-first run.
7983 ExtensionServiceInitParams params = CreateDefaultInitParams();
7984 params.is_first_run = false;
7985 InitializeExtensionService(params);
7987 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7988 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7989 data_dir().AppendASCII("update_from_webstore.pem"),
7990 crx_path);
7992 MockExtensionProvider* provider =
7993 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7994 AddMockExternalProvider(provider);
7995 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7997 content::WindowedNotificationObserver observer(
7998 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7999 content::NotificationService::AllSources());
8000 service()->CheckForExternalUpdates();
8001 observer.Wait();
8002 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
8003 EXPECT_TRUE(service()
8004 ->external_install_manager()
8005 ->HasExternalInstallBubbleForTesting());
8006 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
8009 // Test that there is no bubble for external extensions if the profile is new.
8010 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
8011 FeatureSwitch::ScopedOverride prompt(
8012 FeatureSwitch::prompt_for_external_extensions(), true);
8014 InitializeEmptyExtensionService();
8016 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
8017 PackCRX(data_dir().AppendASCII("update_from_webstore"),
8018 data_dir().AppendASCII("update_from_webstore.pem"),
8019 crx_path);
8021 MockExtensionProvider* provider =
8022 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
8023 AddMockExternalProvider(provider);
8024 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
8026 content::WindowedNotificationObserver observer(
8027 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
8028 content::NotificationService::AllSources());
8029 service()->CheckForExternalUpdates();
8030 observer.Wait();
8031 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
8032 EXPECT_FALSE(service()
8033 ->external_install_manager()
8034 ->HasExternalInstallBubbleForTesting());
8035 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
8038 // Test that clicking to remove the extension on an external install warning
8039 // uninstalls the extension.
8040 TEST_F(ExtensionServiceTest, ExternalInstallClickToRemove) {
8041 FeatureSwitch::ScopedOverride prompt(
8042 FeatureSwitch::prompt_for_external_extensions(), true);
8044 ExtensionServiceInitParams params = CreateDefaultInitParams();
8045 params.is_first_run = false;
8046 InitializeExtensionService(params);
8048 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
8049 PackCRX(data_dir().AppendASCII("update_from_webstore"),
8050 data_dir().AppendASCII("update_from_webstore.pem"),
8051 crx_path);
8053 MockExtensionProvider* provider =
8054 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
8055 AddMockExternalProvider(provider);
8056 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
8058 content::WindowedNotificationObserver observer(
8059 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
8060 content::NotificationService::AllSources());
8061 service_->CheckForExternalUpdates();
8062 observer.Wait();
8063 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
8065 // We check both enabled and disabled, since these are "eventually exclusive"
8066 // sets.
8067 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
8068 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8070 // Click the negative response.
8071 service_->external_install_manager()->error_for_testing()->InstallUIAbort(
8072 true);
8073 // The Extension should be uninstalled.
8074 EXPECT_FALSE(registry()->GetExtensionById(updates_from_webstore,
8075 ExtensionRegistry::EVERYTHING));
8076 // The error should be removed.
8077 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
8080 // Test that clicking to keep the extension on an external install warning
8081 // re-enables the extension.
8082 TEST_F(ExtensionServiceTest, ExternalInstallClickToKeep) {
8083 FeatureSwitch::ScopedOverride prompt(
8084 FeatureSwitch::prompt_for_external_extensions(), true);
8086 ExtensionServiceInitParams params = CreateDefaultInitParams();
8087 params.is_first_run = false;
8088 InitializeExtensionService(params);
8090 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
8091 PackCRX(data_dir().AppendASCII("update_from_webstore"),
8092 data_dir().AppendASCII("update_from_webstore.pem"),
8093 crx_path);
8095 MockExtensionProvider* provider =
8096 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
8097 AddMockExternalProvider(provider);
8098 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
8100 content::WindowedNotificationObserver observer(
8101 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
8102 content::NotificationService::AllSources());
8103 service_->CheckForExternalUpdates();
8104 observer.Wait();
8105 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
8107 // We check both enabled and disabled, since these are "eventually exclusive"
8108 // sets.
8109 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
8110 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8112 // Accept the extension.
8113 service_->external_install_manager()->error_for_testing()->InstallUIProceed();
8115 // It should be enabled again.
8116 EXPECT_TRUE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8117 EXPECT_FALSE(
8118 registry()->disabled_extensions().GetByID(updates_from_webstore));
8120 // The error should be removed.
8121 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
8124 TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) {
8125 InitializeEmptyExtensionService();
8127 scoped_refptr<Extension> extension = extensions::ExtensionBuilder()
8128 .SetManifest(extensions::DictionaryBuilder()
8129 .Set("name", "extension")
8130 .Set("version", "1.0")
8131 .Set("manifest_version", 2).Build())
8132 .Build();
8133 ASSERT_TRUE(extension.get());
8134 const std::string& id = extension->id();
8136 std::set<std::string> id_set;
8137 id_set.insert(id);
8138 extensions::ExtensionNotificationObserver notifications(
8139 content::NotificationService::AllSources(), id_set);
8141 // Installation should be allowed but the extension should never have been
8142 // loaded and it should be blacklisted in prefs.
8143 service()->OnExtensionInstalled(
8144 extension.get(),
8145 syncer::StringOrdinal(),
8146 (extensions::kInstallFlagIsBlacklistedForMalware |
8147 extensions::kInstallFlagInstallImmediately));
8148 base::RunLoop().RunUntilIdle();
8150 // Extension was installed but not loaded.
8151 EXPECT_TRUE(notifications.CheckNotifications(
8152 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED));
8153 EXPECT_TRUE(service()->GetInstalledExtension(id));
8155 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
8156 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(id));
8158 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlacklisted(id));
8159 EXPECT_TRUE(
8160 ExtensionPrefs::Get(profile())->IsBlacklistedExtensionAcknowledged(id));
8163 // Tests a profile being destroyed correctly disables extensions.
8164 TEST_F(ExtensionServiceTest, DestroyingProfileClearsExtensions) {
8165 InitializeEmptyExtensionService();
8167 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
8168 EXPECT_NE(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8169 EXPECT_EQ(1u, registry()->enabled_extensions().size());
8170 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8171 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8172 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
8174 service()->Observe(chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
8175 content::Source<Profile>(profile()),
8176 content::NotificationService::NoDetails());
8177 EXPECT_EQ(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8178 EXPECT_EQ(0u, registry()->enabled_extensions().size());
8179 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8180 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8181 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());