Adding instrumentation to locate the source of jankiness
[chromium-blink-merge.git] / chrome / browser / extensions / extension_service_unittest.cc
blobc7ab916c43165c7871aa9f828aa56bcb29e8a3b2
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/memory/scoped_ptr.h"
20 #include "base/memory/weak_ptr.h"
21 #include "base/message_loop/message_loop.h"
22 #include "base/prefs/scoped_user_pref_update.h"
23 #include "base/stl_util.h"
24 #include "base/strings/string16.h"
25 #include "base/strings/string_number_conversions.h"
26 #include "base/strings/string_util.h"
27 #include "base/strings/utf_string_conversions.h"
28 #include "base/version.h"
29 #include "chrome/browser/browser_process.h"
30 #include "chrome/browser/chrome_notification_types.h"
31 #include "chrome/browser/extensions/app_sync_data.h"
32 #include "chrome/browser/extensions/blacklist.h"
33 #include "chrome/browser/extensions/chrome_app_sorting.h"
34 #include "chrome/browser/extensions/component_loader.h"
35 #include "chrome/browser/extensions/crx_installer.h"
36 #include "chrome/browser/extensions/default_apps.h"
37 #include "chrome/browser/extensions/extension_creator.h"
38 #include "chrome/browser/extensions/extension_error_reporter.h"
39 #include "chrome/browser/extensions/extension_error_ui.h"
40 #include "chrome/browser/extensions/extension_management_test_util.h"
41 #include "chrome/browser/extensions/extension_notification_observer.h"
42 #include "chrome/browser/extensions/extension_service.h"
43 #include "chrome/browser/extensions/extension_service_test_base.h"
44 #include "chrome/browser/extensions/extension_special_storage_policy.h"
45 #include "chrome/browser/extensions/extension_sync_data.h"
46 #include "chrome/browser/extensions/extension_sync_service.h"
47 #include "chrome/browser/extensions/extension_util.h"
48 #include "chrome/browser/extensions/external_install_error.h"
49 #include "chrome/browser/extensions/external_install_manager.h"
50 #include "chrome/browser/extensions/external_policy_loader.h"
51 #include "chrome/browser/extensions/external_pref_loader.h"
52 #include "chrome/browser/extensions/external_provider_impl.h"
53 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
54 #include "chrome/browser/extensions/installed_loader.h"
55 #include "chrome/browser/extensions/pack_extension_job.h"
56 #include "chrome/browser/extensions/pending_extension_info.h"
57 #include "chrome/browser/extensions/pending_extension_manager.h"
58 #include "chrome/browser/extensions/test_blacklist.h"
59 #include "chrome/browser/extensions/test_extension_system.h"
60 #include "chrome/browser/extensions/unpacked_installer.h"
61 #include "chrome/browser/extensions/updater/extension_updater.h"
62 #include "chrome/browser/prefs/pref_service_syncable.h"
63 #include "chrome/browser/sync/profile_sync_service.h"
64 #include "chrome/browser/sync/profile_sync_service_factory.h"
65 #include "chrome/common/chrome_constants.h"
66 #include "chrome/common/chrome_switches.h"
67 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
68 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
69 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
70 #include "chrome/common/pref_names.h"
71 #include "chrome/common/url_constants.h"
72 #include "chrome/test/base/scoped_browser_locale.h"
73 #include "chrome/test/base/testing_pref_service_syncable.h"
74 #include "chrome/test/base/testing_profile.h"
75 #include "components/crx_file/id_util.h"
76 #include "components/pref_registry/pref_registry_syncable.h"
77 #include "content/public/browser/dom_storage_context.h"
78 #include "content/public/browser/gpu_data_manager.h"
79 #include "content/public/browser/indexed_db_context.h"
80 #include "content/public/browser/notification_registrar.h"
81 #include "content/public/browser/notification_service.h"
82 #include "content/public/browser/plugin_service.h"
83 #include "content/public/browser/render_process_host.h"
84 #include "content/public/browser/storage_partition.h"
85 #include "content/public/common/content_constants.h"
86 #include "content/public/test/test_utils.h"
87 #include "extensions/browser/extension_registry.h"
88 #include "extensions/browser/extension_system.h"
89 #include "extensions/browser/external_provider_interface.h"
90 #include "extensions/browser/install_flag.h"
91 #include "extensions/browser/management_policy.h"
92 #include "extensions/browser/test_management_policy.h"
93 #include "extensions/browser/uninstall_reason.h"
94 #include "extensions/common/constants.h"
95 #include "extensions/common/extension.h"
96 #include "extensions/common/extension_builder.h"
97 #include "extensions/common/extension_l10n_util.h"
98 #include "extensions/common/extension_resource.h"
99 #include "extensions/common/feature_switch.h"
100 #include "extensions/common/manifest_constants.h"
101 #include "extensions/common/manifest_handlers/background_info.h"
102 #include "extensions/common/manifest_url_handlers.h"
103 #include "extensions/common/permissions/permission_set.h"
104 #include "extensions/common/permissions/permissions_data.h"
105 #include "extensions/common/switches.h"
106 #include "extensions/common/url_pattern.h"
107 #include "extensions/common/value_builder.h"
108 #include "gpu/config/gpu_info.h"
109 #include "grit/browser_resources.h"
110 #include "net/cookies/canonical_cookie.h"
111 #include "net/cookies/cookie_monster.h"
112 #include "net/cookies/cookie_options.h"
113 #include "net/url_request/url_request_context.h"
114 #include "net/url_request/url_request_context_getter.h"
115 #include "storage/browser/database/database_tracker.h"
116 #include "storage/browser/quota/quota_manager.h"
117 #include "storage/common/database/database_identifier.h"
118 #include "sync/api/fake_sync_change_processor.h"
119 #include "sync/api/string_ordinal.h"
120 #include "sync/api/sync_data.h"
121 #include "sync/api/sync_error_factory.h"
122 #include "sync/api/sync_error_factory_mock.h"
123 #include "sync/api/syncable_service.h"
124 #include "sync/protocol/app_specifics.pb.h"
125 #include "sync/protocol/extension_specifics.pb.h"
126 #include "sync/protocol/sync.pb.h"
127 #include "testing/gtest/include/gtest/gtest.h"
128 #include "testing/platform_test.h"
129 #include "url/gurl.h"
131 #if defined(ENABLE_MANAGED_USERS)
132 #include "chrome/browser/supervised_user/supervised_user_service.h"
133 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
134 #endif
136 #if defined(OS_CHROMEOS)
137 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
138 #include "chrome/browser/chromeos/settings/cros_settings.h"
139 #include "chrome/browser/chromeos/settings/device_settings_service.h"
140 #endif
142 // The blacklist tests rely on safe browsing.
143 #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
144 #define ENABLE_BLACKLIST_TESTS
145 #endif
147 using base::DictionaryValue;
148 using base::ListValue;
149 using base::Value;
150 using content::BrowserContext;
151 using content::BrowserThread;
152 using content::DOMStorageContext;
153 using content::IndexedDBContext;
154 using content::PluginService;
155 using extensions::APIPermission;
156 using extensions::APIPermissionSet;
157 using extensions::AppSorting;
158 using extensions::Blacklist;
159 using extensions::CrxInstaller;
160 using extensions::Extension;
161 using extensions::ExtensionCreator;
162 using extensions::ExtensionPrefs;
163 using extensions::ExtensionRegistry;
164 using extensions::ExtensionResource;
165 using extensions::ExtensionSystem;
166 using extensions::FakeSafeBrowsingDatabaseManager;
167 using extensions::FeatureSwitch;
168 using extensions::Manifest;
169 using extensions::PermissionSet;
170 using extensions::TestExtensionSystem;
171 using extensions::UnloadedExtensionInfo;
172 using extensions::URLPatternSet;
174 namespace keys = extensions::manifest_keys;
176 namespace {
178 // Extension ids used during testing.
179 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
180 const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
181 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
182 const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
183 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
184 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
185 const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
186 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
187 const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad";
188 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
189 const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
190 const char unpacked[] = "cbcdidchbppangcjoddlpdjlenngjldk";
191 const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
193 struct ExtensionsOrder {
194 bool operator()(const scoped_refptr<const Extension>& a,
195 const scoped_refptr<const Extension>& b) {
196 return a->name() < b->name();
200 static std::vector<base::string16> GetErrors() {
201 const std::vector<base::string16>* errors =
202 ExtensionErrorReporter::GetInstance()->GetErrors();
203 std::vector<base::string16> ret_val;
205 for (std::vector<base::string16>::const_iterator iter = errors->begin();
206 iter != errors->end(); ++iter) {
207 std::string utf8_error = base::UTF16ToUTF8(*iter);
208 if (utf8_error.find(".svn") == std::string::npos) {
209 ret_val.push_back(*iter);
213 // The tests rely on the errors being in a certain order, which can vary
214 // depending on how filesystem iteration works.
215 std::stable_sort(ret_val.begin(), ret_val.end());
217 return ret_val;
220 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
221 int schemes = URLPattern::SCHEME_ALL;
222 extent->AddPattern(URLPattern(schemes, pattern));
225 base::FilePath GetTemporaryFile() {
226 base::FilePath temp_file;
227 CHECK(base::CreateTemporaryFile(&temp_file));
228 return temp_file;
231 bool WaitForCountNotificationsCallback(int *count) {
232 return --(*count) == 0;
235 } // namespace
237 class MockExtensionProvider : public extensions::ExternalProviderInterface {
238 public:
239 MockExtensionProvider(
240 VisitorInterface* visitor,
241 Manifest::Location location)
242 : location_(location), visitor_(visitor), visit_count_(0) {
245 virtual ~MockExtensionProvider() {}
247 void UpdateOrAddExtension(const std::string& id,
248 const std::string& version,
249 const base::FilePath& path) {
250 extension_map_[id] = std::make_pair(version, path);
253 void RemoveExtension(const std::string& id) {
254 extension_map_.erase(id);
257 // ExternalProvider implementation:
258 virtual void VisitRegisteredExtension() override {
259 visit_count_++;
260 for (DataMap::const_iterator i = extension_map_.begin();
261 i != extension_map_.end(); ++i) {
262 Version version(i->second.first);
264 visitor_->OnExternalExtensionFileFound(
265 i->first, &version, i->second.second, location_,
266 Extension::NO_FLAGS, false);
268 visitor_->OnExternalProviderReady(this);
271 virtual bool HasExtension(const std::string& id) const override {
272 return extension_map_.find(id) != extension_map_.end();
275 virtual bool GetExtensionDetails(
276 const std::string& id,
277 Manifest::Location* location,
278 scoped_ptr<Version>* version) const override {
279 DataMap::const_iterator it = extension_map_.find(id);
280 if (it == extension_map_.end())
281 return false;
283 if (version)
284 version->reset(new Version(it->second.first));
286 if (location)
287 *location = location_;
289 return true;
292 virtual bool IsReady() const override {
293 return true;
296 virtual void ServiceShutdown() override {
299 int visit_count() const { return visit_count_; }
300 void set_visit_count(int visit_count) {
301 visit_count_ = visit_count;
304 private:
305 typedef std::map< std::string, std::pair<std::string, base::FilePath> >
306 DataMap;
307 DataMap extension_map_;
308 Manifest::Location location_;
309 VisitorInterface* visitor_;
311 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
312 // Mutable because it must be incremented on each call to
313 // VisitRegisteredExtension(), which must be a const method to inherit
314 // from the class being mocked.
315 mutable int visit_count_;
317 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
320 class MockProviderVisitor
321 : public extensions::ExternalProviderInterface::VisitorInterface {
322 public:
323 // The provider will return |fake_base_path| from
324 // GetBaseCrxFilePath(). User can test the behavior with
325 // and without an empty path using this parameter.
326 explicit MockProviderVisitor(base::FilePath fake_base_path)
327 : ids_found_(0),
328 fake_base_path_(fake_base_path),
329 expected_creation_flags_(Extension::NO_FLAGS) {
330 profile_.reset(new TestingProfile);
333 MockProviderVisitor(base::FilePath fake_base_path,
334 int expected_creation_flags)
335 : ids_found_(0),
336 fake_base_path_(fake_base_path),
337 expected_creation_flags_(expected_creation_flags) {
340 int Visit(const std::string& json_data) {
341 // Give the test json file to the provider for parsing.
342 provider_.reset(new extensions::ExternalProviderImpl(
343 this,
344 new extensions::ExternalTestingLoader(json_data, fake_base_path_),
345 profile_.get(),
346 Manifest::EXTERNAL_PREF,
347 Manifest::EXTERNAL_PREF_DOWNLOAD,
348 Extension::NO_FLAGS));
350 // We also parse the file into a dictionary to compare what we get back
351 // from the provider.
352 JSONStringValueSerializer serializer(json_data);
353 base::Value* json_value = serializer.Deserialize(NULL, NULL);
355 if (!json_value || !json_value->IsType(base::Value::TYPE_DICTIONARY)) {
356 NOTREACHED() << "Unable to deserialize json data";
357 return -1;
358 } else {
359 base::DictionaryValue* external_extensions =
360 static_cast<base::DictionaryValue*>(json_value);
361 prefs_.reset(external_extensions);
364 // Reset our counter.
365 ids_found_ = 0;
366 // Ask the provider to look up all extensions and return them.
367 provider_->VisitRegisteredExtension();
369 return ids_found_;
372 virtual bool OnExternalExtensionFileFound(const std::string& id,
373 const Version* version,
374 const base::FilePath& path,
375 Manifest::Location unused,
376 int creation_flags,
377 bool mark_acknowledged) override {
378 EXPECT_EQ(expected_creation_flags_, creation_flags);
380 ++ids_found_;
381 base::DictionaryValue* pref;
382 // This tests is to make sure that the provider only notifies us of the
383 // values we gave it. So if the id we doesn't exist in our internal
384 // dictionary then something is wrong.
385 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
386 << "Got back ID (" << id.c_str() << ") we weren't expecting";
388 EXPECT_TRUE(path.IsAbsolute());
389 if (!fake_base_path_.empty())
390 EXPECT_TRUE(fake_base_path_.IsParent(path));
392 if (pref) {
393 EXPECT_TRUE(provider_->HasExtension(id));
395 // Ask provider if the extension we got back is registered.
396 Manifest::Location location = Manifest::INVALID_LOCATION;
397 scoped_ptr<Version> v1;
398 base::FilePath crx_path;
400 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
401 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
403 scoped_ptr<Version> v2;
404 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
405 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
406 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
407 EXPECT_EQ(Manifest::EXTERNAL_PREF, location);
409 // Remove it so we won't count it ever again.
410 prefs_->Remove(id, NULL);
412 return true;
415 virtual bool OnExternalExtensionUpdateUrlFound(
416 const std::string& id,
417 const std::string& install_parameter,
418 const GURL& update_url,
419 Manifest::Location location,
420 int creation_flags,
421 bool mark_acknowledged) override {
422 ++ids_found_;
423 base::DictionaryValue* pref;
424 // This tests is to make sure that the provider only notifies us of the
425 // values we gave it. So if the id we doesn't exist in our internal
426 // dictionary then something is wrong.
427 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
428 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
429 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location);
431 if (pref) {
432 EXPECT_TRUE(provider_->HasExtension(id));
434 // External extensions with update URLs do not have versions.
435 scoped_ptr<Version> v1;
436 Manifest::Location location1 = Manifest::INVALID_LOCATION;
437 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
438 EXPECT_FALSE(v1.get());
439 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1);
441 std::string parsed_install_parameter;
442 pref->GetString("install_parameter", &parsed_install_parameter);
443 EXPECT_EQ(parsed_install_parameter, install_parameter);
445 // Remove it so we won't count it again.
446 prefs_->Remove(id, NULL);
448 return true;
451 virtual void OnExternalProviderReady(
452 const extensions::ExternalProviderInterface* provider) override {
453 EXPECT_EQ(provider, provider_.get());
454 EXPECT_TRUE(provider->IsReady());
457 private:
458 int ids_found_;
459 base::FilePath fake_base_path_;
460 int expected_creation_flags_;
461 scoped_ptr<extensions::ExternalProviderImpl> provider_;
462 scoped_ptr<base::DictionaryValue> prefs_;
463 scoped_ptr<TestingProfile> profile_;
465 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
468 class ExtensionServiceTest : public extensions::ExtensionServiceTestBase,
469 public content::NotificationObserver {
470 public:
471 ExtensionServiceTest()
472 : unloaded_reason_(UnloadedExtensionInfo::REASON_UNDEFINED),
473 installed_(NULL),
474 was_update_(false),
475 override_external_install_prompt_(
476 FeatureSwitch::prompt_for_external_extensions(),
477 false),
478 expected_extensions_count_(0) {
479 registrar_.Add(this,
480 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
481 content::NotificationService::AllSources());
482 registrar_.Add(this,
483 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
484 content::NotificationService::AllSources());
485 registrar_.Add(
486 this,
487 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
488 content::NotificationService::AllSources());
491 virtual void Observe(int type,
492 const content::NotificationSource& source,
493 const content::NotificationDetails& details) override {
494 switch (type) {
495 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
496 const Extension* extension =
497 content::Details<const Extension>(details).ptr();
498 loaded_.push_back(make_scoped_refptr(extension));
499 // The tests rely on the errors being in a certain order, which can vary
500 // depending on how filesystem iteration works.
501 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
502 break;
505 case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
506 UnloadedExtensionInfo* unloaded_info =
507 content::Details<UnloadedExtensionInfo>(details).ptr();
508 const Extension* e = unloaded_info->extension;
509 unloaded_id_ = e->id();
510 unloaded_reason_ = unloaded_info->reason;
511 extensions::ExtensionList::iterator i =
512 std::find(loaded_.begin(), loaded_.end(), e);
513 // TODO(erikkay) fix so this can be an assert. Right now the tests
514 // are manually calling clear() on loaded_, so this isn't doable.
515 if (i == loaded_.end())
516 return;
517 loaded_.erase(i);
518 break;
520 case extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED: {
521 const extensions::InstalledExtensionInfo* installed_info =
522 content::Details<const extensions::InstalledExtensionInfo>(details)
523 .ptr();
524 installed_ = installed_info->extension;
525 was_update_ = installed_info->is_update;
526 old_name_ = installed_info->old_name;
527 break;
530 default:
531 DCHECK(false);
535 void AddMockExternalProvider(
536 extensions::ExternalProviderInterface* provider) {
537 service()->AddProviderForTesting(provider);
540 void MockSyncStartFlare(bool* was_called,
541 syncer::ModelType* model_type_passed_in,
542 syncer::ModelType model_type) {
543 *was_called = true;
544 *model_type_passed_in = model_type;
547 protected:
548 // Paths to some of the fake extensions.
549 base::FilePath good0_path() {
550 return data_dir()
551 .AppendASCII("good")
552 .AppendASCII("Extensions")
553 .AppendASCII(good0)
554 .AppendASCII("1.0.0.0");
557 base::FilePath good1_path() {
558 return data_dir()
559 .AppendASCII("good")
560 .AppendASCII("Extensions")
561 .AppendASCII(good1)
562 .AppendASCII("2");
565 base::FilePath good2_path() {
566 return data_dir()
567 .AppendASCII("good")
568 .AppendASCII("Extensions")
569 .AppendASCII(good2)
570 .AppendASCII("1.0");
573 void TestExternalProvider(MockExtensionProvider* provider,
574 Manifest::Location location);
576 void PackCRX(const base::FilePath& dir_path,
577 const base::FilePath& pem_path,
578 const base::FilePath& crx_path) {
579 // Use the existing pem key, if provided.
580 base::FilePath pem_output_path;
581 if (pem_path.value().empty()) {
582 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
583 } else {
584 ASSERT_TRUE(base::PathExists(pem_path));
587 ASSERT_TRUE(base::DeleteFile(crx_path, false));
589 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
590 ASSERT_TRUE(creator->Run(dir_path,
591 crx_path,
592 pem_path,
593 pem_output_path,
594 ExtensionCreator::kOverwriteCRX));
596 ASSERT_TRUE(base::PathExists(crx_path));
599 enum InstallState {
600 INSTALL_FAILED,
601 INSTALL_UPDATED,
602 INSTALL_NEW,
603 INSTALL_WITHOUT_LOAD,
606 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
607 const base::FilePath& pem_path,
608 InstallState install_state,
609 int creation_flags) {
610 base::FilePath crx_path;
611 base::ScopedTempDir temp_dir;
612 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
613 crx_path = temp_dir.path().AppendASCII("temp.crx");
615 PackCRX(dir_path, pem_path, crx_path);
616 return InstallCRX(crx_path, install_state, creation_flags);
619 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
620 const base::FilePath& pem_path,
621 InstallState install_state) {
622 return PackAndInstallCRX(dir_path, pem_path, install_state,
623 Extension::NO_FLAGS);
626 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
627 InstallState install_state) {
628 return PackAndInstallCRX(dir_path, base::FilePath(), install_state,
629 Extension::NO_FLAGS);
632 // Attempts to install an extension. Use INSTALL_FAILED if the installation
633 // is expected to fail.
634 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
635 // non-empty, expects that the existing extension's title was
636 // |expected_old_name|.
637 const Extension* InstallCRX(const base::FilePath& path,
638 InstallState install_state,
639 int creation_flags,
640 const std::string& expected_old_name) {
641 InstallCRXInternal(path, creation_flags);
642 return VerifyCrxInstall(path, install_state, expected_old_name);
645 // Attempts to install an extension. Use INSTALL_FAILED if the installation
646 // is expected to fail.
647 const Extension* InstallCRX(const base::FilePath& path,
648 InstallState install_state,
649 int creation_flags) {
650 return InstallCRX(path, install_state, creation_flags, std::string());
653 // Attempts to install an extension. Use INSTALL_FAILED if the installation
654 // is expected to fail.
655 const Extension* InstallCRX(const base::FilePath& path,
656 InstallState install_state) {
657 return InstallCRX(path, install_state, Extension::NO_FLAGS);
660 const Extension* InstallCRXFromWebStore(const base::FilePath& path,
661 InstallState install_state) {
662 InstallCRXInternal(path, Extension::FROM_WEBSTORE);
663 return VerifyCrxInstall(path, install_state);
666 const Extension* InstallCRXWithLocation(const base::FilePath& crx_path,
667 Manifest::Location install_location,
668 InstallState install_state) {
669 EXPECT_TRUE(base::PathExists(crx_path))
670 << "Path does not exist: "<< crx_path.value().c_str();
671 // no client (silent install)
672 scoped_refptr<CrxInstaller> installer(
673 CrxInstaller::CreateSilent(service()));
674 installer->set_install_source(install_location);
676 content::WindowedNotificationObserver observer(
677 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
678 content::NotificationService::AllSources());
679 installer->InstallCrx(crx_path);
680 observer.Wait();
682 return VerifyCrxInstall(crx_path, install_state);
685 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
686 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
687 // Returns an Extension pointer if the install succeeded, NULL otherwise.
688 const Extension* VerifyCrxInstall(const base::FilePath& path,
689 InstallState install_state) {
690 return VerifyCrxInstall(path, install_state, std::string());
693 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
694 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
695 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
696 // non-empty, expects that the existing extension's title was
697 // |expected_old_name|.
698 // Returns an Extension pointer if the install succeeded, NULL otherwise.
699 const Extension* VerifyCrxInstall(const base::FilePath& path,
700 InstallState install_state,
701 const std::string& expected_old_name) {
702 std::vector<base::string16> errors = GetErrors();
703 const Extension* extension = NULL;
704 if (install_state != INSTALL_FAILED) {
705 if (install_state == INSTALL_NEW)
706 ++expected_extensions_count_;
708 EXPECT_TRUE(installed_) << path.value();
709 // If and only if INSTALL_UPDATED, it should have the is_update flag.
710 EXPECT_EQ(install_state == INSTALL_UPDATED, was_update_)
711 << path.value();
712 // If INSTALL_UPDATED, old_name_ should match the given string.
713 if (install_state == INSTALL_UPDATED && !expected_old_name.empty())
714 EXPECT_EQ(expected_old_name, old_name_);
715 EXPECT_EQ(0u, errors.size()) << path.value();
717 if (install_state == INSTALL_WITHOUT_LOAD) {
718 EXPECT_EQ(0u, loaded_.size()) << path.value();
719 } else {
720 EXPECT_EQ(1u, loaded_.size()) << path.value();
721 size_t actual_extension_count =
722 registry()->enabled_extensions().size() +
723 registry()->disabled_extensions().size();
724 EXPECT_EQ(expected_extensions_count_, actual_extension_count) <<
725 path.value();
726 extension = loaded_[0].get();
727 EXPECT_TRUE(service()->GetExtensionById(extension->id(), false))
728 << path.value();
731 for (std::vector<base::string16>::iterator err = errors.begin();
732 err != errors.end(); ++err) {
733 LOG(ERROR) << *err;
735 } else {
736 EXPECT_FALSE(installed_) << path.value();
737 EXPECT_EQ(0u, loaded_.size()) << path.value();
738 EXPECT_EQ(1u, errors.size()) << path.value();
741 installed_ = NULL;
742 was_update_ = false;
743 old_name_ = "";
744 loaded_.clear();
745 ExtensionErrorReporter::GetInstance()->ClearErrors();
746 return extension;
749 enum UpdateState {
750 FAILED_SILENTLY,
751 FAILED,
752 UPDATED,
753 INSTALLED,
754 DISABLED,
755 ENABLED
758 void BlackListWebGL() {
759 static const std::string json_blacklist =
760 "{\n"
761 " \"name\": \"gpu blacklist\",\n"
762 " \"version\": \"1.0\",\n"
763 " \"entries\": [\n"
764 " {\n"
765 " \"id\": 1,\n"
766 " \"features\": [\"webgl\"]\n"
767 " }\n"
768 " ]\n"
769 "}";
770 gpu::GPUInfo gpu_info;
771 content::GpuDataManager::GetInstance()->InitializeForTesting(
772 json_blacklist, gpu_info);
775 // Helper method to set up a WindowedNotificationObserver to wait for a
776 // specific CrxInstaller to finish if we don't know the value of the
777 // |installer| yet.
778 static bool IsCrxInstallerDone(extensions::CrxInstaller** installer,
779 const content::NotificationSource& source,
780 const content::NotificationDetails& details) {
781 return content::Source<extensions::CrxInstaller>(source).ptr() ==
782 *installer;
785 void PackCRXAndUpdateExtension(const std::string& id,
786 const base::FilePath& dir_path,
787 const base::FilePath& pem_path,
788 UpdateState expected_state) {
789 base::ScopedTempDir temp_dir;
790 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
791 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
793 PackCRX(dir_path, pem_path, crx_path);
794 UpdateExtension(id, crx_path, expected_state);
797 void UpdateExtension(const std::string& id,
798 const base::FilePath& in_path,
799 UpdateState expected_state) {
800 ASSERT_TRUE(base::PathExists(in_path));
802 // We need to copy this to a temporary location because Update() will delete
803 // it.
804 base::FilePath path = temp_dir().path();
805 path = path.Append(in_path.BaseName());
806 ASSERT_TRUE(base::CopyFile(in_path, path));
808 int previous_enabled_extension_count =
809 registry()->enabled_extensions().size();
810 int previous_installed_extension_count =
811 previous_enabled_extension_count +
812 registry()->disabled_extensions().size();
814 extensions::CrxInstaller* installer = NULL;
815 content::WindowedNotificationObserver observer(
816 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
817 base::Bind(&IsCrxInstallerDone, &installer));
818 service()->UpdateExtension(id, path, true, &installer);
820 if (installer)
821 observer.Wait();
822 else
823 base::RunLoop().RunUntilIdle();
825 std::vector<base::string16> errors = GetErrors();
826 int error_count = errors.size();
827 int enabled_extension_count = registry()->enabled_extensions().size();
828 int installed_extension_count =
829 enabled_extension_count + registry()->disabled_extensions().size();
831 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
832 EXPECT_EQ(expected_error_count, error_count) << path.value();
834 if (expected_state <= FAILED) {
835 EXPECT_EQ(previous_enabled_extension_count,
836 enabled_extension_count);
837 EXPECT_EQ(previous_installed_extension_count,
838 installed_extension_count);
839 } else {
840 int expected_installed_extension_count =
841 (expected_state >= INSTALLED) ? 1 : 0;
842 int expected_enabled_extension_count =
843 (expected_state >= ENABLED) ? 1 : 0;
844 EXPECT_EQ(expected_installed_extension_count,
845 installed_extension_count);
846 EXPECT_EQ(expected_enabled_extension_count,
847 enabled_extension_count);
850 // Update() should the temporary input file.
851 EXPECT_FALSE(base::PathExists(path));
854 void TerminateExtension(const std::string& id) {
855 const Extension* extension = service()->GetInstalledExtension(id);
856 if (!extension) {
857 ADD_FAILURE();
858 return;
860 service()->TrackTerminatedExtensionForTest(extension);
863 size_t GetPrefKeyCount() {
864 const base::DictionaryValue* dict =
865 profile()->GetPrefs()->GetDictionary("extensions.settings");
866 if (!dict) {
867 ADD_FAILURE();
868 return 0;
870 return dict->size();
873 void UninstallExtension(const std::string& id, bool use_helper) {
874 // Verify that the extension is installed.
875 base::FilePath extension_path = extensions_install_dir().AppendASCII(id);
876 EXPECT_TRUE(base::PathExists(extension_path));
877 size_t pref_key_count = GetPrefKeyCount();
878 EXPECT_GT(pref_key_count, 0u);
879 ValidateIntegerPref(id, "state", Extension::ENABLED);
881 // Uninstall it.
882 if (use_helper) {
883 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(
884 service(), id, extensions::UNINSTALL_REASON_FOR_TESTING));
885 } else {
886 EXPECT_TRUE(service()->UninstallExtension(
888 extensions::UNINSTALL_REASON_FOR_TESTING,
889 base::Bind(&base::DoNothing),
890 NULL));
892 --expected_extensions_count_;
894 // We should get an unload notification.
895 EXPECT_FALSE(unloaded_id_.empty());
896 EXPECT_EQ(id, unloaded_id_);
898 // Verify uninstalled state.
899 size_t new_pref_key_count = GetPrefKeyCount();
900 if (new_pref_key_count == pref_key_count) {
901 ValidateIntegerPref(id, "state",
902 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
903 } else {
904 EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
907 // The extension should not be in the service anymore.
908 EXPECT_FALSE(service()->GetInstalledExtension(id));
909 base::RunLoop().RunUntilIdle();
911 // The directory should be gone.
912 EXPECT_FALSE(base::PathExists(extension_path));
915 void ValidatePrefKeyCount(size_t count) {
916 EXPECT_EQ(count, GetPrefKeyCount());
919 testing::AssertionResult ValidateBooleanPref(
920 const std::string& extension_id,
921 const std::string& pref_path,
922 bool expected_val) {
923 std::string msg = "while checking: ";
924 msg += extension_id;
925 msg += " ";
926 msg += pref_path;
927 msg += " == ";
928 msg += expected_val ? "true" : "false";
930 PrefService* prefs = profile()->GetPrefs();
931 const base::DictionaryValue* dict =
932 prefs->GetDictionary("extensions.settings");
933 if (!dict) {
934 return testing::AssertionFailure()
935 << "extension.settings does not exist " << msg;
938 const base::DictionaryValue* pref = NULL;
939 if (!dict->GetDictionary(extension_id, &pref)) {
940 return testing::AssertionFailure()
941 << "extension pref does not exist " << msg;
944 bool val;
945 if (!pref->GetBoolean(pref_path, &val)) {
946 return testing::AssertionFailure()
947 << pref_path << " pref not found " << msg;
950 return expected_val == val
951 ? testing::AssertionSuccess()
952 : testing::AssertionFailure() << "base::Value is incorrect " << msg;
955 bool IsPrefExist(const std::string& extension_id,
956 const std::string& pref_path) {
957 const base::DictionaryValue* dict =
958 profile()->GetPrefs()->GetDictionary("extensions.settings");
959 if (dict == NULL) return false;
960 const base::DictionaryValue* pref = NULL;
961 if (!dict->GetDictionary(extension_id, &pref)) {
962 return false;
964 if (pref == NULL) {
965 return false;
967 bool val;
968 if (!pref->GetBoolean(pref_path, &val)) {
969 return false;
971 return true;
974 void ValidateIntegerPref(const std::string& extension_id,
975 const std::string& pref_path,
976 int expected_val) {
977 std::string msg = " while checking: ";
978 msg += extension_id;
979 msg += " ";
980 msg += pref_path;
981 msg += " == ";
982 msg += base::IntToString(expected_val);
984 PrefService* prefs = profile()->GetPrefs();
985 const base::DictionaryValue* dict =
986 prefs->GetDictionary("extensions.settings");
987 ASSERT_TRUE(dict != NULL) << msg;
988 const base::DictionaryValue* pref = NULL;
989 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
990 EXPECT_TRUE(pref != NULL) << msg;
991 int val;
992 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
993 EXPECT_EQ(expected_val, val) << msg;
996 void ValidateStringPref(const std::string& extension_id,
997 const std::string& pref_path,
998 const std::string& expected_val) {
999 std::string msg = " while checking: ";
1000 msg += extension_id;
1001 msg += ".manifest.";
1002 msg += pref_path;
1003 msg += " == ";
1004 msg += expected_val;
1006 const base::DictionaryValue* dict =
1007 profile()->GetPrefs()->GetDictionary("extensions.settings");
1008 ASSERT_TRUE(dict != NULL) << msg;
1009 const base::DictionaryValue* pref = NULL;
1010 std::string manifest_path = extension_id + ".manifest";
1011 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
1012 EXPECT_TRUE(pref != NULL) << msg;
1013 std::string val;
1014 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
1015 EXPECT_EQ(expected_val, val) << msg;
1018 void SetPref(const std::string& extension_id,
1019 const std::string& pref_path,
1020 base::Value* value,
1021 const std::string& msg) {
1022 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1023 base::DictionaryValue* dict = update.Get();
1024 ASSERT_TRUE(dict != NULL) << msg;
1025 base::DictionaryValue* pref = NULL;
1026 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1027 EXPECT_TRUE(pref != NULL) << msg;
1028 pref->Set(pref_path, value);
1031 void SetPrefInteg(const std::string& extension_id,
1032 const std::string& pref_path,
1033 int value) {
1034 std::string msg = " while setting: ";
1035 msg += extension_id;
1036 msg += " ";
1037 msg += pref_path;
1038 msg += " = ";
1039 msg += base::IntToString(value);
1041 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1044 void SetPrefBool(const std::string& extension_id,
1045 const std::string& pref_path,
1046 bool value) {
1047 std::string msg = " while setting: ";
1048 msg += extension_id + " " + pref_path;
1049 msg += " = ";
1050 msg += (value ? "true" : "false");
1052 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1055 void ClearPref(const std::string& extension_id,
1056 const std::string& pref_path) {
1057 std::string msg = " while clearing: ";
1058 msg += extension_id + " " + pref_path;
1060 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1061 base::DictionaryValue* dict = update.Get();
1062 ASSERT_TRUE(dict != NULL) << msg;
1063 base::DictionaryValue* pref = NULL;
1064 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1065 EXPECT_TRUE(pref != NULL) << msg;
1066 pref->Remove(pref_path, NULL);
1069 void SetPrefStringSet(const std::string& extension_id,
1070 const std::string& pref_path,
1071 const std::set<std::string>& value) {
1072 std::string msg = " while setting: ";
1073 msg += extension_id + " " + pref_path;
1075 base::ListValue* list_value = new base::ListValue();
1076 for (std::set<std::string>::const_iterator iter = value.begin();
1077 iter != value.end(); ++iter)
1078 list_value->Append(new base::StringValue(*iter));
1080 SetPref(extension_id, pref_path, list_value, msg);
1083 void InitPluginService() {
1084 #if defined(ENABLE_PLUGINS)
1085 PluginService::GetInstance()->Init();
1086 #endif
1089 void InitializeExtensionSyncService() {
1090 extension_sync_service_.reset(new ExtensionSyncService(
1091 profile(), ExtensionPrefs::Get(browser_context()), service()));
1094 void InitializeEmptyExtensionServiceWithTestingPrefs() {
1095 ExtensionServiceTestBase::ExtensionServiceInitParams params =
1096 CreateDefaultInitParams();
1097 params.pref_file = base::FilePath();
1098 InitializeExtensionService(params);
1101 extensions::ManagementPolicy* GetManagementPolicy() {
1102 return ExtensionSystem::Get(browser_context())->management_policy();
1105 ExtensionSyncService* extension_sync_service() {
1106 return extension_sync_service_.get();
1109 protected:
1110 typedef extensions::ExtensionManagementPrefUpdater<TestingPrefServiceSyncable>
1111 ManagementPrefUpdater;
1112 scoped_ptr<ExtensionSyncService> extension_sync_service_;
1113 extensions::ExtensionList loaded_;
1114 std::string unloaded_id_;
1115 UnloadedExtensionInfo::Reason unloaded_reason_;
1116 const Extension* installed_;
1117 bool was_update_;
1118 std::string old_name_;
1119 FeatureSwitch::ScopedOverride override_external_install_prompt_;
1121 private:
1122 // Create a CrxInstaller and install the CRX file.
1123 // Instead of calling this method yourself, use InstallCRX(), which does extra
1124 // error checking.
1125 void InstallCRXInternal(const base::FilePath& crx_path) {
1126 InstallCRXInternal(crx_path, Extension::NO_FLAGS);
1129 void InstallCRXInternal(const base::FilePath& crx_path, int creation_flags) {
1130 ASSERT_TRUE(base::PathExists(crx_path))
1131 << "Path does not exist: "<< crx_path.value().c_str();
1132 scoped_refptr<CrxInstaller> installer(
1133 CrxInstaller::CreateSilent(service()));
1134 installer->set_creation_flags(creation_flags);
1135 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT))
1136 installer->set_allow_silent_install(true);
1138 content::WindowedNotificationObserver observer(
1139 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1140 content::Source<extensions::CrxInstaller>(installer.get()));
1142 installer->InstallCrx(crx_path);
1144 observer.Wait();
1147 size_t expected_extensions_count_;
1148 content::NotificationRegistrar registrar_;
1151 // Receives notifications from a PackExtensionJob, indicating either that
1152 // packing succeeded or that there was some error.
1153 class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
1154 public:
1155 PackExtensionTestClient(const base::FilePath& expected_crx_path,
1156 const base::FilePath& expected_private_key_path);
1157 virtual void OnPackSuccess(const base::FilePath& crx_path,
1158 const base::FilePath& private_key_path) override;
1159 virtual void OnPackFailure(const std::string& error_message,
1160 ExtensionCreator::ErrorType type) override;
1162 private:
1163 const base::FilePath expected_crx_path_;
1164 const base::FilePath expected_private_key_path_;
1165 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
1168 PackExtensionTestClient::PackExtensionTestClient(
1169 const base::FilePath& expected_crx_path,
1170 const base::FilePath& expected_private_key_path)
1171 : expected_crx_path_(expected_crx_path),
1172 expected_private_key_path_(expected_private_key_path) {}
1174 // If packing succeeded, we make sure that the package names match our
1175 // expectations.
1176 void PackExtensionTestClient::OnPackSuccess(
1177 const base::FilePath& crx_path,
1178 const base::FilePath& private_key_path) {
1179 // We got the notification and processed it; we don't expect any further tasks
1180 // to be posted to the current thread, so we should stop blocking and continue
1181 // on with the rest of the test.
1182 // This call to |Quit()| matches the call to |Run()| in the
1183 // |PackPunctuatedExtension| test.
1184 base::MessageLoop::current()->Quit();
1185 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
1186 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
1187 ASSERT_TRUE(base::PathExists(private_key_path));
1190 // The tests are designed so that we never expect to see a packing error.
1191 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1192 ExtensionCreator::ErrorType type) {
1193 if (type == ExtensionCreator::kCRXExists)
1194 FAIL() << "Packing should not fail.";
1195 else
1196 FAIL() << "Existing CRX should have been overwritten.";
1199 // Test loading good extensions from the profile directory.
1200 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1201 InitPluginService();
1202 InitializeGoodInstalledExtensionService();
1203 service()->Init();
1205 uint32 expected_num_extensions = 3u;
1206 ASSERT_EQ(expected_num_extensions, loaded_.size());
1208 EXPECT_EQ(std::string(good0), loaded_[0]->id());
1209 EXPECT_EQ(std::string("My extension 1"),
1210 loaded_[0]->name());
1211 EXPECT_EQ(std::string("The first extension that I made."),
1212 loaded_[0]->description());
1213 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
1214 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false));
1215 EXPECT_EQ(expected_num_extensions, registry()->enabled_extensions().size());
1217 ValidatePrefKeyCount(3);
1218 ValidateIntegerPref(good0, "state", Extension::ENABLED);
1219 ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
1220 ValidateIntegerPref(good1, "state", Extension::ENABLED);
1221 ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
1222 ValidateIntegerPref(good2, "state", Extension::ENABLED);
1223 ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
1225 URLPatternSet expected_patterns;
1226 AddPattern(&expected_patterns, "file:///*");
1227 AddPattern(&expected_patterns, "http://*.google.com/*");
1228 AddPattern(&expected_patterns, "https://*.google.com/*");
1229 const Extension* extension = loaded_[0].get();
1230 const extensions::UserScriptList& scripts =
1231 extensions::ContentScriptsInfo::GetContentScripts(extension);
1232 ASSERT_EQ(2u, scripts.size());
1233 EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
1234 EXPECT_EQ(2u, scripts[0].js_scripts().size());
1235 ExtensionResource resource00(extension->id(),
1236 scripts[0].js_scripts()[0].extension_root(),
1237 scripts[0].js_scripts()[0].relative_path());
1238 base::FilePath expected_path =
1239 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
1240 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
1241 ExtensionResource resource01(extension->id(),
1242 scripts[0].js_scripts()[1].extension_root(),
1243 scripts[0].js_scripts()[1].relative_path());
1244 expected_path =
1245 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
1246 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
1247 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension));
1248 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
1249 EXPECT_EQ("http://*.news.com/*",
1250 scripts[1].url_patterns().begin()->GetAsString());
1251 ExtensionResource resource10(extension->id(),
1252 scripts[1].js_scripts()[0].extension_root(),
1253 scripts[1].js_scripts()[0].relative_path());
1254 expected_path =
1255 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
1256 expected_path = base::MakeAbsoluteFilePath(expected_path);
1257 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
1259 expected_patterns.ClearPatterns();
1260 AddPattern(&expected_patterns, "http://*.google.com/*");
1261 AddPattern(&expected_patterns, "https://*.google.com/*");
1262 EXPECT_EQ(
1263 expected_patterns,
1264 extension->permissions_data()->active_permissions()->explicit_hosts());
1266 EXPECT_EQ(std::string(good1), loaded_[1]->id());
1267 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
1268 EXPECT_EQ(std::string(), loaded_[1]->description());
1269 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
1270 extensions::BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
1271 EXPECT_EQ(0u,
1272 extensions::ContentScriptsInfo::GetContentScripts(loaded_[1].get())
1273 .size());
1275 // We don't parse the plugins section on Chrome OS.
1276 #if defined(OS_CHROMEOS)
1277 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1278 #else
1279 ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1280 const std::vector<extensions::PluginInfo>* plugins =
1281 extensions::PluginInfo::GetPlugins(loaded_[1].get());
1282 ASSERT_TRUE(plugins);
1283 ASSERT_EQ(2u, plugins->size());
1284 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
1285 plugins->at(0).path.value());
1286 EXPECT_TRUE(plugins->at(0).is_public);
1287 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1288 plugins->at(1).path.value());
1289 EXPECT_FALSE(plugins->at(1).is_public);
1290 #endif
1292 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
1294 int index = expected_num_extensions - 1;
1295 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1296 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1297 EXPECT_EQ(std::string(), loaded_[index]->description());
1298 EXPECT_EQ(0u,
1299 extensions::ContentScriptsInfo::GetContentScripts(
1300 loaded_[index].get()).size());
1301 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
1304 // Test loading bad extensions from the profile directory.
1305 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
1306 // Initialize the test dir with a bad Preferences/extensions.
1307 base::FilePath source_install_dir =
1308 data_dir().AppendASCII("bad").AppendASCII("Extensions");
1309 base::FilePath pref_path =
1310 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1312 InitializeInstalledExtensionService(pref_path, source_install_dir);
1314 service()->Init();
1316 ASSERT_EQ(4u, GetErrors().size());
1317 ASSERT_EQ(0u, loaded_.size());
1319 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[0]),
1320 std::string("Could not load extension from '*'. ") +
1321 extensions::manifest_errors::kManifestUnreadable)) <<
1322 base::UTF16ToUTF8(GetErrors()[0]);
1324 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[1]),
1325 std::string("Could not load extension from '*'. ") +
1326 extensions::manifest_errors::kManifestUnreadable)) <<
1327 base::UTF16ToUTF8(GetErrors()[1]);
1329 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[2]),
1330 std::string("Could not load extension from '*'. ") +
1331 extensions::manifest_errors::kMissingFile)) <<
1332 base::UTF16ToUTF8(GetErrors()[2]);
1334 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[3]),
1335 std::string("Could not load extension from '*'. ") +
1336 extensions::manifest_errors::kManifestUnreadable)) <<
1337 base::UTF16ToUTF8(GetErrors()[3]);
1340 // Test various cases for delayed install because of missing imports.
1341 TEST_F(ExtensionServiceTest, PendingImports) {
1342 InitPluginService();
1344 base::FilePath source_install_dir =
1345 data_dir().AppendASCII("pending_updates_with_imports").AppendASCII(
1346 "Extensions");
1347 base::FilePath pref_path =
1348 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1350 InitializeInstalledExtensionService(pref_path, source_install_dir);
1352 // Verify there are no pending extensions initially.
1353 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions());
1355 service()->Init();
1356 // Wait for GarbageCollectExtensions task to complete.
1357 base::RunLoop().RunUntilIdle();
1359 // These extensions are used by the extensions we test below, they must be
1360 // installed.
1361 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1362 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1363 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1364 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1366 // Each of these extensions should have been rejected because of dependencies
1367 // that cannot be satisfied.
1368 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1369 EXPECT_FALSE(
1370 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1371 EXPECT_FALSE(
1372 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1373 EXPECT_FALSE(
1374 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1375 EXPECT_FALSE(
1376 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1377 EXPECT_FALSE(
1378 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
1379 EXPECT_FALSE(
1380 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
1382 // Make sure the import started for the extension with a dependency.
1383 EXPECT_TRUE(
1384 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1385 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1386 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1388 EXPECT_FALSE(base::PathExists(extensions_install_dir().AppendASCII(
1389 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
1391 EXPECT_TRUE(service()->pending_extension_manager()->HasPendingExtensions());
1392 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
1393 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
1394 // Remove it because we are not testing the pending extension manager's
1395 // ability to download and install extensions.
1396 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id));
1399 // Test installing extensions. This test tries to install few extensions using
1400 // crx files. If you need to change those crx files, feel free to repackage
1401 // them, throw away the key used and change the id's above.
1402 TEST_F(ExtensionServiceTest, InstallExtension) {
1403 InitializeEmptyExtensionService();
1405 // Extensions not enabled.
1406 service()->set_extensions_enabled(false);
1407 base::FilePath path = data_dir().AppendASCII("good.crx");
1408 InstallCRX(path, INSTALL_FAILED);
1409 service()->set_extensions_enabled(true);
1411 ValidatePrefKeyCount(0);
1413 // A simple extension that should install without error.
1414 path = data_dir().AppendASCII("good.crx");
1415 InstallCRX(path, INSTALL_NEW);
1416 // TODO(erikkay): verify the contents of the installed extension.
1418 int pref_count = 0;
1419 ValidatePrefKeyCount(++pref_count);
1420 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1421 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
1423 // An extension with page actions.
1424 path = data_dir().AppendASCII("page_action.crx");
1425 InstallCRX(path, INSTALL_NEW);
1426 ValidatePrefKeyCount(++pref_count);
1427 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1428 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
1430 // Bad signature.
1431 path = data_dir().AppendASCII("bad_signature.crx");
1432 InstallCRX(path, INSTALL_FAILED);
1433 ValidatePrefKeyCount(pref_count);
1435 // 0-length extension file.
1436 path = data_dir().AppendASCII("not_an_extension.crx");
1437 InstallCRX(path, INSTALL_FAILED);
1438 ValidatePrefKeyCount(pref_count);
1440 // Bad magic number.
1441 path = data_dir().AppendASCII("bad_magic.crx");
1442 InstallCRX(path, INSTALL_FAILED);
1443 ValidatePrefKeyCount(pref_count);
1445 // Packed extensions may have folders or files that have underscores.
1446 // This will only cause a warning, rather than a fatal error.
1447 path = data_dir().AppendASCII("bad_underscore.crx");
1448 InstallCRX(path, INSTALL_NEW);
1449 ValidatePrefKeyCount(++pref_count);
1451 // A test for an extension with a 2048-bit public key.
1452 path = data_dir().AppendASCII("good2048.crx");
1453 InstallCRX(path, INSTALL_NEW);
1454 ValidatePrefKeyCount(++pref_count);
1455 ValidateIntegerPref(good2048, "state", Extension::ENABLED);
1456 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
1458 // TODO(erikkay): add more tests for many of the failure cases.
1459 // TODO(erikkay): add tests for upgrade cases.
1462 struct MockExtensionRegistryObserver
1463 : public extensions::ExtensionRegistryObserver {
1464 virtual void OnExtensionWillBeInstalled(
1465 content::BrowserContext* browser_context,
1466 const Extension* extension,
1467 bool is_update,
1468 bool from_ephemeral,
1469 const std::string& old_name) override {
1470 last_extension_installed = extension->id();
1473 virtual void OnExtensionUninstalled(
1474 content::BrowserContext* browser_context,
1475 const Extension* extension,
1476 extensions::UninstallReason reason) override {
1477 last_extension_uninstalled = extension->id();
1480 std::string last_extension_installed;
1481 std::string last_extension_uninstalled;
1484 // Test that correct notifications are sent to ExtensionRegistryObserver on
1485 // extension install and uninstall.
1486 TEST_F(ExtensionServiceTest, InstallObserverNotified) {
1487 InitializeEmptyExtensionService();
1489 extensions::ExtensionRegistry* registry(
1490 extensions::ExtensionRegistry::Get(profile()));
1491 MockExtensionRegistryObserver observer;
1492 registry->AddObserver(&observer);
1494 // A simple extension that should install without error.
1495 ASSERT_TRUE(observer.last_extension_installed.empty());
1496 base::FilePath path = data_dir().AppendASCII("good.crx");
1497 InstallCRX(path, INSTALL_NEW);
1498 ASSERT_EQ(good_crx, observer.last_extension_installed);
1500 // Uninstall the extension.
1501 ASSERT_TRUE(observer.last_extension_uninstalled.empty());
1502 UninstallExtension(good_crx, false);
1503 ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
1505 registry->RemoveObserver(&observer);
1508 // Tests that flags passed to OnExternalExtensionFileFound() make it to the
1509 // extension object.
1510 TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
1511 const char kPrefFromBookmark[] = "from_bookmark";
1513 InitializeEmptyExtensionService();
1515 base::FilePath path = data_dir().AppendASCII("good.crx");
1516 service()->set_extensions_enabled(true);
1518 // Register and install an external extension.
1519 Version version("1.0.0.0");
1520 content::WindowedNotificationObserver observer(
1521 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1522 content::NotificationService::AllSources());
1523 if (service()->OnExternalExtensionFileFound(good_crx,
1524 &version,
1525 path,
1526 Manifest::EXTERNAL_PREF,
1527 Extension::FROM_BOOKMARK,
1528 false /* mark_acknowledged */)) {
1529 observer.Wait();
1532 const Extension* extension = service()->GetExtensionById(good_crx, false);
1533 ASSERT_TRUE(extension);
1534 ASSERT_TRUE(extension->from_bookmark());
1535 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1537 // Upgrade to version 2.0, the flag should be preserved.
1538 path = data_dir().AppendASCII("good2.crx");
1539 UpdateExtension(good_crx, path, ENABLED);
1540 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1541 extension = service()->GetExtensionById(good_crx, false);
1542 ASSERT_TRUE(extension);
1543 ASSERT_TRUE(extension->from_bookmark());
1546 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1547 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
1548 InitializeEmptyExtensionService();
1550 base::FilePath path = data_dir().AppendASCII("good.crx");
1551 service()->set_extensions_enabled(true);
1553 // Install an external extension.
1554 Version version("1.0.0.0");
1555 content::WindowedNotificationObserver observer(
1556 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1557 content::NotificationService::AllSources());
1558 if (service()->OnExternalExtensionFileFound(good_crx,
1559 &version,
1560 path,
1561 Manifest::EXTERNAL_PREF,
1562 Extension::NO_FLAGS,
1563 false)) {
1564 observer.Wait();
1567 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1569 // Uninstall it and check that its killbit gets set.
1570 UninstallExtension(good_crx, false);
1571 ValidateIntegerPref(good_crx, "state",
1572 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1574 // Try to re-install it externally. This should fail because of the killbit.
1575 service()->OnExternalExtensionFileFound(good_crx,
1576 &version,
1577 path,
1578 Manifest::EXTERNAL_PREF,
1579 Extension::NO_FLAGS,
1580 false);
1581 base::RunLoop().RunUntilIdle();
1582 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1583 ValidateIntegerPref(good_crx, "state",
1584 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1586 version = Version("1.0.0.1");
1587 // Repeat the same thing with a newer version of the extension.
1588 path = data_dir().AppendASCII("good2.crx");
1589 service()->OnExternalExtensionFileFound(good_crx,
1590 &version,
1591 path,
1592 Manifest::EXTERNAL_PREF,
1593 Extension::NO_FLAGS,
1594 false);
1595 base::RunLoop().RunUntilIdle();
1596 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1597 ValidateIntegerPref(good_crx, "state",
1598 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1600 // Try adding the same extension from an external update URL.
1601 ASSERT_FALSE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
1602 good_crx,
1603 std::string(),
1604 GURL("http:://fake.update/url"),
1605 Manifest::EXTERNAL_PREF_DOWNLOAD,
1606 Extension::NO_FLAGS,
1607 false));
1609 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
1612 // Test that uninstalling an external extension does not crash when
1613 // the extension could not be loaded.
1614 // This extension shown in preferences file requires an experimental permission.
1615 // It could not be loaded without such permission.
1616 TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
1617 base::FilePath source_install_dir =
1618 data_dir().AppendASCII("good").AppendASCII("Extensions");
1619 // The preference contains an external extension
1620 // that requires 'experimental' permission.
1621 base::FilePath pref_path = source_install_dir
1622 .DirName()
1623 .AppendASCII("PreferencesExperimental");
1625 // Aforementioned extension will not be loaded if
1626 // there is no '--enable-experimental-extension-apis' command line flag.
1627 InitializeInstalledExtensionService(pref_path, source_install_dir);
1629 service()->Init();
1631 // Check and try to uninstall it.
1632 // If we don't check whether the extension is loaded before we uninstall it
1633 // in CheckExternalUninstall, a crash will happen here because we will get or
1634 // dereference a NULL pointer (extension) inside UninstallExtension.
1635 MockExtensionProvider provider(NULL, Manifest::EXTERNAL_REGISTRY);
1636 service()->OnExternalProviderReady(&provider);
1639 // Test that external extensions with incorrect IDs are not installed.
1640 TEST_F(ExtensionServiceTest, FailOnWrongId) {
1641 InitializeEmptyExtensionService();
1642 base::FilePath path = data_dir().AppendASCII("good.crx");
1643 service()->set_extensions_enabled(true);
1645 Version version("1.0.0.0");
1647 const std::string wrong_id = all_zero;
1648 const std::string correct_id = good_crx;
1649 ASSERT_NE(correct_id, wrong_id);
1651 // Install an external extension with an ID from the external
1652 // source that is not equal to the ID in the extension manifest.
1653 content::WindowedNotificationObserver observer(
1654 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1655 content::NotificationService::AllSources());
1656 service()->OnExternalExtensionFileFound(wrong_id,
1657 &version,
1658 path,
1659 Manifest::EXTERNAL_PREF,
1660 Extension::NO_FLAGS,
1661 false);
1663 observer.Wait();
1664 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1666 // Try again with the right ID. Expect success.
1667 content::WindowedNotificationObserver observer2(
1668 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1669 content::NotificationService::AllSources());
1670 if (service()->OnExternalExtensionFileFound(correct_id,
1671 &version,
1672 path,
1673 Manifest::EXTERNAL_PREF,
1674 Extension::NO_FLAGS,
1675 false)) {
1676 observer2.Wait();
1678 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1681 // Test that external extensions with incorrect versions are not installed.
1682 TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1683 InitializeEmptyExtensionService();
1684 base::FilePath path = data_dir().AppendASCII("good.crx");
1685 service()->set_extensions_enabled(true);
1687 // Install an external extension with a version from the external
1688 // source that is not equal to the version in the extension manifest.
1689 Version wrong_version("1.2.3.4");
1690 content::WindowedNotificationObserver observer(
1691 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1692 content::NotificationService::AllSources());
1693 service()->OnExternalExtensionFileFound(good_crx,
1694 &wrong_version,
1695 path,
1696 Manifest::EXTERNAL_PREF,
1697 Extension::NO_FLAGS,
1698 false);
1700 observer.Wait();
1701 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1703 // Try again with the right version. Expect success.
1704 service()->pending_extension_manager()->Remove(good_crx);
1705 Version correct_version("1.0.0.0");
1706 content::WindowedNotificationObserver observer2(
1707 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1708 content::NotificationService::AllSources());
1709 if (service()->OnExternalExtensionFileFound(good_crx,
1710 &correct_version,
1711 path,
1712 Manifest::EXTERNAL_PREF,
1713 Extension::NO_FLAGS,
1714 false)) {
1715 observer2.Wait();
1717 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1720 // Install a user script (they get converted automatically to an extension)
1721 TEST_F(ExtensionServiceTest, InstallUserScript) {
1722 // The details of script conversion are tested elsewhere, this just tests
1723 // integration with ExtensionService.
1724 InitializeEmptyExtensionService();
1726 base::FilePath path = data_dir().AppendASCII("user_script_basic.user.js");
1728 ASSERT_TRUE(base::PathExists(path));
1729 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1730 installer->set_allow_silent_install(true);
1731 installer->InstallUserScript(
1732 path,
1733 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1735 base::RunLoop().RunUntilIdle();
1736 std::vector<base::string16> errors = GetErrors();
1737 EXPECT_TRUE(installed_) << "Nothing was installed.";
1738 EXPECT_FALSE(was_update_) << path.value();
1739 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1740 EXPECT_EQ(0u, errors.size()) << "There were errors: "
1741 << JoinString(errors, ',');
1742 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false))
1743 << path.value();
1745 installed_ = NULL;
1746 was_update_ = false;
1747 loaded_.clear();
1748 ExtensionErrorReporter::GetInstance()->ClearErrors();
1751 // Extensions don't install during shutdown.
1752 TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
1753 InitializeEmptyExtensionService();
1755 // Simulate shutdown.
1756 service()->set_browser_terminating_for_test(true);
1758 base::FilePath path = data_dir().AppendASCII("good.crx");
1759 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1760 installer->set_allow_silent_install(true);
1761 installer->InstallCrx(path);
1762 base::RunLoop().RunUntilIdle();
1764 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
1765 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
1768 // This tests that the granted permissions preferences are correctly set when
1769 // installing an extension.
1770 TEST_F(ExtensionServiceTest, GrantedPermissions) {
1771 InitializeEmptyExtensionService();
1772 base::FilePath path = data_dir().AppendASCII("permissions");
1774 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1775 path = path.AppendASCII("unknown");
1777 ASSERT_TRUE(base::PathExists(pem_path));
1778 ASSERT_TRUE(base::PathExists(path));
1780 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1782 APIPermissionSet expected_api_perms;
1783 URLPatternSet expected_host_perms;
1785 // Make sure there aren't any granted permissions before the
1786 // extension is installed.
1787 scoped_refptr<PermissionSet> known_perms(
1788 prefs->GetGrantedPermissions(permissions_crx));
1789 EXPECT_FALSE(known_perms.get());
1791 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
1793 EXPECT_EQ(0u, GetErrors().size());
1794 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1795 EXPECT_EQ(permissions_crx, extension->id());
1797 // Verify that the valid API permissions have been recognized.
1798 expected_api_perms.insert(APIPermission::kTab);
1800 AddPattern(&expected_host_perms, "http://*.google.com/*");
1801 AddPattern(&expected_host_perms, "https://*.google.com/*");
1802 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
1803 AddPattern(&expected_host_perms, "http://www.example.com/*");
1805 known_perms = prefs->GetGrantedPermissions(extension->id());
1806 EXPECT_TRUE(known_perms.get());
1807 EXPECT_FALSE(known_perms->IsEmpty());
1808 EXPECT_EQ(expected_api_perms, known_perms->apis());
1809 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1810 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
1814 #if !defined(OS_CHROMEOS)
1815 // This tests that the granted permissions preferences are correctly set for
1816 // default apps.
1817 TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
1818 InitializeEmptyExtensionService();
1819 base::FilePath path = data_dir().AppendASCII("permissions");
1821 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1822 path = path.AppendASCII("unknown");
1824 ASSERT_TRUE(base::PathExists(pem_path));
1825 ASSERT_TRUE(base::PathExists(path));
1827 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1829 APIPermissionSet expected_api_perms;
1830 URLPatternSet expected_host_perms;
1832 // Make sure there aren't any granted permissions before the
1833 // extension is installed.
1834 scoped_refptr<PermissionSet> known_perms(
1835 prefs->GetGrantedPermissions(permissions_crx));
1836 EXPECT_FALSE(known_perms.get());
1838 const Extension* extension = PackAndInstallCRX(
1839 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
1841 EXPECT_EQ(0u, GetErrors().size());
1842 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1843 EXPECT_EQ(permissions_crx, extension->id());
1845 // Verify that the valid API permissions have been recognized.
1846 expected_api_perms.insert(APIPermission::kTab);
1848 known_perms = prefs->GetGrantedPermissions(extension->id());
1849 EXPECT_TRUE(known_perms.get());
1850 EXPECT_FALSE(known_perms->IsEmpty());
1851 EXPECT_EQ(expected_api_perms, known_perms->apis());
1852 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1854 #endif
1856 #if !defined(OS_POSIX) || defined(OS_MACOSX)
1857 // Tests that the granted permissions full_access bit gets set correctly when
1858 // an extension contains an NPAPI plugin.
1859 // Only run this on platforms that support NPAPI plugins.
1860 TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
1861 InitPluginService();
1863 InitializeEmptyExtensionService();
1865 ASSERT_TRUE(base::PathExists(good1_path()));
1866 const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW);
1867 EXPECT_EQ(0u, GetErrors().size());
1868 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1869 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1871 scoped_refptr<PermissionSet> permissions(
1872 prefs->GetGrantedPermissions(extension->id()));
1873 EXPECT_FALSE(permissions->IsEmpty());
1874 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
1875 EXPECT_FALSE(permissions->apis().empty());
1876 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
1878 // Full access implies full host access too...
1879 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
1881 #endif
1883 // Tests that the extension is disabled when permissions are missing from
1884 // the extension's granted permissions preferences. (This simulates updating
1885 // the browser to a version which recognizes more permissions).
1886 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
1887 InitializeEmptyExtensionService();
1889 base::FilePath path =
1890 data_dir().AppendASCII("permissions").AppendASCII("unknown");
1892 ASSERT_TRUE(base::PathExists(path));
1894 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
1896 EXPECT_EQ(0u, GetErrors().size());
1897 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1898 std::string extension_id = extension->id();
1900 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1902 APIPermissionSet expected_api_permissions;
1903 URLPatternSet expected_host_permissions;
1905 expected_api_permissions.insert(APIPermission::kTab);
1906 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1907 AddPattern(&expected_host_permissions, "https://*.google.com/*");
1908 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
1909 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1911 std::set<std::string> host_permissions;
1913 // Test that the extension is disabled when an API permission is missing from
1914 // the extension's granted api permissions preference. (This simulates
1915 // updating the browser to a version which recognizes a new API permission).
1916 SetPref(extension_id, "granted_permissions.api",
1917 new base::ListValue(), "granted_permissions.api");
1918 service()->ReloadExtensionsForTest();
1920 EXPECT_EQ(1u, registry()->disabled_extensions().size());
1921 extension = registry()->disabled_extensions().begin()->get();
1923 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
1924 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
1925 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1927 // Now grant and re-enable the extension, making sure the prefs are updated.
1928 service()->GrantPermissionsAndEnableExtension(extension);
1930 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
1931 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
1932 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1934 scoped_refptr<PermissionSet> current_perms(
1935 prefs->GetGrantedPermissions(extension_id));
1936 ASSERT_TRUE(current_perms.get());
1937 ASSERT_FALSE(current_perms->IsEmpty());
1938 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
1939 ASSERT_EQ(expected_api_permissions, current_perms->apis());
1940 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
1942 // Tests that the extension is disabled when a host permission is missing from
1943 // the extension's granted host permissions preference. (This simulates
1944 // updating the browser to a version which recognizes additional host
1945 // permissions).
1946 host_permissions.clear();
1947 current_perms = NULL;
1949 host_permissions.insert("http://*.google.com/*");
1950 host_permissions.insert("https://*.google.com/*");
1951 host_permissions.insert("http://*.google.com.hk/*");
1953 base::ListValue* api_permissions = new base::ListValue();
1954 api_permissions->Append(
1955 new base::StringValue("tabs"));
1956 SetPref(extension_id, "granted_permissions.api",
1957 api_permissions, "granted_permissions.api");
1958 SetPrefStringSet(
1959 extension_id, "granted_permissions.scriptable_host", host_permissions);
1961 service()->ReloadExtensionsForTest();
1963 EXPECT_EQ(1u, registry()->disabled_extensions().size());
1964 extension = registry()->disabled_extensions().begin()->get();
1966 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
1967 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
1968 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1970 // Now grant and re-enable the extension, making sure the prefs are updated.
1971 service()->GrantPermissionsAndEnableExtension(extension);
1973 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
1974 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1976 current_perms = prefs->GetGrantedPermissions(extension_id);
1977 ASSERT_TRUE(current_perms.get());
1978 ASSERT_FALSE(current_perms->IsEmpty());
1979 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
1980 ASSERT_EQ(expected_api_permissions, current_perms->apis());
1981 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
1984 // Test Packaging and installing an extension.
1985 TEST_F(ExtensionServiceTest, PackExtension) {
1986 InitializeEmptyExtensionService();
1987 base::FilePath input_directory =
1988 data_dir()
1989 .AppendASCII("good")
1990 .AppendASCII("Extensions")
1991 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
1992 .AppendASCII("1.0.0.0");
1994 base::ScopedTempDir temp_dir;
1995 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
1996 base::FilePath output_directory = temp_dir.path();
1998 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
1999 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2001 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2002 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2003 privkey_path, ExtensionCreator::kNoRunFlags));
2004 ASSERT_TRUE(base::PathExists(crx_path));
2005 ASSERT_TRUE(base::PathExists(privkey_path));
2007 // Repeat the run with the pem file gone, and no special flags
2008 // Should refuse to overwrite the existing crx.
2009 base::DeleteFile(privkey_path, false);
2010 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2011 privkey_path, ExtensionCreator::kNoRunFlags));
2013 // OK, now try it with a flag to overwrite existing crx. Should work.
2014 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2015 privkey_path, ExtensionCreator::kOverwriteCRX));
2017 // Repeat the run allowing existing crx, but the existing pem is still
2018 // an error. Should fail.
2019 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2020 privkey_path, ExtensionCreator::kOverwriteCRX));
2022 ASSERT_TRUE(base::PathExists(privkey_path));
2023 InstallCRX(crx_path, INSTALL_NEW);
2025 // Try packing with invalid paths.
2026 creator.reset(new ExtensionCreator());
2027 ASSERT_FALSE(
2028 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
2029 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2031 // Try packing an empty directory. Should fail because an empty directory is
2032 // not a valid extension.
2033 base::ScopedTempDir temp_dir2;
2034 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
2035 creator.reset(new ExtensionCreator());
2036 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2037 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2039 // Try packing with an invalid manifest.
2040 std::string invalid_manifest_content = "I am not a manifest.";
2041 ASSERT_TRUE(base::WriteFile(
2042 temp_dir2.path().Append(extensions::kManifestFilename),
2043 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
2044 creator.reset(new ExtensionCreator());
2045 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2046 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2048 // Try packing with a private key that is a valid key, but invalid for the
2049 // extension.
2050 base::FilePath bad_private_key_dir =
2051 data_dir().AppendASCII("bad_private_key");
2052 crx_path = output_directory.AppendASCII("bad_private_key.crx");
2053 privkey_path = data_dir().AppendASCII("bad_private_key.pem");
2054 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
2055 privkey_path, ExtensionCreator::kOverwriteCRX));
2058 // Test Packaging and installing an extension whose name contains punctuation.
2059 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
2060 InitializeEmptyExtensionService();
2061 base::FilePath input_directory = data_dir()
2062 .AppendASCII("good")
2063 .AppendASCII("Extensions")
2064 .AppendASCII(good0)
2065 .AppendASCII("1.0.0.0");
2067 base::ScopedTempDir temp_dir;
2068 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2070 // Extension names containing punctuation, and the expected names for the
2071 // packed extensions.
2072 const base::FilePath punctuated_names[] = {
2073 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2074 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2075 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
2076 NormalizePathSeparators(),
2078 const base::FilePath expected_crx_names[] = {
2079 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2080 base::FilePath(
2081 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2082 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
2084 const base::FilePath expected_private_key_names[] = {
2085 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2086 base::FilePath(
2087 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2088 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
2091 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
2092 SCOPED_TRACE(punctuated_names[i].value().c_str());
2093 base::FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
2095 // Copy the extension into the output directory, as PackExtensionJob doesn't
2096 // let us choose where to output the packed extension.
2097 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
2099 base::FilePath expected_crx_path =
2100 temp_dir.path().Append(expected_crx_names[i]);
2101 base::FilePath expected_private_key_path =
2102 temp_dir.path().Append(expected_private_key_names[i]);
2103 PackExtensionTestClient pack_client(expected_crx_path,
2104 expected_private_key_path);
2105 scoped_refptr<extensions::PackExtensionJob> packer(
2106 new extensions::PackExtensionJob(&pack_client, output_dir,
2107 base::FilePath(),
2108 ExtensionCreator::kOverwriteCRX));
2109 packer->Start();
2111 // The packer will post a notification task to the current thread's message
2112 // loop when it is finished. We manually run the loop here so that we
2113 // block and catch the notification; otherwise, the process would exit.
2114 // This call to |Run()| is matched by a call to |Quit()| in the
2115 // |PackExtensionTestClient|'s notification handling code.
2116 base::MessageLoop::current()->Run();
2118 if (HasFatalFailure())
2119 return;
2121 InstallCRX(expected_crx_path, INSTALL_NEW);
2125 TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
2126 InitializeEmptyExtensionService();
2128 base::ScopedTempDir extension_temp_dir;
2129 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
2130 base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
2131 ASSERT_TRUE(
2132 base::CopyDirectory(data_dir()
2133 .AppendASCII("good")
2134 .AppendASCII("Extensions")
2135 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2136 .AppendASCII("1.0.0.0"),
2137 input_directory,
2138 /*recursive=*/true));
2140 base::ScopedTempDir output_temp_dir;
2141 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
2142 base::FilePath output_directory = output_temp_dir.path();
2144 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2145 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2147 // Pack the extension once to get a private key.
2148 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2149 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2150 privkey_path, ExtensionCreator::kNoRunFlags))
2151 << creator->error_message();
2152 ASSERT_TRUE(base::PathExists(crx_path));
2153 ASSERT_TRUE(base::PathExists(privkey_path));
2155 base::DeleteFile(crx_path, false);
2156 // Move the pem file into the extension.
2157 base::Move(privkey_path,
2158 input_directory.AppendASCII("privkey.pem"));
2160 // This pack should fail because of the contained private key.
2161 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2162 privkey_path, ExtensionCreator::kNoRunFlags));
2163 EXPECT_THAT(creator->error_message(),
2164 testing::ContainsRegex(
2165 "extension includes the key file.*privkey.pem"));
2168 // Test Packaging and installing an extension using an openssl generated key.
2169 // The openssl is generated with the following:
2170 // > openssl genrsa -out privkey.pem 1024
2171 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
2172 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
2173 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
2174 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
2175 InitializeEmptyExtensionService();
2176 base::FilePath input_directory =
2177 data_dir()
2178 .AppendASCII("good")
2179 .AppendASCII("Extensions")
2180 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2181 .AppendASCII("1.0.0.0");
2182 base::FilePath privkey_path(
2183 data_dir().AppendASCII("openssl_privkey_asn1.pem"));
2184 ASSERT_TRUE(base::PathExists(privkey_path));
2186 base::ScopedTempDir temp_dir;
2187 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2188 base::FilePath output_directory = temp_dir.path();
2190 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2192 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2193 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
2194 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2196 InstallCRX(crx_path, INSTALL_NEW);
2199 #if defined(THREAD_SANITIZER)
2200 // Flaky under Tsan. http://crbug.com/377702
2201 #define MAYBE_InstallTheme DISABLED_InstallTheme
2202 #else
2203 #define MAYBE_InstallTheme InstallTheme
2204 #endif
2206 TEST_F(ExtensionServiceTest, MAYBE_InstallTheme) {
2207 InitializeEmptyExtensionService();
2208 service()->Init();
2210 // A theme.
2211 base::FilePath path = data_dir().AppendASCII("theme.crx");
2212 InstallCRX(path, INSTALL_NEW);
2213 int pref_count = 0;
2214 ValidatePrefKeyCount(++pref_count);
2215 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2216 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2218 // A theme when extensions are disabled. Themes can be installed, even when
2219 // extensions are disabled.
2220 service()->set_extensions_enabled(false);
2221 path = data_dir().AppendASCII("theme2.crx");
2222 InstallCRX(path, INSTALL_NEW);
2223 ValidatePrefKeyCount(++pref_count);
2224 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
2225 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
2227 // A theme with extension elements. Themes cannot have extension elements,
2228 // so any such elements (like content scripts) should be ignored.
2229 service()->set_extensions_enabled(true);
2231 path = data_dir().AppendASCII("theme_with_extension.crx");
2232 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2233 ValidatePrefKeyCount(++pref_count);
2234 ASSERT_TRUE(extension);
2235 EXPECT_TRUE(extension->is_theme());
2236 EXPECT_EQ(
2238 extensions::ContentScriptsInfo::GetContentScripts(extension).size());
2241 // A theme with image resources missing (misspelt path).
2242 path = data_dir().AppendASCII("theme_missing_image.crx");
2243 InstallCRX(path, INSTALL_FAILED);
2244 ValidatePrefKeyCount(pref_count);
2247 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
2248 // Load.
2249 InitializeEmptyExtensionService();
2250 service()->Init();
2252 base::FilePath extension_path = data_dir().AppendASCII("theme_i18n");
2254 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2255 base::RunLoop().RunUntilIdle();
2256 EXPECT_EQ(0u, GetErrors().size());
2257 ASSERT_EQ(1u, loaded_.size());
2258 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2259 const Extension* theme = registry()->enabled_extensions().begin()->get();
2260 EXPECT_EQ("name", theme->name());
2261 EXPECT_EQ("description", theme->description());
2263 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a
2264 // temporary directory, but it automatically installs to the extension's
2265 // directory, and we don't want to copy the whole extension for a unittest.
2266 base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
2267 ASSERT_TRUE(base::PathExists(theme_file));
2268 ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive.
2271 // Tests that we can change the ID of an unpacked extension by adding a key
2272 // to its manifest.
2273 TEST_F(ExtensionServiceTest, UnpackedExtensionCanChangeID) {
2274 InitializeEmptyExtensionService();
2276 base::ScopedTempDir temp;
2277 ASSERT_TRUE(temp.CreateUniqueTempDir());
2279 base::FilePath extension_path = temp.path();
2280 base::FilePath manifest_path =
2281 extension_path.Append(extensions::kManifestFilename);
2282 base::FilePath manifest_no_key =
2283 data_dir().AppendASCII("unpacked").AppendASCII("manifest_no_key.json");
2285 base::FilePath manifest_with_key =
2286 data_dir().AppendASCII("unpacked").AppendASCII("manifest_with_key.json");
2288 ASSERT_TRUE(base::PathExists(manifest_no_key));
2289 ASSERT_TRUE(base::PathExists(manifest_with_key));
2291 // Load the unpacked extension with no key.
2292 base::CopyFile(manifest_no_key, manifest_path);
2293 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2295 base::RunLoop().RunUntilIdle();
2296 EXPECT_EQ(0u, GetErrors().size());
2297 ASSERT_EQ(1u, loaded_.size());
2298 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2300 // Add the key to the manifest.
2301 base::CopyFile(manifest_with_key, manifest_path);
2302 loaded_.clear();
2304 // Reload the extensions.
2305 service()->ReloadExtensionsForTest();
2306 const Extension* extension = service()->GetExtensionById(unpacked, false);
2307 EXPECT_EQ(unpacked, extension->id());
2308 ASSERT_EQ(1u, loaded_.size());
2310 // TODO(jstritar): Right now this just makes sure we don't crash and burn, but
2311 // we should also test that preferences are preserved.
2314 #if defined(OS_POSIX)
2315 TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
2316 base::FilePath source_data_dir =
2317 data_dir().AppendASCII("unpacked").AppendASCII("symlinks_allowed");
2319 // Paths to test data files.
2320 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2321 ASSERT_TRUE(base::PathExists(source_manifest));
2322 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2323 ASSERT_TRUE(base::PathExists(source_icon));
2325 // Set up the temporary extension directory.
2326 base::ScopedTempDir temp;
2327 ASSERT_TRUE(temp.CreateUniqueTempDir());
2328 base::FilePath extension_path = temp.path();
2329 base::FilePath manifest = extension_path.Append(
2330 extensions::kManifestFilename);
2331 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2332 base::CopyFile(source_manifest, manifest);
2333 base::CreateSymbolicLink(source_icon, icon_symlink);
2335 // Load extension.
2336 InitializeEmptyExtensionService();
2337 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2338 base::RunLoop().RunUntilIdle();
2340 EXPECT_TRUE(GetErrors().empty());
2341 ASSERT_EQ(1u, loaded_.size());
2342 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2344 #endif
2346 TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
2347 InitializeEmptyExtensionService();
2348 base::FilePath extension_path = data_dir().AppendASCII("underscore_name");
2349 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2350 base::RunLoop().RunUntilIdle();
2351 EXPECT_EQ(1u, GetErrors().size());
2352 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2355 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
2356 InitializeEmptyExtensionService();
2357 service()->Init();
2359 base::FilePath theme_path = data_dir().AppendASCII("theme_i18n");
2361 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
2363 EXPECT_EQ(0u, GetErrors().size());
2364 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2365 EXPECT_EQ("name", theme->name());
2366 EXPECT_EQ("description", theme->description());
2369 TEST_F(ExtensionServiceTest, InstallApps) {
2370 InitializeEmptyExtensionService();
2372 // An empty app.
2373 const Extension* app =
2374 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2375 int pref_count = 0;
2376 ValidatePrefKeyCount(++pref_count);
2377 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2378 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2379 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
2381 // Another app with non-overlapping extent. Should succeed.
2382 PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2383 ValidatePrefKeyCount(++pref_count);
2385 // A third app whose extent overlaps the first. Should fail.
2386 PackAndInstallCRX(data_dir().AppendASCII("app3"), INSTALL_FAILED);
2387 ValidatePrefKeyCount(pref_count);
2390 // Tests that file access is OFF by default.
2391 TEST_F(ExtensionServiceTest, DefaultFileAccess) {
2392 InitializeEmptyExtensionService();
2393 const Extension* extension = PackAndInstallCRX(
2394 data_dir().AppendASCII("permissions").AppendASCII("files"), INSTALL_NEW);
2395 EXPECT_EQ(0u, GetErrors().size());
2396 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2397 EXPECT_FALSE(
2398 ExtensionPrefs::Get(profile())->AllowFileAccess(extension->id()));
2401 TEST_F(ExtensionServiceTest, UpdateApps) {
2402 InitializeEmptyExtensionService();
2403 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2405 // First install v1 of a hosted app.
2406 const Extension* extension =
2407 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2408 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2409 std::string id = extension->id();
2410 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2412 // Now try updating to v2.
2413 UpdateExtension(id,
2414 extensions_path.AppendASCII("v2.crx"),
2415 ENABLED);
2416 ASSERT_EQ(std::string("2"),
2417 service()->GetExtensionById(id, false)->version()->GetString());
2420 // Verifies that the NTP page and launch ordinals are kept when updating apps.
2421 TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
2422 InitializeEmptyExtensionService();
2423 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2424 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2426 // First install v1 of a hosted app.
2427 const Extension* extension =
2428 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2429 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2430 std::string id = extension->id();
2431 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2433 // Modify the ordinals so we can distinguish them from the defaults.
2434 syncer::StringOrdinal new_page_ordinal =
2435 sorting->GetPageOrdinal(id).CreateAfter();
2436 syncer::StringOrdinal new_launch_ordinal =
2437 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2439 sorting->SetPageOrdinal(id, new_page_ordinal);
2440 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2442 // Now try updating to v2.
2443 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2444 ASSERT_EQ(std::string("2"),
2445 service()->GetExtensionById(id, false)->version()->GetString());
2447 // Verify that the ordinals match.
2448 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2449 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
2452 // Ensures that the CWS has properly initialized ordinals.
2453 TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
2454 InitializeEmptyExtensionService();
2455 service()->component_loader()->Add(
2456 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
2457 service()->Init();
2459 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2460 EXPECT_TRUE(
2461 sorting->GetPageOrdinal(extensions::kWebStoreAppId).IsValid());
2462 EXPECT_TRUE(
2463 sorting->GetAppLaunchOrdinal(extensions::kWebStoreAppId).IsValid());
2466 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
2467 InitializeEmptyExtensionService();
2468 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2470 int pref_count = 0;
2472 // Install app1 with unlimited storage.
2473 const Extension* extension =
2474 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2475 ValidatePrefKeyCount(++pref_count);
2476 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2477 const std::string id1 = extension->id();
2478 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2479 APIPermission::kUnlimitedStorage));
2480 EXPECT_TRUE(extension->web_extent().MatchesURL(
2481 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2482 const GURL origin1(
2483 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2484 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2485 origin1));
2487 // Install app2 from the same origin with unlimited storage.
2488 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2489 ValidatePrefKeyCount(++pref_count);
2490 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2491 const std::string id2 = extension->id();
2492 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2493 APIPermission::kUnlimitedStorage));
2494 EXPECT_TRUE(extension->web_extent().MatchesURL(
2495 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2496 const GURL origin2(
2497 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2498 EXPECT_EQ(origin1, origin2);
2499 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2500 origin2));
2502 // Uninstall one of them, unlimited storage should still be granted
2503 // to the origin.
2504 UninstallExtension(id1, false);
2505 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2506 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2507 origin1));
2509 // Uninstall the other, unlimited storage should be revoked.
2510 UninstallExtension(id2, false);
2511 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2512 EXPECT_FALSE(
2513 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2514 origin2));
2517 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
2518 InitializeEmptyExtensionService();
2519 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2521 int pref_count = 0;
2523 const Extension* extension =
2524 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2525 ValidatePrefKeyCount(++pref_count);
2526 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2527 EXPECT_TRUE(extension->is_app());
2528 const std::string id1 = extension->id();
2529 const GURL origin1(
2530 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2531 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2532 origin1));
2534 // App 4 has a different origin (maps.google.com).
2535 extension = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
2536 ValidatePrefKeyCount(++pref_count);
2537 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2538 const std::string id2 = extension->id();
2539 const GURL origin2(
2540 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2541 ASSERT_NE(origin1, origin2);
2542 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2543 origin2));
2545 UninstallExtension(id1, false);
2546 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2548 UninstallExtension(id2, false);
2550 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2551 EXPECT_FALSE(
2552 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2553 origin1));
2554 EXPECT_FALSE(
2555 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2556 origin2));
2559 // Test that when an extension version is reinstalled, nothing happens.
2560 TEST_F(ExtensionServiceTest, Reinstall) {
2561 InitializeEmptyExtensionService();
2563 // A simple extension that should install without error.
2564 base::FilePath path = data_dir().AppendASCII("good.crx");
2565 InstallCRX(path, INSTALL_NEW);
2567 ValidatePrefKeyCount(1);
2568 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2569 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2571 // Reinstall the same version, it should overwrite the previous one.
2572 InstallCRX(path, INSTALL_UPDATED);
2574 ValidatePrefKeyCount(1);
2575 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2576 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2579 // Test that we can determine if extensions came from the
2580 // Chrome web store.
2581 TEST_F(ExtensionServiceTest, FromWebStore) {
2582 InitializeEmptyExtensionService();
2584 // A simple extension that should install without error.
2585 base::FilePath path = data_dir().AppendASCII("good.crx");
2586 // Not from web store.
2587 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2588 std::string id = extension->id();
2590 ValidatePrefKeyCount(1);
2591 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
2592 ASSERT_FALSE(extension->from_webstore());
2594 // Test install from web store.
2595 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
2597 ValidatePrefKeyCount(1);
2598 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2600 // Reload so extension gets reinitialized with new value.
2601 service()->ReloadExtensionsForTest();
2602 extension = service()->GetExtensionById(id, false);
2603 ASSERT_TRUE(extension->from_webstore());
2605 // Upgrade to version 2.0
2606 path = data_dir().AppendASCII("good2.crx");
2607 UpdateExtension(good_crx, path, ENABLED);
2608 ValidatePrefKeyCount(1);
2609 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2612 // Test upgrading a signed extension.
2613 TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
2614 InitializeEmptyExtensionService();
2616 base::FilePath path = data_dir().AppendASCII("good.crx");
2617 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2618 std::string id = extension->id();
2620 ASSERT_EQ("1.0.0.0", extension->version()->GetString());
2621 ASSERT_EQ(0u, GetErrors().size());
2623 // Upgrade to version 1.0.0.1.
2624 // Also test that the extension's old and new title are correctly retrieved.
2625 path = data_dir().AppendASCII("good2.crx");
2626 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
2627 extension = service()->GetExtensionById(id, false);
2629 ASSERT_EQ("1.0.0.1", extension->version()->GetString());
2630 ASSERT_EQ("My updated extension 1", extension->name());
2631 ASSERT_EQ(0u, GetErrors().size());
2634 // Test upgrading a signed extension with a bad signature.
2635 TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
2636 InitializeEmptyExtensionService();
2638 base::FilePath path = data_dir().AppendASCII("good.crx");
2639 InstallCRX(path, INSTALL_NEW);
2641 // Try upgrading with a bad signature. This should fail during the unpack,
2642 // because the key will not match the signature.
2643 path = data_dir().AppendASCII("bad_signature.crx");
2644 InstallCRX(path, INSTALL_FAILED);
2647 // Test a normal update via the UpdateExtension API
2648 TEST_F(ExtensionServiceTest, UpdateExtension) {
2649 InitializeEmptyExtensionService();
2651 base::FilePath path = data_dir().AppendASCII("good.crx");
2653 const Extension* good = InstallCRX(path, INSTALL_NEW);
2654 ASSERT_EQ("1.0.0.0", good->VersionString());
2655 ASSERT_EQ(good_crx, good->id());
2657 path = data_dir().AppendASCII("good2.crx");
2658 UpdateExtension(good_crx, path, ENABLED);
2659 ASSERT_EQ(
2660 "1.0.0.1",
2661 service()->GetExtensionById(good_crx, false)->version()->GetString());
2664 // Extensions should not be updated during browser shutdown.
2665 TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
2666 InitializeEmptyExtensionService();
2668 // Install an extension.
2669 base::FilePath path = data_dir().AppendASCII("good.crx");
2670 const Extension* good = InstallCRX(path, INSTALL_NEW);
2671 ASSERT_EQ(good_crx, good->id());
2673 // Simulate shutdown.
2674 service()->set_browser_terminating_for_test(true);
2676 // Update should fail and extension should not be updated.
2677 path = data_dir().AppendASCII("good2.crx");
2678 bool updated = service()->UpdateExtension(good_crx, path, true, NULL);
2679 ASSERT_FALSE(updated);
2680 ASSERT_EQ(
2681 "1.0.0.0",
2682 service()->GetExtensionById(good_crx, false)->version()->GetString());
2685 // Test updating a not-already-installed extension - this should fail
2686 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
2687 InitializeEmptyExtensionService();
2689 base::FilePath path = data_dir().AppendASCII("good.crx");
2690 UpdateExtension(good_crx, path, UPDATED);
2691 base::RunLoop().RunUntilIdle();
2693 ASSERT_EQ(0u, registry()->enabled_extensions().size());
2694 ASSERT_FALSE(installed_);
2695 ASSERT_EQ(0u, loaded_.size());
2698 // Makes sure you can't downgrade an extension via UpdateExtension
2699 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
2700 InitializeEmptyExtensionService();
2702 base::FilePath path = data_dir().AppendASCII("good2.crx");
2704 const Extension* good = InstallCRX(path, INSTALL_NEW);
2705 ASSERT_EQ("1.0.0.1", good->VersionString());
2706 ASSERT_EQ(good_crx, good->id());
2708 // Change path from good2.crx -> good.crx
2709 path = data_dir().AppendASCII("good.crx");
2710 UpdateExtension(good_crx, path, FAILED);
2711 ASSERT_EQ(
2712 "1.0.0.1",
2713 service()->GetExtensionById(good_crx, false)->version()->GetString());
2716 // Make sure calling update with an identical version does nothing
2717 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
2718 InitializeEmptyExtensionService();
2720 base::FilePath path = data_dir().AppendASCII("good.crx");
2722 const Extension* good = InstallCRX(path, INSTALL_NEW);
2723 ASSERT_EQ(good_crx, good->id());
2724 UpdateExtension(good_crx, path, FAILED_SILENTLY);
2727 // Tests that updating an extension does not clobber old state.
2728 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
2729 InitializeEmptyExtensionService();
2731 base::FilePath path = data_dir().AppendASCII("good.crx");
2733 const Extension* good = InstallCRX(path, INSTALL_NEW);
2734 ASSERT_EQ("1.0.0.0", good->VersionString());
2735 ASSERT_EQ(good_crx, good->id());
2737 // Disable it and allow it to run in incognito. These settings should carry
2738 // over to the updated version.
2739 service()->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
2740 extensions::util::SetIsIncognitoEnabled(good->id(), profile(), true);
2741 ExtensionPrefs::Get(profile())
2742 ->SetDidExtensionEscalatePermissions(good, true);
2744 path = data_dir().AppendASCII("good2.crx");
2745 UpdateExtension(good_crx, path, INSTALLED);
2746 ASSERT_EQ(1u, registry()->disabled_extensions().size());
2747 const Extension* good2 = service()->GetExtensionById(good_crx, true);
2748 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2749 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good2->id(), profile()));
2750 EXPECT_TRUE(ExtensionPrefs::Get(profile())
2751 ->DidExtensionEscalatePermissions(good2->id()));
2754 // Tests that updating preserves extension location.
2755 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
2756 InitializeEmptyExtensionService();
2758 base::FilePath path = data_dir().AppendASCII("good.crx");
2760 const Extension* good =
2761 InstallCRXWithLocation(path, Manifest::EXTERNAL_PREF, INSTALL_NEW);
2763 ASSERT_EQ("1.0.0.0", good->VersionString());
2764 ASSERT_EQ(good_crx, good->id());
2766 path = data_dir().AppendASCII("good2.crx");
2767 UpdateExtension(good_crx, path, ENABLED);
2768 const Extension* good2 = service()->GetExtensionById(good_crx, false);
2769 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2770 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
2773 // Makes sure that LOAD extension types can downgrade.
2774 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
2775 InitializeEmptyExtensionService();
2777 base::ScopedTempDir temp;
2778 ASSERT_TRUE(temp.CreateUniqueTempDir());
2780 // We'll write the extension manifest dynamically to a temporary path
2781 // to make it easier to change the version number.
2782 base::FilePath extension_path = temp.path();
2783 base::FilePath manifest_path =
2784 extension_path.Append(extensions::kManifestFilename);
2785 ASSERT_FALSE(base::PathExists(manifest_path));
2787 // Start with version 2.0.
2788 base::DictionaryValue manifest;
2789 manifest.SetString("version", "2.0");
2790 manifest.SetString("name", "LOAD Downgrade Test");
2791 manifest.SetInteger("manifest_version", 2);
2793 JSONFileValueSerializer serializer(manifest_path);
2794 ASSERT_TRUE(serializer.Serialize(manifest));
2796 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2797 base::RunLoop().RunUntilIdle();
2799 EXPECT_EQ(0u, GetErrors().size());
2800 ASSERT_EQ(1u, loaded_.size());
2801 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2802 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2803 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2805 // Now set the version number to 1.0, reload the extensions and verify that
2806 // the downgrade was accepted.
2807 manifest.SetString("version", "1.0");
2808 ASSERT_TRUE(serializer.Serialize(manifest));
2810 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2811 base::RunLoop().RunUntilIdle();
2813 EXPECT_EQ(0u, GetErrors().size());
2814 ASSERT_EQ(1u, loaded_.size());
2815 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2816 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2817 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2820 #if !defined(OS_POSIX) || defined(OS_MACOSX)
2821 // LOAD extensions with plugins require approval.
2822 // Only run this on platforms that support NPAPI plugins.
2823 TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
2824 base::FilePath extension_with_plugin_path = good1_path();
2825 base::FilePath extension_no_plugin_path = good2_path();
2827 InitPluginService();
2828 InitializeEmptyExtensionService();
2829 InitializeProcessManager();
2830 service()->set_show_extensions_prompts(true);
2832 // Start by canceling any install prompts.
2833 ExtensionInstallPrompt::g_auto_confirm_for_tests =
2834 ExtensionInstallPrompt::CANCEL;
2836 // The extension that has a plugin should not install.
2837 extensions::UnpackedInstaller::Create(service())
2838 ->Load(extension_with_plugin_path);
2839 base::RunLoop().RunUntilIdle();
2840 EXPECT_EQ(0u, GetErrors().size());
2841 EXPECT_EQ(0u, loaded_.size());
2842 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2843 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2845 // But the extension with no plugin should since there's no prompt.
2846 ExtensionErrorReporter::GetInstance()->ClearErrors();
2847 extensions::UnpackedInstaller::Create(service())
2848 ->Load(extension_no_plugin_path);
2849 base::RunLoop().RunUntilIdle();
2850 EXPECT_EQ(0u, GetErrors().size());
2851 EXPECT_EQ(1u, loaded_.size());
2852 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2853 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2854 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2856 // The plugin extension should install if we accept the dialog.
2857 ExtensionInstallPrompt::g_auto_confirm_for_tests =
2858 ExtensionInstallPrompt::ACCEPT;
2860 ExtensionErrorReporter::GetInstance()->ClearErrors();
2861 extensions::UnpackedInstaller::Create(service())
2862 ->Load(extension_with_plugin_path);
2863 base::RunLoop().RunUntilIdle();
2864 EXPECT_EQ(0u, GetErrors().size());
2865 EXPECT_EQ(2u, loaded_.size());
2866 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2867 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2868 EXPECT_TRUE(registry()->enabled_extensions().Contains(good1));
2869 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2871 // Make sure the granted permissions have been setup.
2872 scoped_refptr<PermissionSet> permissions(
2873 ExtensionPrefs::Get(profile())->GetGrantedPermissions(good1));
2874 EXPECT_FALSE(permissions->IsEmpty());
2875 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
2876 EXPECT_FALSE(permissions->apis().empty());
2877 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
2879 // We should be able to reload the extension without getting another prompt.
2880 loaded_.clear();
2881 ExtensionInstallPrompt::g_auto_confirm_for_tests =
2882 ExtensionInstallPrompt::CANCEL;
2884 service()->ReloadExtension(good1);
2885 base::RunLoop().RunUntilIdle();
2886 EXPECT_EQ(1u, loaded_.size());
2887 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2888 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2890 #endif // !defined(OS_POSIX) || defined(OS_MACOSX)
2892 namespace {
2894 bool IsExtension(const Extension* extension) {
2895 return extension->GetType() == Manifest::TYPE_EXTENSION;
2898 #if defined(ENABLE_BLACKLIST_TESTS)
2899 std::set<std::string> StringSet(const std::string& s) {
2900 std::set<std::string> set;
2901 set.insert(s);
2902 return set;
2904 std::set<std::string> StringSet(const std::string& s1, const std::string& s2) {
2905 std::set<std::string> set = StringSet(s1);
2906 set.insert(s2);
2907 return set;
2909 #endif // defined(ENABLE_BLACKLIST_TESTS)
2911 } // namespace
2913 // Test adding a pending extension.
2914 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
2915 InitializeEmptyExtensionService();
2917 const std::string kFakeId(all_zero);
2918 const GURL kFakeUpdateURL("http:://fake.update/url");
2919 const bool kFakeRemoteInstall(false);
2920 const bool kFakeInstalledByCustodian(false);
2922 EXPECT_TRUE(
2923 service()->pending_extension_manager()->AddFromSync(
2924 kFakeId,
2925 kFakeUpdateURL,
2926 &IsExtension,
2927 kFakeRemoteInstall,
2928 kFakeInstalledByCustodian));
2930 const extensions::PendingExtensionInfo* pending_extension_info;
2931 ASSERT_TRUE((pending_extension_info =
2932 service()->pending_extension_manager()->GetById(kFakeId)));
2933 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
2934 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
2935 // Use
2936 // EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install())
2937 // instead of
2938 // EXPECT_EQ(kFakeRemoteInstall, pending_extension_info->remote_install())
2939 // as gcc 4.7 issues the following warning on EXPECT_EQ(false, x), which is
2940 // turned into an error with -Werror=conversion-null:
2941 // converting 'false' to pointer type for argument 1 of
2942 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)'
2943 // https://code.google.com/p/googletest/issues/detail?id=458
2944 EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install());
2947 namespace {
2948 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2949 const char kGoodUpdateURL[] = "http://good.update/url";
2950 const bool kGoodIsFromSync = true;
2951 const bool kGoodRemoteInstall = false;
2952 const bool kGoodInstalledByCustodian = false;
2953 } // namespace
2955 // Test updating a pending extension.
2956 TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
2957 InitializeEmptyExtensionService();
2958 EXPECT_TRUE(
2959 service()->pending_extension_manager()->AddFromSync(
2960 kGoodId,
2961 GURL(kGoodUpdateURL),
2962 &IsExtension,
2963 kGoodRemoteInstall,
2964 kGoodInstalledByCustodian));
2965 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2967 base::FilePath path = data_dir().AppendASCII("good.crx");
2968 UpdateExtension(kGoodId, path, ENABLED);
2970 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2972 const Extension* extension = service()->GetExtensionById(kGoodId, true);
2973 ASSERT_TRUE(extension);
2976 namespace {
2978 bool IsTheme(const Extension* extension) {
2979 return extension->is_theme();
2982 } // namespace
2984 // Test updating a pending theme.
2985 // Disabled due to ASAN failure. http://crbug.com/108320
2986 TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
2987 InitializeEmptyExtensionService();
2988 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
2989 theme_crx, GURL(), &IsTheme, false, false));
2990 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
2992 base::FilePath path = data_dir().AppendASCII("theme.crx");
2993 UpdateExtension(theme_crx, path, ENABLED);
2995 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
2997 const Extension* extension = service()->GetExtensionById(theme_crx, true);
2998 ASSERT_TRUE(extension);
3000 EXPECT_FALSE(
3001 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3002 EXPECT_TRUE(service()->IsExtensionEnabled(theme_crx));
3005 #if defined(OS_CHROMEOS)
3006 // Always fails on ChromeOS: http://crbug.com/79737
3007 #define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
3008 #else
3009 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
3010 #endif
3011 // Test updating a pending CRX as if the source is an external extension
3012 // with an update URL. In this case we don't know if the CRX is a theme
3013 // or not.
3014 TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
3015 InitializeEmptyExtensionService();
3016 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3017 theme_crx,
3018 std::string(),
3019 GURL(),
3020 Manifest::EXTERNAL_PREF_DOWNLOAD,
3021 Extension::NO_FLAGS,
3022 false));
3024 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3026 base::FilePath path = data_dir().AppendASCII("theme.crx");
3027 UpdateExtension(theme_crx, path, ENABLED);
3029 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3031 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3032 ASSERT_TRUE(extension);
3034 EXPECT_FALSE(
3035 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3036 EXPECT_TRUE(service()->IsExtensionEnabled(extension->id()));
3037 EXPECT_FALSE(
3038 extensions::util::IsIncognitoEnabled(extension->id(), profile()));
3041 // Test updating a pending CRX as if the source is an external extension
3042 // with an update URL. The external update should overwrite a sync update,
3043 // but a sync update should not overwrite a non-sync update.
3044 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
3045 InitializeEmptyExtensionService();
3047 // Add a crx to be installed from the update mechanism.
3048 EXPECT_TRUE(
3049 service()->pending_extension_manager()->AddFromSync(
3050 kGoodId,
3051 GURL(kGoodUpdateURL),
3052 &IsExtension,
3053 kGoodRemoteInstall,
3054 kGoodInstalledByCustodian));
3056 // Check that there is a pending crx, with is_from_sync set to true.
3057 const extensions::PendingExtensionInfo* pending_extension_info;
3058 ASSERT_TRUE((pending_extension_info =
3059 service()->pending_extension_manager()->GetById(kGoodId)));
3060 EXPECT_TRUE(pending_extension_info->is_from_sync());
3062 // Add a crx to be updated, with the same ID, from a non-sync source.
3063 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3064 kGoodId,
3065 std::string(),
3066 GURL(kGoodUpdateURL),
3067 Manifest::EXTERNAL_PREF_DOWNLOAD,
3068 Extension::NO_FLAGS,
3069 false));
3071 // Check that there is a pending crx, with is_from_sync set to false.
3072 ASSERT_TRUE((pending_extension_info =
3073 service()->pending_extension_manager()->GetById(kGoodId)));
3074 EXPECT_FALSE(pending_extension_info->is_from_sync());
3075 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3076 pending_extension_info->install_source());
3078 // Add a crx to be installed from the update mechanism.
3079 EXPECT_FALSE(
3080 service()->pending_extension_manager()->AddFromSync(
3081 kGoodId,
3082 GURL(kGoodUpdateURL),
3083 &IsExtension,
3084 kGoodRemoteInstall,
3085 kGoodInstalledByCustodian));
3087 // Check that the external, non-sync update was not overridden.
3088 ASSERT_TRUE((pending_extension_info =
3089 service()->pending_extension_manager()->GetById(kGoodId)));
3090 EXPECT_FALSE(pending_extension_info->is_from_sync());
3091 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3092 pending_extension_info->install_source());
3095 // Updating a theme should fail if the updater is explicitly told that
3096 // the CRX is not a theme.
3097 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
3098 InitializeEmptyExtensionService();
3099 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3100 theme_crx, GURL(), &IsExtension, false, false));
3102 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3104 base::FilePath path = data_dir().AppendASCII("theme.crx");
3105 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
3107 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3109 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3110 ASSERT_FALSE(extension);
3113 // TODO(akalin): Test updating a pending extension non-silently once
3114 // we can mock out ExtensionInstallUI and inject our version into
3115 // UpdateExtension().
3117 // Test updating a pending extension which fails the should-install test.
3118 TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
3119 InitializeEmptyExtensionService();
3120 // Add pending extension with a flipped is_theme.
3121 EXPECT_TRUE(
3122 service()->pending_extension_manager()->AddFromSync(
3123 kGoodId,
3124 GURL(kGoodUpdateURL),
3125 &IsTheme,
3126 kGoodRemoteInstall,
3127 kGoodInstalledByCustodian));
3128 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3130 base::FilePath path = data_dir().AppendASCII("good.crx");
3131 UpdateExtension(kGoodId, path, UPDATED);
3133 // TODO(akalin): Figure out how to check that the extensions
3134 // directory is cleaned up properly in OnExtensionInstalled().
3136 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3139 // TODO(akalin): Figure out how to test that installs of pending
3140 // unsyncable extensions are blocked.
3142 // Test updating a pending extension for one that is not pending.
3143 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
3144 InitializeEmptyExtensionService();
3146 base::FilePath path = data_dir().AppendASCII("good.crx");
3147 UpdateExtension(kGoodId, path, UPDATED);
3149 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3152 // Test updating a pending extension for one that is already
3153 // installed.
3154 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
3155 InitializeEmptyExtensionService();
3157 base::FilePath path = data_dir().AppendASCII("good.crx");
3158 const Extension* good = InstallCRX(path, INSTALL_NEW);
3159 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3161 EXPECT_FALSE(good->is_theme());
3163 // Use AddExtensionImpl() as AddFrom*() would balk.
3164 service()->pending_extension_manager()->AddExtensionImpl(
3165 good->id(),
3166 std::string(),
3167 extensions::ManifestURL::GetUpdateURL(good),
3168 Version(),
3169 &IsExtension,
3170 kGoodIsFromSync,
3171 Manifest::INTERNAL,
3172 Extension::NO_FLAGS,
3173 false,
3174 kGoodRemoteInstall);
3175 UpdateExtension(good->id(), path, ENABLED);
3177 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3180 #if defined(ENABLE_BLACKLIST_TESTS)
3181 // Tests blacklisting then unblacklisting extensions after the service has been
3182 // initialized.
3183 TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
3184 extensions::TestBlacklist test_blacklist;
3185 // A profile with 3 extensions installed: good0, good1, and good2.
3186 InitializeGoodInstalledExtensionService();
3187 test_blacklist.Attach(service()->blacklist_);
3188 service()->Init();
3190 const extensions::ExtensionSet& enabled_extensions =
3191 registry()->enabled_extensions();
3192 const extensions::ExtensionSet& blacklisted_extensions =
3193 registry()->blacklisted_extensions();
3195 EXPECT_TRUE(enabled_extensions.Contains(good0) &&
3196 !blacklisted_extensions.Contains(good0));
3197 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3198 !blacklisted_extensions.Contains(good1));
3199 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3200 !blacklisted_extensions.Contains(good2));
3202 EXPECT_FALSE(IsPrefExist(good0, "blacklist"));
3203 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3204 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3205 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3207 // Blacklist good0 and good1 (and an invalid extension ID).
3208 test_blacklist.SetBlacklistState(
3209 good0, extensions::BLACKLISTED_MALWARE, true);
3210 test_blacklist.SetBlacklistState(
3211 good1, extensions::BLACKLISTED_MALWARE, true);
3212 test_blacklist.SetBlacklistState(
3213 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3214 base::RunLoop().RunUntilIdle();
3216 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3217 blacklisted_extensions.Contains(good0));
3218 EXPECT_TRUE(!enabled_extensions.Contains(good1) &&
3219 blacklisted_extensions.Contains(good1));
3220 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3221 !blacklisted_extensions.Contains(good2));
3223 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3224 EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true));
3225 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3226 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3228 // Un-blacklist good1 and blacklist good2.
3229 test_blacklist.Clear(false);
3230 test_blacklist.SetBlacklistState(
3231 good0, extensions::BLACKLISTED_MALWARE, true);
3232 test_blacklist.SetBlacklistState(
3233 good2, extensions::BLACKLISTED_MALWARE, true);
3234 test_blacklist.SetBlacklistState(
3235 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3236 base::RunLoop().RunUntilIdle();
3238 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3239 blacklisted_extensions.Contains(good0));
3240 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3241 !blacklisted_extensions.Contains(good1));
3242 EXPECT_TRUE(!enabled_extensions.Contains(good2) &&
3243 blacklisted_extensions.Contains(good2));
3245 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3246 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3247 EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true));
3248 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3250 #endif // defined(ENABLE_BLACKLIST_TESTS)
3252 #if defined(ENABLE_BLACKLIST_TESTS)
3253 // Tests trying to install a blacklisted extension.
3254 TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
3255 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3256 new FakeSafeBrowsingDatabaseManager(true));
3257 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3259 InitializeEmptyExtensionService();
3260 service()->Init();
3262 // After blacklisting good_crx, we cannot install it.
3263 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
3264 base::RunLoop().RunUntilIdle();
3266 base::FilePath path = data_dir().AppendASCII("good.crx");
3267 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3268 // decide to install this silently. Somebody should fix these tests, all
3269 // 6,000 lines of them. Hah!
3270 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
3271 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3273 #endif // defined(ENABLE_BLACKLIST_TESTS)
3275 #if defined(ENABLE_BLACKLIST_TESTS)
3276 // Unload blacklisted extension on policy change.
3277 TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
3278 extensions::TestBlacklist test_blacklist;
3280 // A profile with no extensions installed.
3281 InitializeEmptyExtensionServiceWithTestingPrefs();
3282 test_blacklist.Attach(service()->blacklist_);
3284 base::FilePath path = data_dir().AppendASCII("good.crx");
3286 const Extension* good = InstallCRX(path, INSTALL_NEW);
3287 EXPECT_EQ(good_crx, good->id());
3288 UpdateExtension(good_crx, path, FAILED_SILENTLY);
3289 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3292 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3293 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3296 test_blacklist.SetBlacklistState(
3297 good_crx, extensions::BLACKLISTED_MALWARE, true);
3298 base::RunLoop().RunUntilIdle();
3300 // The good_crx is blacklisted and the whitelist doesn't negate it.
3301 ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true));
3302 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3304 #endif // defined(ENABLE_BLACKLIST_TESTS)
3306 #if defined(ENABLE_BLACKLIST_TESTS)
3307 // Tests that a blacklisted extension is eventually unloaded on startup, if it
3308 // wasn't already.
3309 TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
3310 extensions::TestBlacklist test_blacklist;
3312 // A profile with 3 extensions installed: good0, good1, and good2.
3313 InitializeGoodInstalledExtensionService();
3314 test_blacklist.Attach(service()->blacklist_);
3316 // Blacklist good1 before the service initializes.
3317 test_blacklist.SetBlacklistState(
3318 good1, extensions::BLACKLISTED_MALWARE, false);
3320 // Load extensions.
3321 service()->Init();
3322 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet
3324 base::RunLoop().RunUntilIdle();
3326 ASSERT_EQ(1u, registry()->blacklisted_extensions().size());
3327 ASSERT_EQ(2u, registry()->enabled_extensions().size());
3329 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
3330 ASSERT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3331 ASSERT_TRUE(registry()->enabled_extensions().Contains(good2));
3333 #endif // defined(ENABLE_BLACKLIST_TESTS)
3335 #if defined(ENABLE_BLACKLIST_TESTS)
3336 // Tests extensions blacklisted in prefs on startup; one still blacklisted by
3337 // safe browsing, the other not. The not-blacklisted one should recover.
3338 TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) {
3339 extensions::TestBlacklist test_blacklist;
3341 InitializeGoodInstalledExtensionService();
3342 test_blacklist.Attach(service()->blacklist_);
3343 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good0, true);
3344 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good1, true);
3346 test_blacklist.SetBlacklistState(
3347 good1, extensions::BLACKLISTED_MALWARE, false);
3349 // Extension service hasn't loaded yet, but IsExtensionEnabled reads out of
3350 // prefs. Ensure it takes into account the blacklist state (crbug.com/373842).
3351 EXPECT_FALSE(service()->IsExtensionEnabled(good0));
3352 EXPECT_FALSE(service()->IsExtensionEnabled(good1));
3353 EXPECT_TRUE(service()->IsExtensionEnabled(good2));
3355 service()->Init();
3357 EXPECT_EQ(2u, registry()->blacklisted_extensions().size());
3358 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3360 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good0));
3361 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3362 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3364 // Give time for the blacklist to update.
3365 base::RunLoop().RunUntilIdle();
3367 EXPECT_EQ(1u, registry()->blacklisted_extensions().size());
3368 EXPECT_EQ(2u, registry()->enabled_extensions().size());
3370 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3371 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3372 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3374 #endif // defined(ENABLE_BLACKLIST_TESTS)
3376 #if defined(ENABLE_BLACKLIST_TESTS)
3377 // Extension is added to blacklist with BLACKLISTED_POTENTIALLY_UNWANTED state
3378 // after it is installed. It is then successfully re-enabled by the user.
3379 TEST_F(ExtensionServiceTest, GreylistedExtensionDisabled) {
3380 extensions::TestBlacklist test_blacklist;
3381 // A profile with 3 extensions installed: good0, good1, and good2.
3382 InitializeGoodInstalledExtensionService();
3383 test_blacklist.Attach(service()->blacklist_);
3384 service()->Init();
3386 const extensions::ExtensionSet& enabled_extensions =
3387 registry()->enabled_extensions();
3388 const extensions::ExtensionSet& disabled_extensions =
3389 registry()->disabled_extensions();
3391 EXPECT_TRUE(enabled_extensions.Contains(good0));
3392 EXPECT_TRUE(enabled_extensions.Contains(good1));
3393 EXPECT_TRUE(enabled_extensions.Contains(good2));
3395 // Blacklist good0 and good1 (and an invalid extension ID).
3396 test_blacklist.SetBlacklistState(
3397 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3398 test_blacklist.SetBlacklistState(
3399 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3400 test_blacklist.SetBlacklistState(
3401 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3402 base::RunLoop().RunUntilIdle();
3404 EXPECT_FALSE(enabled_extensions.Contains(good0));
3405 EXPECT_TRUE(disabled_extensions.Contains(good0));
3406 EXPECT_FALSE(enabled_extensions.Contains(good1));
3407 EXPECT_TRUE(disabled_extensions.Contains(good1));
3408 EXPECT_TRUE(enabled_extensions.Contains(good2));
3409 EXPECT_FALSE(disabled_extensions.Contains(good2));
3411 ValidateIntegerPref(
3412 good0, "blacklist_state", extensions::BLACKLISTED_CWS_POLICY_VIOLATION);
3413 ValidateIntegerPref(
3414 good1, "blacklist_state", extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
3416 // Now user enables good0.
3417 service()->EnableExtension(good0);
3419 EXPECT_TRUE(enabled_extensions.Contains(good0));
3420 EXPECT_FALSE(disabled_extensions.Contains(good0));
3421 EXPECT_FALSE(enabled_extensions.Contains(good1));
3422 EXPECT_TRUE(disabled_extensions.Contains(good1));
3424 // Remove extensions from blacklist.
3425 test_blacklist.SetBlacklistState(
3426 good0, extensions::NOT_BLACKLISTED, true);
3427 test_blacklist.SetBlacklistState(
3428 good1, extensions::NOT_BLACKLISTED, true);
3429 base::RunLoop().RunUntilIdle();
3431 // All extensions are enabled.
3432 EXPECT_TRUE(enabled_extensions.Contains(good0));
3433 EXPECT_FALSE(disabled_extensions.Contains(good0));
3434 EXPECT_TRUE(enabled_extensions.Contains(good1));
3435 EXPECT_FALSE(disabled_extensions.Contains(good1));
3436 EXPECT_TRUE(enabled_extensions.Contains(good2));
3437 EXPECT_FALSE(disabled_extensions.Contains(good2));
3439 #endif // defined(ENABLE_BLACKLIST_TESTS)
3441 #if defined(ENABLE_BLACKLIST_TESTS)
3442 // When extension is removed from greylist, do not re-enable it if it is
3443 // disabled by user.
3444 TEST_F(ExtensionServiceTest, GreylistDontEnableManuallyDisabled) {
3445 extensions::TestBlacklist test_blacklist;
3446 // A profile with 3 extensions installed: good0, good1, and good2.
3447 InitializeGoodInstalledExtensionService();
3448 test_blacklist.Attach(service()->blacklist_);
3449 service()->Init();
3451 const extensions::ExtensionSet& enabled_extensions =
3452 registry()->enabled_extensions();
3453 const extensions::ExtensionSet& disabled_extensions =
3454 registry()->disabled_extensions();
3456 // Manually disable.
3457 service()->DisableExtension(good0,
3458 extensions::Extension::DISABLE_USER_ACTION);
3460 test_blacklist.SetBlacklistState(
3461 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3462 test_blacklist.SetBlacklistState(
3463 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3464 test_blacklist.SetBlacklistState(
3465 good2, extensions::BLACKLISTED_SECURITY_VULNERABILITY, true);
3466 base::RunLoop().RunUntilIdle();
3468 // All extensions disabled.
3469 EXPECT_FALSE(enabled_extensions.Contains(good0));
3470 EXPECT_TRUE(disabled_extensions.Contains(good0));
3471 EXPECT_FALSE(enabled_extensions.Contains(good1));
3472 EXPECT_TRUE(disabled_extensions.Contains(good1));
3473 EXPECT_FALSE(enabled_extensions.Contains(good2));
3474 EXPECT_TRUE(disabled_extensions.Contains(good2));
3476 // Greylisted extension can be enabled.
3477 service()->EnableExtension(good1);
3478 EXPECT_TRUE(enabled_extensions.Contains(good1));
3479 EXPECT_FALSE(disabled_extensions.Contains(good1));
3481 // good1 is now manually disabled.
3482 service()->DisableExtension(good1,
3483 extensions::Extension::DISABLE_USER_ACTION);
3484 EXPECT_FALSE(enabled_extensions.Contains(good1));
3485 EXPECT_TRUE(disabled_extensions.Contains(good1));
3487 // Remove extensions from blacklist.
3488 test_blacklist.SetBlacklistState(
3489 good0, extensions::NOT_BLACKLISTED, true);
3490 test_blacklist.SetBlacklistState(
3491 good1, extensions::NOT_BLACKLISTED, true);
3492 test_blacklist.SetBlacklistState(
3493 good2, extensions::NOT_BLACKLISTED, true);
3494 base::RunLoop().RunUntilIdle();
3496 // good0 and good1 remain disabled.
3497 EXPECT_FALSE(enabled_extensions.Contains(good0));
3498 EXPECT_TRUE(disabled_extensions.Contains(good0));
3499 EXPECT_FALSE(enabled_extensions.Contains(good1));
3500 EXPECT_TRUE(disabled_extensions.Contains(good1));
3501 EXPECT_TRUE(enabled_extensions.Contains(good2));
3502 EXPECT_FALSE(disabled_extensions.Contains(good2));
3504 #endif // defined(ENABLE_BLACKLIST_TESTS)
3506 #if defined(ENABLE_BLACKLIST_TESTS)
3507 // Blacklisted extension with unknown state are not enabled/disabled.
3508 TEST_F(ExtensionServiceTest, GreylistUnknownDontChange) {
3509 extensions::TestBlacklist test_blacklist;
3510 // A profile with 3 extensions installed: good0, good1, and good2.
3511 InitializeGoodInstalledExtensionService();
3512 test_blacklist.Attach(service()->blacklist_);
3513 service()->Init();
3515 const extensions::ExtensionSet& enabled_extensions =
3516 registry()->enabled_extensions();
3517 const extensions::ExtensionSet& disabled_extensions =
3518 registry()->disabled_extensions();
3520 test_blacklist.SetBlacklistState(
3521 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3522 test_blacklist.SetBlacklistState(
3523 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3524 base::RunLoop().RunUntilIdle();
3526 EXPECT_FALSE(enabled_extensions.Contains(good0));
3527 EXPECT_TRUE(disabled_extensions.Contains(good0));
3528 EXPECT_FALSE(enabled_extensions.Contains(good1));
3529 EXPECT_TRUE(disabled_extensions.Contains(good1));
3530 EXPECT_TRUE(enabled_extensions.Contains(good2));
3531 EXPECT_FALSE(disabled_extensions.Contains(good2));
3533 test_blacklist.SetBlacklistState(
3534 good0, extensions::NOT_BLACKLISTED, true);
3535 test_blacklist.SetBlacklistState(
3536 good1, extensions::BLACKLISTED_UNKNOWN, true);
3537 test_blacklist.SetBlacklistState(
3538 good2, extensions::BLACKLISTED_UNKNOWN, true);
3539 base::RunLoop().RunUntilIdle();
3541 // good0 re-enabled, other remain as they were.
3542 EXPECT_TRUE(enabled_extensions.Contains(good0));
3543 EXPECT_FALSE(disabled_extensions.Contains(good0));
3544 EXPECT_FALSE(enabled_extensions.Contains(good1));
3545 EXPECT_TRUE(disabled_extensions.Contains(good1));
3546 EXPECT_TRUE(enabled_extensions.Contains(good2));
3547 EXPECT_FALSE(disabled_extensions.Contains(good2));
3550 // Tests that blacklisted extensions cannot be reloaded, both those loaded
3551 // before and after extension service startup.
3552 TEST_F(ExtensionServiceTest, ReloadBlacklistedExtension) {
3553 extensions::TestBlacklist test_blacklist;
3555 InitializeGoodInstalledExtensionService();
3556 test_blacklist.Attach(service()->blacklist_);
3558 test_blacklist.SetBlacklistState(
3559 good1, extensions::BLACKLISTED_MALWARE, false);
3560 service()->Init();
3561 test_blacklist.SetBlacklistState(
3562 good2, extensions::BLACKLISTED_MALWARE, false);
3563 base::RunLoop().RunUntilIdle();
3565 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3566 EXPECT_EQ(StringSet(good1, good2),
3567 registry()->blacklisted_extensions().GetIDs());
3569 service()->ReloadExtension(good1);
3570 service()->ReloadExtension(good2);
3571 base::RunLoop().RunUntilIdle();
3573 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3574 EXPECT_EQ(StringSet(good1, good2),
3575 registry()->blacklisted_extensions().GetIDs());
3578 #endif // defined(ENABLE_BLACKLIST_TESTS)
3580 // Will not install extension blacklisted by policy.
3581 TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
3582 InitializeEmptyExtensionServiceWithTestingPrefs();
3584 // Blacklist everything.
3586 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3587 pref.SetBlacklistedByDefault(true);
3590 // Blacklist prevents us from installing good_crx.
3591 base::FilePath path = data_dir().AppendASCII("good.crx");
3592 InstallCRX(path, INSTALL_FAILED);
3593 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3595 // Now whitelist this particular extension.
3597 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3598 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3601 // Ensure we can now install good_crx.
3602 InstallCRX(path, INSTALL_NEW);
3603 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3606 // Extension blacklisted by policy get unloaded after installing.
3607 TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
3608 InitializeEmptyExtensionServiceWithTestingPrefs();
3610 // Install good_crx.
3611 base::FilePath path = data_dir().AppendASCII("good.crx");
3612 InstallCRX(path, INSTALL_NEW);
3613 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3616 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3617 // Blacklist this extension.
3618 pref.SetIndividualExtensionInstallationAllowed(good_crx, false);
3621 // Extension should not be running now.
3622 base::RunLoop().RunUntilIdle();
3623 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3626 // Tests that component extensions are not blacklisted by policy.
3627 TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
3628 InitializeEmptyExtensionServiceWithTestingPrefs();
3630 // Blacklist everything.
3632 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3633 pref.SetBlacklistedByDefault(true);
3636 // Install a component extension.
3637 base::FilePath path = data_dir()
3638 .AppendASCII("good")
3639 .AppendASCII("Extensions")
3640 .AppendASCII(good0)
3641 .AppendASCII("1.0.0.0");
3642 std::string manifest;
3643 ASSERT_TRUE(base::ReadFileToString(
3644 path.Append(extensions::kManifestFilename), &manifest));
3645 service()->component_loader()->Add(manifest, path);
3646 service()->Init();
3648 // Extension should be installed despite blacklist.
3649 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3650 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3652 // Poke external providers and make sure the extension is still present.
3653 service()->CheckForExternalUpdates();
3654 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3655 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3657 // Extension should not be uninstalled on blacklist changes.
3659 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3660 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3662 base::RunLoop().RunUntilIdle();
3663 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3664 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3667 // Tests that policy-installed extensions are not blacklisted by policy.
3668 TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
3669 InitializeEmptyExtensionServiceWithTestingPrefs();
3672 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3673 // Blacklist everything.
3674 pref.SetBlacklistedByDefault(true);
3675 // Mark good.crx for force-installation.
3676 pref.SetIndividualExtensionAutoInstalled(
3677 good_crx, "http://example.com/update_url", true);
3680 // Have policy force-install an extension.
3681 MockExtensionProvider* provider =
3682 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3683 AddMockExternalProvider(provider);
3684 provider->UpdateOrAddExtension(
3685 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
3687 // Reloading extensions should find our externally registered extension
3688 // and install it.
3689 content::WindowedNotificationObserver observer(
3690 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3691 content::NotificationService::AllSources());
3692 service()->CheckForExternalUpdates();
3693 observer.Wait();
3695 // Extension should be installed despite blacklist.
3696 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3697 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3699 // Blacklist update should not uninstall the extension.
3701 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3702 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3704 base::RunLoop().RunUntilIdle();
3705 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3706 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3709 // Tests that extensions cannot be installed if the policy provider prohibits
3710 // it. This functionality is implemented in CrxInstaller::ConfirmInstall().
3711 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
3712 InitializeEmptyExtensionService();
3714 GetManagementPolicy()->UnregisterAllProviders();
3715 extensions::TestManagementPolicyProvider provider_(
3716 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3717 GetManagementPolicy()->RegisterProvider(&provider_);
3719 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_FAILED);
3720 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3723 // Tests that extensions cannot be loaded from prefs if the policy provider
3724 // prohibits it. This functionality is implemented in InstalledLoader::Load().
3725 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
3726 InitializeEmptyExtensionService();
3728 // Create a fake extension to be loaded as though it were read from prefs.
3729 base::FilePath path =
3730 data_dir().AppendASCII("management").AppendASCII("simple_extension");
3731 base::DictionaryValue manifest;
3732 manifest.SetString(keys::kName, "simple_extension");
3733 manifest.SetString(keys::kVersion, "1");
3734 // UNPACKED is for extensions loaded from a directory. We use it here, even
3735 // though we're testing loading from prefs, so that we don't need to provide
3736 // an extension key.
3737 extensions::ExtensionInfo extension_info(
3738 &manifest, std::string(), path, Manifest::UNPACKED);
3740 // Ensure we can load it with no management policy in place.
3741 GetManagementPolicy()->UnregisterAllProviders();
3742 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3743 extensions::InstalledLoader(service()).Load(extension_info, false);
3744 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3746 const Extension* extension =
3747 (registry()->enabled_extensions().begin())->get();
3748 EXPECT_TRUE(
3749 service()->UninstallExtension(extension->id(),
3750 extensions::UNINSTALL_REASON_FOR_TESTING,
3751 base::Bind(&base::DoNothing),
3752 NULL));
3753 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3755 // Ensure we cannot load it if management policy prohibits installation.
3756 extensions::TestManagementPolicyProvider provider_(
3757 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3758 GetManagementPolicy()->RegisterProvider(&provider_);
3760 extensions::InstalledLoader(service()).Load(extension_info, false);
3761 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3764 // Tests disabling an extension when prohibited by the ManagementPolicy.
3765 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
3766 InitializeEmptyExtensionService();
3768 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3769 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3770 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3772 GetManagementPolicy()->UnregisterAllProviders();
3773 extensions::TestManagementPolicyProvider provider(
3774 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3775 GetManagementPolicy()->RegisterProvider(&provider);
3777 // Attempt to disable it.
3778 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3780 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3781 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3782 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3785 // Tests uninstalling an extension when prohibited by the ManagementPolicy.
3786 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
3787 InitializeEmptyExtensionService();
3789 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3790 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3791 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3793 GetManagementPolicy()->UnregisterAllProviders();
3794 extensions::TestManagementPolicyProvider provider(
3795 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3796 GetManagementPolicy()->RegisterProvider(&provider);
3798 // Attempt to uninstall it.
3799 EXPECT_FALSE(
3800 service()->UninstallExtension(good_crx,
3801 extensions::UNINSTALL_REASON_FOR_TESTING,
3802 base::Bind(&base::DoNothing),
3803 NULL));
3805 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3806 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3809 // Tests that previously installed extensions that are now prohibited from
3810 // being installed are removed.
3811 TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
3812 InitializeEmptyExtensionService();
3814 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3815 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
3816 EXPECT_EQ(2u, registry()->enabled_extensions().size());
3817 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3819 GetManagementPolicy()->UnregisterAllProviders();
3820 extensions::TestManagementPolicyProvider provider(
3821 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3822 GetManagementPolicy()->RegisterProvider(&provider);
3824 // Run the policy check.
3825 service()->CheckManagementPolicy();
3826 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3827 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3830 // Tests that previously disabled extensions that are now required to be
3831 // enabled are re-enabled on reinstall.
3832 TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
3833 InitializeEmptyExtensionService();
3835 // Install, then disable, an extension.
3836 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3837 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3838 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3839 EXPECT_EQ(1u, registry()->disabled_extensions().size());
3841 // Register an ExtensionMnagementPolicy that requires the extension to remain
3842 // enabled.
3843 GetManagementPolicy()->UnregisterAllProviders();
3844 extensions::TestManagementPolicyProvider provider(
3845 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
3846 GetManagementPolicy()->RegisterProvider(&provider);
3848 // Reinstall the extension.
3849 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_UPDATED);
3850 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3851 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3854 // Flaky on windows; http://crbug.com/309833
3855 #if defined(OS_WIN)
3856 #define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
3857 #else
3858 #define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
3859 #endif
3860 TEST_F(ExtensionServiceTest, MAYBE_ExternalExtensionAutoAcknowledgement) {
3861 InitializeEmptyExtensionService();
3862 service()->set_extensions_enabled(true);
3865 // Register and install an external extension.
3866 MockExtensionProvider* provider =
3867 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
3868 AddMockExternalProvider(provider);
3869 provider->UpdateOrAddExtension(
3870 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
3873 // Have policy force-install an extension.
3874 MockExtensionProvider* provider = new MockExtensionProvider(
3875 service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3876 AddMockExternalProvider(provider);
3877 provider->UpdateOrAddExtension(
3878 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
3881 // Providers are set up. Let them run.
3882 int count = 2;
3883 content::WindowedNotificationObserver observer(
3884 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3885 base::Bind(&WaitForCountNotificationsCallback, &count));
3886 service()->CheckForExternalUpdates();
3888 observer.Wait();
3890 ASSERT_EQ(2u, registry()->enabled_extensions().size());
3891 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3892 EXPECT_TRUE(service()->GetExtensionById(page_action, false));
3893 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
3894 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
3895 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
3898 #if !defined(OS_CHROMEOS)
3899 // This tests if default apps are installed correctly.
3900 TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
3901 InitializeEmptyExtensionService();
3902 service()->set_extensions_enabled(true);
3905 std::string json_data =
3907 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
3908 " \"external_crx\": \"good.crx\","
3909 " \"external_version\": \"1.0.0.0\","
3910 " \"is_bookmark_app\": false"
3911 " }"
3912 "}";
3913 default_apps::Provider* provider = new default_apps::Provider(
3914 profile(),
3915 service(),
3916 new extensions::ExternalTestingLoader(json_data, data_dir()),
3917 Manifest::INTERNAL,
3918 Manifest::INVALID_LOCATION,
3919 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
3921 AddMockExternalProvider(provider);
3924 ASSERT_EQ(0u, registry()->enabled_extensions().size());
3925 content::WindowedNotificationObserver observer(
3926 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3927 content::NotificationService::AllSources());
3928 service()->CheckForExternalUpdates();
3929 observer.Wait();
3931 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3932 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3933 const Extension* extension = service()->GetExtensionById(good_crx, false);
3934 EXPECT_TRUE(extension->from_webstore());
3935 EXPECT_TRUE(extension->was_installed_by_default());
3937 #endif
3939 // Tests disabling extensions
3940 TEST_F(ExtensionServiceTest, DisableExtension) {
3941 InitializeEmptyExtensionService();
3943 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3944 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
3945 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3947 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3948 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3949 EXPECT_EQ(0u, registry()->terminated_extensions().size());
3950 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
3952 // Disable it.
3953 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3955 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
3956 EXPECT_FALSE(service()->GetExtensionById(good_crx, false));
3957 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3958 EXPECT_EQ(1u, registry()->disabled_extensions().size());
3959 EXPECT_EQ(0u, registry()->terminated_extensions().size());
3960 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
3963 TEST_F(ExtensionServiceTest, TerminateExtension) {
3964 InitializeEmptyExtensionService();
3966 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3967 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3968 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3969 EXPECT_EQ(0u, registry()->terminated_extensions().size());
3970 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
3972 TerminateExtension(good_crx);
3974 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3975 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3976 EXPECT_EQ(1u, registry()->terminated_extensions().size());
3977 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
3980 TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
3981 InitializeEmptyExtensionService();
3983 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3984 TerminateExtension(good_crx);
3985 EXPECT_TRUE(registry()->GetExtensionById(
3986 good_crx, extensions::ExtensionRegistry::TERMINATED));
3988 // Disable it.
3989 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3991 EXPECT_FALSE(registry()->GetExtensionById(
3992 good_crx, extensions::ExtensionRegistry::TERMINATED));
3993 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
3995 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3996 EXPECT_EQ(1u, registry()->disabled_extensions().size());
3997 EXPECT_EQ(0u, registry()->terminated_extensions().size());
3998 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4001 // Tests disabling all extensions (simulating --disable-extensions flag).
4002 TEST_F(ExtensionServiceTest, DisableAllExtensions) {
4003 InitializeEmptyExtensionService();
4005 base::FilePath path = data_dir().AppendASCII("good.crx");
4006 InstallCRX(path, INSTALL_NEW);
4008 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4009 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4011 // Disable extensions.
4012 service()->set_extensions_enabled(false);
4013 service()->ReloadExtensionsForTest();
4015 // There shouldn't be extensions in either list.
4016 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4017 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4019 // This shouldn't do anything when all extensions are disabled.
4020 service()->EnableExtension(good_crx);
4021 service()->ReloadExtensionsForTest();
4023 // There still shouldn't be extensions in either list.
4024 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4025 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4027 // And then re-enable the extensions.
4028 service()->set_extensions_enabled(true);
4029 service()->ReloadExtensionsForTest();
4031 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4032 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4035 // Tests reloading extensions.
4036 TEST_F(ExtensionServiceTest, ReloadExtensions) {
4037 InitializeEmptyExtensionService();
4039 // Simple extension that should install without error.
4040 base::FilePath path = data_dir().AppendASCII("good.crx");
4041 InstallCRX(path, INSTALL_NEW,
4042 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4043 const char* extension_id = good_crx;
4044 service()->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
4046 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4047 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4049 service()->ReloadExtensionsForTest();
4051 // The creation flags should not change when reloading the extension.
4052 const Extension* extension = service()->GetExtensionById(good_crx, true);
4053 EXPECT_TRUE(extension->from_webstore());
4054 EXPECT_TRUE(extension->was_installed_by_default());
4055 EXPECT_FALSE(extension->from_bookmark());
4057 // Extension counts shouldn't change.
4058 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4059 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4061 service()->EnableExtension(extension_id);
4063 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4064 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4066 // Need to clear |loaded_| manually before reloading as the
4067 // EnableExtension() call above inserted into it and
4068 // UnloadAllExtensions() doesn't send out notifications.
4069 loaded_.clear();
4070 service()->ReloadExtensionsForTest();
4072 // Extension counts shouldn't change.
4073 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4074 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4077 // Tests reloading an extension.
4078 TEST_F(ExtensionServiceTest, ReloadExtension) {
4079 InitializeEmptyExtensionService();
4080 InitializeProcessManager();
4082 // Simple extension that should install without error.
4083 const char* extension_id = "behllobkkfkfnphdnhnkndlbkcpglgmj";
4084 base::FilePath ext = data_dir()
4085 .AppendASCII("good")
4086 .AppendASCII("Extensions")
4087 .AppendASCII(extension_id)
4088 .AppendASCII("1.0.0.0");
4089 extensions::UnpackedInstaller::Create(service())->Load(ext);
4090 base::RunLoop().RunUntilIdle();
4092 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4093 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4095 service()->ReloadExtension(extension_id);
4097 // Extension should be disabled now, waiting to be reloaded.
4098 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4099 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4100 EXPECT_EQ(Extension::DISABLE_RELOAD,
4101 ExtensionPrefs::Get(profile())->GetDisableReasons(extension_id));
4103 // Reloading again should not crash.
4104 service()->ReloadExtension(extension_id);
4106 // Finish reloading
4107 base::RunLoop().RunUntilIdle();
4109 // Extension should be enabled again.
4110 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4111 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4114 TEST_F(ExtensionServiceTest, UninstallExtension) {
4115 InitializeEmptyExtensionService();
4116 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4117 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4118 UninstallExtension(good_crx, false);
4119 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4120 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4123 TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
4124 InitializeEmptyExtensionService();
4125 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4126 TerminateExtension(good_crx);
4127 UninstallExtension(good_crx, false);
4128 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4131 // Tests the uninstaller helper.
4132 TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
4133 InitializeEmptyExtensionService();
4134 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4135 UninstallExtension(good_crx, true);
4136 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4139 TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
4140 InitializeEmptyExtensionService();
4141 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4142 TerminateExtension(good_crx);
4143 UninstallExtension(good_crx, true);
4144 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4147 // An extension disabled because of unsupported requirements should re-enabled
4148 // if updated to a version with supported requirements as long as there are no
4149 // other disable reasons.
4150 TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
4151 InitializeEmptyExtensionService();
4152 BlackListWebGL();
4154 base::FilePath path = data_dir().AppendASCII("requirements");
4155 base::FilePath pem_path =
4156 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4157 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4158 pem_path,
4159 INSTALL_NEW);
4160 std::string id = extension_v1->id();
4161 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4163 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4165 PackCRX(path.AppendASCII("v2_bad_requirements"),
4166 pem_path,
4167 v2_bad_requirements_crx);
4168 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4169 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4171 base::FilePath v3_good_crx = GetTemporaryFile();
4173 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4174 UpdateExtension(id, v3_good_crx, ENABLED);
4175 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4178 // Extensions disabled through user action should stay disabled.
4179 TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
4180 InitializeEmptyExtensionService();
4181 BlackListWebGL();
4183 base::FilePath path = data_dir().AppendASCII("requirements");
4184 base::FilePath pem_path =
4185 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4186 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4187 pem_path,
4188 INSTALL_NEW);
4189 std::string id = extension_v1->id();
4190 service()->DisableExtension(id, Extension::DISABLE_USER_ACTION);
4191 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4193 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4195 PackCRX(path.AppendASCII("v2_bad_requirements"),
4196 pem_path,
4197 v2_bad_requirements_crx);
4198 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4199 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4201 base::FilePath v3_good_crx = GetTemporaryFile();
4203 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4204 UpdateExtension(id, v3_good_crx, INSTALLED);
4205 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4208 // The extension should not re-enabled because it was disabled from a
4209 // permission increase.
4210 TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
4211 InitializeEmptyExtensionService();
4212 BlackListWebGL();
4214 base::FilePath path = data_dir().AppendASCII("requirements");
4215 base::FilePath pem_path =
4216 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4217 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4218 pem_path,
4219 INSTALL_NEW);
4220 std::string id = extension_v1->id();
4221 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4223 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
4225 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
4226 pem_path,
4227 v2_bad_requirements_and_permissions_crx);
4228 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
4229 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4231 base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
4233 PackCRX(path.AppendASCII("v3_bad_permissions"),
4234 pem_path,
4235 v3_bad_permissions_crx);
4236 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
4237 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4240 // Unpacked extensions are not allowed to be installed if they have unsupported
4241 // requirements.
4242 TEST_F(ExtensionServiceTest, UnpackedRequirements) {
4243 InitializeEmptyExtensionService();
4244 BlackListWebGL();
4246 base::FilePath path =
4247 data_dir().AppendASCII("requirements").AppendASCII("v2_bad_requirements");
4248 extensions::UnpackedInstaller::Create(service())->Load(path);
4249 base::RunLoop().RunUntilIdle();
4250 EXPECT_EQ(1u, GetErrors().size());
4251 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4254 class ExtensionCookieCallback {
4255 public:
4256 ExtensionCookieCallback()
4257 : result_(false),
4258 weak_factory_(base::MessageLoop::current()) {}
4260 void SetCookieCallback(bool result) {
4261 base::MessageLoop::current()->PostTask(FROM_HERE,
4262 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4263 result_ = result;
4266 void GetAllCookiesCallback(const net::CookieList& list) {
4267 base::MessageLoop::current()->PostTask(FROM_HERE,
4268 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4269 list_ = list;
4271 net::CookieList list_;
4272 bool result_;
4273 base::WeakPtrFactory<base::MessageLoop> weak_factory_;
4276 // Verifies extension state is removed upon uninstall.
4277 TEST_F(ExtensionServiceTest, ClearExtensionData) {
4278 InitializeEmptyExtensionService();
4279 ExtensionCookieCallback callback;
4281 // Load a test extension.
4282 base::FilePath path = data_dir();
4283 path = path.AppendASCII("good.crx");
4284 const Extension* extension = InstallCRX(path, INSTALL_NEW);
4285 ASSERT_TRUE(extension);
4286 GURL ext_url(extension->url());
4287 std::string origin_id = storage::GetIdentifierFromOrigin(ext_url);
4289 // Set a cookie for the extension.
4290 net::CookieMonster* cookie_monster = profile()
4291 ->GetRequestContextForExtensions()
4292 ->GetURLRequestContext()
4293 ->cookie_store()
4294 ->GetCookieMonster();
4295 ASSERT_TRUE(cookie_monster);
4296 net::CookieOptions options;
4297 cookie_monster->SetCookieWithOptionsAsync(
4298 ext_url, "dummy=value", options,
4299 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4300 base::Unretained(&callback)));
4301 base::RunLoop().RunUntilIdle();
4302 EXPECT_TRUE(callback.result_);
4304 cookie_monster->GetAllCookiesForURLAsync(
4305 ext_url,
4306 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4307 base::Unretained(&callback)));
4308 base::RunLoop().RunUntilIdle();
4309 EXPECT_EQ(1U, callback.list_.size());
4311 // Open a database.
4312 storage::DatabaseTracker* db_tracker =
4313 BrowserContext::GetDefaultStoragePartition(profile())
4314 ->GetDatabaseTracker();
4315 base::string16 db_name = base::UTF8ToUTF16("db");
4316 base::string16 description = base::UTF8ToUTF16("db_description");
4317 int64 size;
4318 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4319 db_tracker->DatabaseClosed(origin_id, db_name);
4320 std::vector<storage::OriginInfo> origins;
4321 db_tracker->GetAllOriginsInfo(&origins);
4322 EXPECT_EQ(1U, origins.size());
4323 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4325 // Create local storage. We only simulate this by creating the backing files.
4326 // Note: This test depends on details of how the dom_storage library
4327 // stores data in the host file system.
4328 base::FilePath lso_dir_path =
4329 profile()->GetPath().AppendASCII("Local Storage");
4330 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4331 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4332 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4333 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4334 EXPECT_TRUE(base::PathExists(lso_file_path));
4336 // Create indexed db. Similarly, it is enough to only simulate this by
4337 // creating the directory on the disk.
4338 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4339 profile())->GetIndexedDBContext();
4340 idb_context->SetTaskRunnerForTesting(
4341 base::MessageLoop::current()->message_loop_proxy().get());
4342 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4343 EXPECT_TRUE(base::CreateDirectory(idb_path));
4344 EXPECT_TRUE(base::DirectoryExists(idb_path));
4346 // Uninstall the extension.
4347 base::RunLoop run_loop;
4348 ASSERT_TRUE(
4349 service()->UninstallExtension(good_crx,
4350 extensions::UNINSTALL_REASON_FOR_TESTING,
4351 run_loop.QuitClosure(),
4352 NULL));
4353 // The data deletion happens on the IO thread.
4354 run_loop.Run();
4356 // Check that the cookie is gone.
4357 cookie_monster->GetAllCookiesForURLAsync(
4358 ext_url,
4359 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4360 base::Unretained(&callback)));
4361 base::RunLoop().RunUntilIdle();
4362 EXPECT_EQ(0U, callback.list_.size());
4364 // The database should have vanished as well.
4365 origins.clear();
4366 db_tracker->GetAllOriginsInfo(&origins);
4367 EXPECT_EQ(0U, origins.size());
4369 // Check that the LSO file has been removed.
4370 EXPECT_FALSE(base::PathExists(lso_file_path));
4372 // Check if the indexed db has disappeared too.
4373 EXPECT_FALSE(base::DirectoryExists(idb_path));
4376 // Verifies app state is removed upon uninstall.
4377 TEST_F(ExtensionServiceTest, ClearAppData) {
4378 InitializeEmptyExtensionService();
4379 ExtensionCookieCallback callback;
4381 int pref_count = 0;
4383 // Install app1 with unlimited storage.
4384 const Extension* extension =
4385 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
4386 ValidatePrefKeyCount(++pref_count);
4387 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4388 const std::string id1 = extension->id();
4389 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4390 APIPermission::kUnlimitedStorage));
4391 const GURL origin1(
4392 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4393 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4394 origin1));
4395 std::string origin_id = storage::GetIdentifierFromOrigin(origin1);
4397 // Install app2 from the same origin with unlimited storage.
4398 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
4399 ValidatePrefKeyCount(++pref_count);
4400 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4401 const std::string id2 = extension->id();
4402 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4403 APIPermission::kUnlimitedStorage));
4404 EXPECT_TRUE(extension->web_extent().MatchesURL(
4405 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
4406 const GURL origin2(
4407 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4408 EXPECT_EQ(origin1, origin2);
4409 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4410 origin2));
4412 // Set a cookie for the extension.
4413 net::CookieMonster* cookie_monster = profile()
4414 ->GetRequestContext()
4415 ->GetURLRequestContext()
4416 ->cookie_store()
4417 ->GetCookieMonster();
4418 ASSERT_TRUE(cookie_monster);
4419 net::CookieOptions options;
4420 cookie_monster->SetCookieWithOptionsAsync(
4421 origin1, "dummy=value", options,
4422 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4423 base::Unretained(&callback)));
4424 base::RunLoop().RunUntilIdle();
4425 EXPECT_TRUE(callback.result_);
4427 cookie_monster->GetAllCookiesForURLAsync(
4428 origin1,
4429 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4430 base::Unretained(&callback)));
4431 base::RunLoop().RunUntilIdle();
4432 EXPECT_EQ(1U, callback.list_.size());
4434 // Open a database.
4435 storage::DatabaseTracker* db_tracker =
4436 BrowserContext::GetDefaultStoragePartition(profile())
4437 ->GetDatabaseTracker();
4438 base::string16 db_name = base::UTF8ToUTF16("db");
4439 base::string16 description = base::UTF8ToUTF16("db_description");
4440 int64 size;
4441 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4442 db_tracker->DatabaseClosed(origin_id, db_name);
4443 std::vector<storage::OriginInfo> origins;
4444 db_tracker->GetAllOriginsInfo(&origins);
4445 EXPECT_EQ(1U, origins.size());
4446 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4448 // Create local storage. We only simulate this by creating the backing files.
4449 // Note: This test depends on details of how the dom_storage library
4450 // stores data in the host file system.
4451 base::FilePath lso_dir_path =
4452 profile()->GetPath().AppendASCII("Local Storage");
4453 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4454 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4455 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4456 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4457 EXPECT_TRUE(base::PathExists(lso_file_path));
4459 // Create indexed db. Similarly, it is enough to only simulate this by
4460 // creating the directory on the disk.
4461 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4462 profile())->GetIndexedDBContext();
4463 idb_context->SetTaskRunnerForTesting(
4464 base::MessageLoop::current()->message_loop_proxy().get());
4465 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4466 EXPECT_TRUE(base::CreateDirectory(idb_path));
4467 EXPECT_TRUE(base::DirectoryExists(idb_path));
4469 // Uninstall one of them, unlimited storage should still be granted
4470 // to the origin.
4471 UninstallExtension(id1, false);
4472 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4473 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4474 origin1));
4476 // Check that the cookie is still there.
4477 cookie_monster->GetAllCookiesForURLAsync(
4478 origin1,
4479 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4480 base::Unretained(&callback)));
4481 base::RunLoop().RunUntilIdle();
4482 EXPECT_EQ(1U, callback.list_.size());
4484 // Now uninstall the other. Storage should be cleared for the apps.
4485 UninstallExtension(id2, false);
4486 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4487 EXPECT_FALSE(
4488 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4489 origin1));
4491 // Check that the cookie is gone.
4492 cookie_monster->GetAllCookiesForURLAsync(
4493 origin1,
4494 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4495 base::Unretained(&callback)));
4496 base::RunLoop().RunUntilIdle();
4497 EXPECT_EQ(0U, callback.list_.size());
4499 // The database should have vanished as well.
4500 origins.clear();
4501 db_tracker->GetAllOriginsInfo(&origins);
4502 EXPECT_EQ(0U, origins.size());
4504 // Check that the LSO file has been removed.
4505 EXPECT_FALSE(base::PathExists(lso_file_path));
4507 // Check if the indexed db has disappeared too.
4508 EXPECT_FALSE(base::DirectoryExists(idb_path));
4511 // Tests loading single extensions (like --load-extension)
4512 // Flaky crashes. http://crbug.com/231806
4513 TEST_F(ExtensionServiceTest, DISABLED_LoadExtension) {
4514 InitializeEmptyExtensionService();
4516 base::FilePath ext1 = data_dir()
4517 .AppendASCII("good")
4518 .AppendASCII("Extensions")
4519 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4520 .AppendASCII("1.0.0.0");
4521 extensions::UnpackedInstaller::Create(service())->Load(ext1);
4522 base::RunLoop().RunUntilIdle();
4523 EXPECT_EQ(0u, GetErrors().size());
4524 ASSERT_EQ(1u, loaded_.size());
4525 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
4526 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4528 ValidatePrefKeyCount(1);
4530 base::FilePath no_manifest =
4531 data_dir()
4532 .AppendASCII("bad")
4533 // .AppendASCII("Extensions")
4534 .AppendASCII("cccccccccccccccccccccccccccccccc")
4535 .AppendASCII("1");
4536 extensions::UnpackedInstaller::Create(service())->Load(no_manifest);
4537 base::RunLoop().RunUntilIdle();
4538 EXPECT_EQ(1u, GetErrors().size());
4539 ASSERT_EQ(1u, loaded_.size());
4540 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4542 // Test uninstall.
4543 std::string id = loaded_[0]->id();
4544 EXPECT_FALSE(unloaded_id_.length());
4545 service()->UninstallExtension(id,
4546 extensions::UNINSTALL_REASON_FOR_TESTING,
4547 base::Bind(&base::DoNothing),
4548 NULL);
4549 base::RunLoop().RunUntilIdle();
4550 EXPECT_EQ(id, unloaded_id_);
4551 ASSERT_EQ(0u, loaded_.size());
4552 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4555 // Tests that we generate IDs when they are not specified in the manifest for
4556 // --load-extension.
4557 TEST_F(ExtensionServiceTest, GenerateID) {
4558 InitializeEmptyExtensionService();
4560 base::FilePath no_id_ext = data_dir().AppendASCII("no_id");
4561 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
4562 base::RunLoop().RunUntilIdle();
4563 EXPECT_EQ(0u, GetErrors().size());
4564 ASSERT_EQ(1u, loaded_.size());
4565 ASSERT_TRUE(crx_file::id_util::IdIsValid(loaded_[0]->id()));
4566 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
4568 ValidatePrefKeyCount(1);
4570 std::string previous_id = loaded_[0]->id();
4572 // If we reload the same path, we should get the same extension ID.
4573 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
4574 base::RunLoop().RunUntilIdle();
4575 ASSERT_EQ(1u, loaded_.size());
4576 ASSERT_EQ(previous_id, loaded_[0]->id());
4579 TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
4580 InitializeEmptyExtensionService();
4582 base::FilePath bad_locale =
4583 data_dir().AppendASCII("unpacked").AppendASCII("bad_messages_file");
4584 extensions::UnpackedInstaller::Create(service())->Load(bad_locale);
4585 base::RunLoop().RunUntilIdle();
4586 EXPECT_EQ(1u, GetErrors().size());
4587 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
4588 .AppendASCII("ms")
4589 .AppendASCII("messages.json");
4590 EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
4591 testing::HasSubstr(
4592 base::UTF16ToUTF8(ms_messages_file.LossyDisplayName())),
4593 testing::HasSubstr("Dictionary keys must be quoted.")));
4594 ASSERT_EQ(0u, loaded_.size());
4597 void ExtensionServiceTest::TestExternalProvider(
4598 MockExtensionProvider* provider, Manifest::Location location) {
4599 // Verify that starting with no providers loads no extensions.
4600 service()->Init();
4601 ASSERT_EQ(0u, loaded_.size());
4603 provider->set_visit_count(0);
4605 // Register a test extension externally using the mock registry provider.
4606 base::FilePath source_path = data_dir().AppendASCII("good.crx");
4608 // Add the extension.
4609 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
4611 // Reloading extensions should find our externally registered extension
4612 // and install it.
4613 content::WindowedNotificationObserver observer(
4614 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4615 content::NotificationService::AllSources());
4616 service()->CheckForExternalUpdates();
4617 observer.Wait();
4619 ASSERT_EQ(0u, GetErrors().size());
4620 ASSERT_EQ(1u, loaded_.size());
4621 ASSERT_EQ(location, loaded_[0]->location());
4622 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
4623 ValidatePrefKeyCount(1);
4624 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4625 ValidateIntegerPref(good_crx, "location", location);
4627 // Reload extensions without changing anything. The extension should be
4628 // loaded again.
4629 loaded_.clear();
4630 service()->ReloadExtensionsForTest();
4631 base::RunLoop().RunUntilIdle();
4632 ASSERT_EQ(0u, GetErrors().size());
4633 ASSERT_EQ(1u, loaded_.size());
4634 ValidatePrefKeyCount(1);
4635 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4636 ValidateIntegerPref(good_crx, "location", location);
4638 // Now update the extension with a new version. We should get upgraded.
4639 source_path = source_path.DirName().AppendASCII("good2.crx");
4640 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
4642 loaded_.clear();
4643 content::WindowedNotificationObserver observer_2(
4644 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4645 content::NotificationService::AllSources());
4646 service()->CheckForExternalUpdates();
4647 observer_2.Wait();
4648 ASSERT_EQ(0u, GetErrors().size());
4649 ASSERT_EQ(1u, loaded_.size());
4650 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
4651 ValidatePrefKeyCount(1);
4652 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4653 ValidateIntegerPref(good_crx, "location", location);
4655 // Uninstall the extension and reload. Nothing should happen because the
4656 // preference should prevent us from reinstalling.
4657 std::string id = loaded_[0]->id();
4658 bool no_uninstall =
4659 GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL);
4660 service()->UninstallExtension(id,
4661 extensions::UNINSTALL_REASON_FOR_TESTING,
4662 base::Bind(&base::DoNothing),
4663 NULL);
4664 base::RunLoop().RunUntilIdle();
4666 base::FilePath install_path = extensions_install_dir().AppendASCII(id);
4667 if (no_uninstall) {
4668 // Policy controlled extensions should not have been touched by uninstall.
4669 ASSERT_TRUE(base::PathExists(install_path));
4670 } else {
4671 // The extension should also be gone from the install directory.
4672 ASSERT_FALSE(base::PathExists(install_path));
4673 loaded_.clear();
4674 service()->CheckForExternalUpdates();
4675 base::RunLoop().RunUntilIdle();
4676 ASSERT_EQ(0u, loaded_.size());
4677 ValidatePrefKeyCount(1);
4678 ValidateIntegerPref(good_crx, "state",
4679 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
4680 ValidateIntegerPref(good_crx, "location", location);
4682 // Now clear the preference and reinstall.
4683 SetPrefInteg(good_crx, "state", Extension::ENABLED);
4685 loaded_.clear();
4686 content::WindowedNotificationObserver observer(
4687 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4688 content::NotificationService::AllSources());
4689 service()->CheckForExternalUpdates();
4690 observer.Wait();
4691 ASSERT_EQ(1u, loaded_.size());
4693 ValidatePrefKeyCount(1);
4694 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4695 ValidateIntegerPref(good_crx, "location", location);
4697 if (GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL)) {
4698 EXPECT_EQ(2, provider->visit_count());
4699 } else {
4700 // Now test an externally triggered uninstall (deleting the registry key or
4701 // the pref entry).
4702 provider->RemoveExtension(good_crx);
4704 loaded_.clear();
4705 service()->OnExternalProviderReady(provider);
4706 base::RunLoop().RunUntilIdle();
4707 ASSERT_EQ(0u, loaded_.size());
4708 ValidatePrefKeyCount(0);
4710 // The extension should also be gone from the install directory.
4711 ASSERT_FALSE(base::PathExists(install_path));
4713 // Now test the case where user uninstalls and then the extension is removed
4714 // from the external provider.
4715 content::WindowedNotificationObserver observer(
4716 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4717 content::NotificationService::AllSources());
4718 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
4719 service()->CheckForExternalUpdates();
4720 observer.Wait();
4722 ASSERT_EQ(1u, loaded_.size());
4723 ASSERT_EQ(0u, GetErrors().size());
4725 // User uninstalls.
4726 loaded_.clear();
4727 service()->UninstallExtension(id,
4728 extensions::UNINSTALL_REASON_FOR_TESTING,
4729 base::Bind(&base::DoNothing),
4730 NULL);
4731 base::RunLoop().RunUntilIdle();
4732 ASSERT_EQ(0u, loaded_.size());
4734 // Then remove the extension from the extension provider.
4735 provider->RemoveExtension(good_crx);
4737 // Should still be at 0.
4738 loaded_.clear();
4739 extensions::InstalledLoader(service()).LoadAllExtensions();
4740 base::RunLoop().RunUntilIdle();
4741 ASSERT_EQ(0u, loaded_.size());
4742 ValidatePrefKeyCount(1);
4744 EXPECT_EQ(5, provider->visit_count());
4748 // Tests the external installation feature
4749 #if defined(OS_WIN)
4750 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
4751 // This should all work, even when normal extension installation is disabled.
4752 InitializeEmptyExtensionService();
4753 service()->set_extensions_enabled(false);
4755 // Now add providers. Extension system takes ownership of the objects.
4756 MockExtensionProvider* reg_provider =
4757 new MockExtensionProvider(service(), Manifest::EXTERNAL_REGISTRY);
4758 AddMockExternalProvider(reg_provider);
4759 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
4761 #endif
4763 TEST_F(ExtensionServiceTest, ExternalInstallPref) {
4764 InitializeEmptyExtensionService();
4766 // Now add providers. Extension system takes ownership of the objects.
4767 MockExtensionProvider* pref_provider =
4768 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
4770 AddMockExternalProvider(pref_provider);
4771 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
4774 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
4775 // This should all work, even when normal extension installation is disabled.
4776 InitializeEmptyExtensionService();
4777 service()->set_extensions_enabled(false);
4779 // TODO(skerner): The mock provider is not a good model of a provider
4780 // that works with update URLs, because it adds file and version info.
4781 // Extend the mock to work with update URLs. This test checks the
4782 // behavior that is common to all external extension visitors. The
4783 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4784 // what the visitor does results in an extension being downloaded and
4785 // installed.
4786 MockExtensionProvider* pref_provider =
4787 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF_DOWNLOAD);
4788 AddMockExternalProvider(pref_provider);
4789 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
4792 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
4793 // This should all work, even when normal extension installation is disabled.
4794 InitializeEmptyExtensionService();
4795 service()->set_extensions_enabled(false);
4797 // TODO(skerner): The mock provider is not a good model of a provider
4798 // that works with update URLs, because it adds file and version info.
4799 // Extend the mock to work with update URLs. This test checks the
4800 // behavior that is common to all external extension visitors. The
4801 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4802 // what the visitor does results in an extension being downloaded and
4803 // installed.
4804 MockExtensionProvider* pref_provider =
4805 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4806 AddMockExternalProvider(pref_provider);
4807 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
4810 // Tests that external extensions get uninstalled when the external extension
4811 // providers can't account for them.
4812 TEST_F(ExtensionServiceTest, ExternalUninstall) {
4813 // Start the extensions service with one external extension already installed.
4814 base::FilePath source_install_dir =
4815 data_dir().AppendASCII("good").AppendASCII("Extensions");
4816 base::FilePath pref_path = source_install_dir
4817 .DirName()
4818 .AppendASCII("PreferencesExternal");
4820 // This initializes the extensions service with no ExternalProviders.
4821 InitializeInstalledExtensionService(pref_path, source_install_dir);
4822 service()->set_extensions_enabled(false);
4824 service()->Init();
4826 ASSERT_EQ(0u, GetErrors().size());
4827 ASSERT_EQ(0u, loaded_.size());
4829 // Verify that it's not the disabled extensions flag causing it not to load.
4830 service()->set_extensions_enabled(true);
4831 service()->ReloadExtensionsForTest();
4832 base::RunLoop().RunUntilIdle();
4834 ASSERT_EQ(0u, GetErrors().size());
4835 ASSERT_EQ(0u, loaded_.size());
4838 // Test that running multiple update checks simultaneously does not
4839 // keep the update from succeeding.
4840 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
4841 InitializeEmptyExtensionService();
4843 MockExtensionProvider* provider =
4844 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
4845 AddMockExternalProvider(provider);
4847 // Verify that starting with no providers loads no extensions.
4848 service()->Init();
4849 ASSERT_EQ(0u, loaded_.size());
4851 // Start two checks for updates.
4852 provider->set_visit_count(0);
4853 service()->CheckForExternalUpdates();
4854 service()->CheckForExternalUpdates();
4855 base::RunLoop().RunUntilIdle();
4857 // Two calls should cause two checks for external extensions.
4858 EXPECT_EQ(2, provider->visit_count());
4859 EXPECT_EQ(0u, GetErrors().size());
4860 EXPECT_EQ(0u, loaded_.size());
4862 // Register a test extension externally using the mock registry provider.
4863 base::FilePath source_path = data_dir().AppendASCII("good.crx");
4864 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
4866 // Two checks for external updates should find the extension, and install it
4867 // once.
4868 content::WindowedNotificationObserver observer(
4869 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4870 content::NotificationService::AllSources());
4871 provider->set_visit_count(0);
4872 service()->CheckForExternalUpdates();
4873 service()->CheckForExternalUpdates();
4874 observer.Wait();
4875 EXPECT_EQ(2, provider->visit_count());
4876 ASSERT_EQ(0u, GetErrors().size());
4877 ASSERT_EQ(1u, loaded_.size());
4878 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
4879 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
4880 ValidatePrefKeyCount(1);
4881 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4882 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
4884 provider->RemoveExtension(good_crx);
4885 provider->set_visit_count(0);
4886 service()->CheckForExternalUpdates();
4887 service()->CheckForExternalUpdates();
4888 base::RunLoop().RunUntilIdle();
4890 // Two calls should cause two checks for external extensions.
4891 // Because the external source no longer includes good_crx,
4892 // good_crx will be uninstalled. So, expect that no extensions
4893 // are loaded.
4894 EXPECT_EQ(2, provider->visit_count());
4895 EXPECT_EQ(0u, GetErrors().size());
4896 EXPECT_EQ(0u, loaded_.size());
4899 TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
4900 InitializeEmptyExtensionService();
4902 // Test some valid extension records.
4903 // Set a base path to avoid erroring out on relative paths.
4904 // Paths starting with // are absolute on every platform we support.
4905 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
4906 ASSERT_TRUE(base_path.IsAbsolute());
4907 MockProviderVisitor visitor(base_path);
4908 std::string json_data =
4910 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4911 " \"external_crx\": \"RandomExtension.crx\","
4912 " \"external_version\": \"1.0\""
4913 " },"
4914 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4915 " \"external_crx\": \"RandomExtension2.crx\","
4916 " \"external_version\": \"2.0\""
4917 " },"
4918 " \"cccccccccccccccccccccccccccccccc\": {"
4919 " \"external_update_url\": \"http:\\\\foo.com/update\","
4920 " \"install_parameter\": \"id\""
4921 " }"
4922 "}";
4923 EXPECT_EQ(3, visitor.Visit(json_data));
4925 // Simulate an external_extensions.json file that contains seven invalid
4926 // records:
4927 // - One that is missing the 'external_crx' key.
4928 // - One that is missing the 'external_version' key.
4929 // - One that is specifying .. in the path.
4930 // - One that specifies both a file and update URL.
4931 // - One that specifies no file or update URL.
4932 // - One that has an update URL that is not well formed.
4933 // - One that contains a malformed version.
4934 // - One that has an invalid id.
4935 // - One that has a non-dictionary value.
4936 // - One that has an integer 'external_version' instead of a string.
4937 // The final extension is valid, and we check that it is read to make sure
4938 // failures don't stop valid records from being read.
4939 json_data =
4941 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4942 " \"external_version\": \"1.0\""
4943 " },"
4944 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4945 " \"external_crx\": \"RandomExtension.crx\""
4946 " },"
4947 " \"cccccccccccccccccccccccccccccccc\": {"
4948 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
4949 " \"external_version\": \"2.0\""
4950 " },"
4951 " \"dddddddddddddddddddddddddddddddd\": {"
4952 " \"external_crx\": \"RandomExtension2.crx\","
4953 " \"external_version\": \"2.0\","
4954 " \"external_update_url\": \"http:\\\\foo.com/update\""
4955 " },"
4956 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
4957 " },"
4958 " \"ffffffffffffffffffffffffffffffff\": {"
4959 " \"external_update_url\": \"This string is not a valid URL\""
4960 " },"
4961 " \"gggggggggggggggggggggggggggggggg\": {"
4962 " \"external_crx\": \"RandomExtension3.crx\","
4963 " \"external_version\": \"This is not a valid version!\""
4964 " },"
4965 " \"This is not a valid id!\": {},"
4966 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
4967 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
4968 " \"external_crx\": \"RandomExtension4.crx\","
4969 " \"external_version\": 1.0"
4970 " },"
4971 " \"pppppppppppppppppppppppppppppppp\": {"
4972 " \"external_crx\": \"RandomValidExtension.crx\","
4973 " \"external_version\": \"1.0\""
4974 " }"
4975 "}";
4976 EXPECT_EQ(1, visitor.Visit(json_data));
4978 // Check that if a base path is not provided, use of a relative
4979 // path fails.
4980 base::FilePath empty;
4981 MockProviderVisitor visitor_no_relative_paths(empty);
4983 // Use absolute paths. Expect success.
4984 json_data =
4986 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4987 " \"external_crx\": \"//RandomExtension1.crx\","
4988 " \"external_version\": \"3.0\""
4989 " },"
4990 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4991 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
4992 " \"external_version\": \"3.0\""
4993 " }"
4994 "}";
4995 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
4997 // Use a relative path. Expect that it will error out.
4998 json_data =
5000 " \"cccccccccccccccccccccccccccccccc\": {"
5001 " \"external_crx\": \"RandomExtension2.crx\","
5002 " \"external_version\": \"3.0\""
5003 " }"
5004 "}";
5005 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
5007 // Test supported_locales.
5008 json_data =
5010 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5011 " \"external_crx\": \"RandomExtension.crx\","
5012 " \"external_version\": \"1.0\","
5013 " \"supported_locales\": [ \"en\" ]"
5014 " },"
5015 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5016 " \"external_crx\": \"RandomExtension2.crx\","
5017 " \"external_version\": \"2.0\","
5018 " \"supported_locales\": [ \"en-GB\" ]"
5019 " },"
5020 " \"cccccccccccccccccccccccccccccccc\": {"
5021 " \"external_crx\": \"RandomExtension2.crx\","
5022 " \"external_version\": \"3.0\","
5023 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
5024 " }"
5025 "}";
5027 ScopedBrowserLocale guard("en-US");
5028 EXPECT_EQ(2, visitor.Visit(json_data));
5031 // Test keep_if_present.
5032 json_data =
5034 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5035 " \"external_crx\": \"RandomExtension.crx\","
5036 " \"external_version\": \"1.0\","
5037 " \"keep_if_present\": true"
5038 " }"
5039 "}";
5041 EXPECT_EQ(0, visitor.Visit(json_data));
5044 // Test is_bookmark_app.
5045 MockProviderVisitor from_bookmark_visitor(
5046 base_path, Extension::FROM_BOOKMARK);
5047 json_data =
5049 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5050 " \"external_crx\": \"RandomExtension.crx\","
5051 " \"external_version\": \"1.0\","
5052 " \"is_bookmark_app\": true"
5053 " }"
5054 "}";
5055 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
5057 // Test is_from_webstore.
5058 MockProviderVisitor from_webstore_visitor(
5059 base_path, Extension::FROM_WEBSTORE);
5060 json_data =
5062 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5063 " \"external_crx\": \"RandomExtension.crx\","
5064 " \"external_version\": \"1.0\","
5065 " \"is_from_webstore\": true"
5066 " }"
5067 "}";
5068 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
5070 // Test was_installed_by_eom.
5071 MockProviderVisitor was_installed_by_eom_visitor(
5072 base_path, Extension::WAS_INSTALLED_BY_OEM);
5073 json_data =
5075 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5076 " \"external_crx\": \"RandomExtension.crx\","
5077 " \"external_version\": \"1.0\","
5078 " \"was_installed_by_oem\": true"
5079 " }"
5080 "}";
5081 EXPECT_EQ(1, was_installed_by_eom_visitor.Visit(json_data));
5084 // Test loading good extensions from the profile directory.
5085 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
5086 // Ensure we're testing in "en" and leave global state untouched.
5087 extension_l10n_util::ScopedLocaleForTest testLocale("en");
5089 // Initialize the test dir with a good Preferences/extensions.
5090 base::FilePath source_install_dir = data_dir().AppendASCII("l10n");
5091 base::FilePath pref_path =
5092 source_install_dir.Append(chrome::kPreferencesFilename);
5093 InitializeInstalledExtensionService(pref_path, source_install_dir);
5095 service()->Init();
5097 ASSERT_EQ(3u, loaded_.size());
5099 // This was equal to "sr" on load.
5100 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
5102 // These are untouched by re-localization.
5103 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
5104 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
5106 // This one starts with Serbian name, and gets re-localized into English.
5107 EXPECT_EQ("My name is simple.", loaded_[0]->name());
5109 // These are untouched by re-localization.
5110 EXPECT_EQ("My name is simple.", loaded_[1]->name());
5111 EXPECT_EQ("no l10n", loaded_[2]->name());
5114 class ExtensionsReadyRecorder : public content::NotificationObserver {
5115 public:
5116 ExtensionsReadyRecorder() : ready_(false) {
5117 registrar_.Add(this,
5118 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
5119 content::NotificationService::AllSources());
5122 void set_ready(bool value) { ready_ = value; }
5123 bool ready() { return ready_; }
5125 private:
5126 virtual void Observe(int type,
5127 const content::NotificationSource& source,
5128 const content::NotificationDetails& details) override {
5129 switch (type) {
5130 case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED:
5131 ready_ = true;
5132 break;
5133 default:
5134 NOTREACHED();
5138 content::NotificationRegistrar registrar_;
5139 bool ready_;
5142 // Test that we get enabled/disabled correctly for all the pref/command-line
5143 // combinations. We don't want to derive from the ExtensionServiceTest class
5144 // for this test, so we use ExtensionServiceTestSimple.
5146 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
5147 // enabled or not.
5148 TEST(ExtensionServiceTestSimple, Enabledness) {
5149 // Make sure the PluginService singleton is destroyed at the end of the test.
5150 base::ShadowingAtExitManager at_exit_manager;
5151 #if defined(ENABLE_PLUGINS)
5152 content::PluginService::GetInstance()->Init();
5153 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
5154 #endif
5156 ExtensionErrorReporter::Init(false); // no noisy errors
5157 ExtensionsReadyRecorder recorder;
5158 scoped_ptr<TestingProfile> profile(new TestingProfile());
5159 content::TestBrowserThreadBundle thread_bundle_;
5160 #if defined OS_CHROMEOS
5161 chromeos::ScopedTestDeviceSettingsService device_settings_service;
5162 chromeos::ScopedTestCrosSettings cros_settings;
5163 scoped_ptr<chromeos::ScopedTestUserManager> user_manager(
5164 new chromeos::ScopedTestUserManager);
5165 #endif
5166 scoped_ptr<CommandLine> command_line;
5167 base::FilePath install_dir = profile->GetPath()
5168 .AppendASCII(extensions::kInstallDirectoryName);
5170 // By default, we are enabled.
5171 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
5172 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
5173 ExtensionSystem::Get(profile.get()))->
5174 CreateExtensionService(
5175 command_line.get(),
5176 install_dir,
5177 false);
5178 EXPECT_TRUE(service->extensions_enabled());
5179 service->Init();
5180 base::RunLoop().RunUntilIdle();
5181 EXPECT_TRUE(recorder.ready());
5182 #if defined OS_CHROMEOS
5183 user_manager.reset();
5184 #endif
5186 // If either the command line or pref is set, we are disabled.
5187 recorder.set_ready(false);
5188 profile.reset(new TestingProfile());
5189 command_line->AppendSwitch(switches::kDisableExtensions);
5190 service = static_cast<extensions::TestExtensionSystem*>(
5191 ExtensionSystem::Get(profile.get()))->
5192 CreateExtensionService(
5193 command_line.get(),
5194 install_dir,
5195 false);
5196 EXPECT_FALSE(service->extensions_enabled());
5197 service->Init();
5198 base::RunLoop().RunUntilIdle();
5199 EXPECT_TRUE(recorder.ready());
5201 recorder.set_ready(false);
5202 profile.reset(new TestingProfile());
5203 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5204 service = static_cast<extensions::TestExtensionSystem*>(
5205 ExtensionSystem::Get(profile.get()))->
5206 CreateExtensionService(
5207 command_line.get(),
5208 install_dir,
5209 false);
5210 EXPECT_FALSE(service->extensions_enabled());
5211 service->Init();
5212 base::RunLoop().RunUntilIdle();
5213 EXPECT_TRUE(recorder.ready());
5215 recorder.set_ready(false);
5216 profile.reset(new TestingProfile());
5217 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5218 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
5219 service = static_cast<extensions::TestExtensionSystem*>(
5220 ExtensionSystem::Get(profile.get()))->
5221 CreateExtensionService(
5222 command_line.get(),
5223 install_dir,
5224 false);
5225 EXPECT_FALSE(service->extensions_enabled());
5226 service->Init();
5227 base::RunLoop().RunUntilIdle();
5228 EXPECT_TRUE(recorder.ready());
5230 // Explicitly delete all the resources used in this test.
5231 profile.reset();
5232 service = NULL;
5233 // Execute any pending deletion tasks.
5234 base::RunLoop().RunUntilIdle();
5237 // Test loading extensions that require limited and unlimited storage quotas.
5238 TEST_F(ExtensionServiceTest, StorageQuota) {
5239 InitializeEmptyExtensionService();
5241 base::FilePath extensions_path = data_dir().AppendASCII("storage_quota");
5243 base::FilePath limited_quota_ext =
5244 extensions_path.AppendASCII("limited_quota")
5245 .AppendASCII("1.0");
5247 // The old permission name for unlimited quota was "unlimited_storage", but
5248 // we changed it to "unlimitedStorage". This tests both versions.
5249 base::FilePath unlimited_quota_ext =
5250 extensions_path.AppendASCII("unlimited_quota")
5251 .AppendASCII("1.0");
5252 base::FilePath unlimited_quota_ext2 =
5253 extensions_path.AppendASCII("unlimited_quota")
5254 .AppendASCII("2.0");
5255 extensions::UnpackedInstaller::Create(service())->Load(limited_quota_ext);
5256 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext);
5257 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext2);
5258 base::RunLoop().RunUntilIdle();
5260 ASSERT_EQ(3u, loaded_.size());
5261 EXPECT_TRUE(profile());
5262 EXPECT_FALSE(profile()->IsOffTheRecord());
5263 EXPECT_FALSE(
5264 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5265 loaded_[0]->url()));
5266 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5267 loaded_[1]->url()));
5268 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5269 loaded_[2]->url()));
5272 // Tests ComponentLoader::Add().
5273 TEST_F(ExtensionServiceTest, ComponentExtensions) {
5274 InitializeEmptyExtensionService();
5276 // Component extensions should work even when extensions are disabled.
5277 service()->set_extensions_enabled(false);
5279 base::FilePath path = data_dir()
5280 .AppendASCII("good")
5281 .AppendASCII("Extensions")
5282 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
5283 .AppendASCII("1.0.0.0");
5285 std::string manifest;
5286 ASSERT_TRUE(base::ReadFileToString(
5287 path.Append(extensions::kManifestFilename), &manifest));
5289 service()->component_loader()->Add(manifest, path);
5290 service()->Init();
5292 // Note that we do not pump messages -- the extension should be loaded
5293 // immediately.
5295 EXPECT_EQ(0u, GetErrors().size());
5296 ASSERT_EQ(1u, loaded_.size());
5297 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
5298 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5300 // Component extensions get a prefs entry on first install.
5301 ValidatePrefKeyCount(1);
5303 // Reload all extensions, and make sure it comes back.
5304 std::string extension_id = (*registry()->enabled_extensions().begin())->id();
5305 loaded_.clear();
5306 service()->ReloadExtensionsForTest();
5307 ASSERT_EQ(1u, registry()->enabled_extensions().size());
5308 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id());
5311 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
5312 InitializeEmptyExtensionService();
5313 InitializeExtensionSyncService();
5315 bool flare_was_called = false;
5316 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5317 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5318 extension_sync_service()->SetSyncStartFlare(
5319 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5320 factory.GetWeakPtr(),
5321 &flare_was_called, // Safe due to WeakPtrFactory scope.
5322 &triggered_type)); // Safe due to WeakPtrFactory scope.
5324 // Install a component extension.
5325 std::string manifest;
5326 ASSERT_TRUE(base::ReadFileToString(
5327 good0_path().Append(extensions::kManifestFilename), &manifest));
5328 service()->component_loader()->Add(manifest, good0_path());
5329 ASSERT_FALSE(service()->is_ready());
5330 service()->Init();
5331 ASSERT_TRUE(service()->is_ready());
5333 // Extensions added before service is_ready() don't trigger sync startup.
5334 EXPECT_FALSE(flare_was_called);
5335 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5338 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
5339 InitializeGoodInstalledExtensionService();
5340 InitializeExtensionSyncService();
5342 bool flare_was_called = false;
5343 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5344 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5345 extension_sync_service()->SetSyncStartFlare(
5346 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5347 factory.GetWeakPtr(),
5348 &flare_was_called, // Safe due to WeakPtrFactory scope.
5349 &triggered_type)); // Safe due to WeakPtrFactory scope.
5351 ASSERT_FALSE(service()->is_ready());
5352 service()->Init();
5353 ASSERT_EQ(3u, loaded_.size());
5354 ASSERT_TRUE(service()->is_ready());
5356 // Extensions added before service is_ready() don't trigger sync startup.
5357 EXPECT_FALSE(flare_was_called);
5358 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5361 TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
5362 InitializeEmptyExtensionService();
5363 InitializeExtensionSyncService();
5364 service()->Init();
5365 ASSERT_TRUE(service()->is_ready());
5367 bool flare_was_called = false;
5368 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5369 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5370 extension_sync_service()->SetSyncStartFlare(
5371 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5372 factory.GetWeakPtr(),
5373 &flare_was_called, // Safe due to WeakPtrFactory scope.
5374 &triggered_type)); // Safe due to WeakPtrFactory scope.
5376 base::FilePath path = data_dir().AppendASCII("good.crx");
5377 InstallCRX(path, INSTALL_NEW);
5379 EXPECT_TRUE(flare_was_called);
5380 EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
5382 // Reset.
5383 flare_was_called = false;
5384 triggered_type = syncer::UNSPECIFIED;
5386 // Once sync starts, flare should no longer be invoked.
5387 extension_sync_service()->MergeDataAndStartSyncing(
5388 syncer::EXTENSIONS,
5389 syncer::SyncDataList(),
5390 scoped_ptr<syncer::SyncChangeProcessor>(
5391 new syncer::FakeSyncChangeProcessor),
5392 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5393 path = data_dir().AppendASCII("page_action.crx");
5394 InstallCRX(path, INSTALL_NEW);
5395 EXPECT_FALSE(flare_was_called);
5396 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5399 TEST_F(ExtensionServiceTest, DisableExtensionFromSync) {
5400 // Start the extensions service with one external extension already installed.
5401 base::FilePath source_install_dir =
5402 data_dir().AppendASCII("good").AppendASCII("Extensions");
5403 base::FilePath pref_path =
5404 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5406 InitializeInstalledExtensionService(pref_path, source_install_dir);
5407 InitializeExtensionSyncService();
5409 // The user has enabled sync.
5410 ProfileSyncService* sync_service =
5411 ProfileSyncServiceFactory::GetForProfile(profile());
5412 sync_service->SetSyncSetupCompleted();
5414 service()->Init();
5415 ASSERT_TRUE(service()->is_ready());
5417 ASSERT_EQ(3u, loaded_.size());
5419 // We start enabled.
5420 const Extension* extension = service()->GetExtensionById(good0, true);
5421 ASSERT_TRUE(extension);
5422 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5423 extensions::ExtensionSyncData disable_good_crx(
5424 *extension, false, false, false);
5426 // Then sync data arrives telling us to disable |good0|.
5427 syncer::SyncDataList sync_data;
5428 sync_data.push_back(disable_good_crx.GetSyncData());
5429 extension_sync_service()->MergeDataAndStartSyncing(
5430 syncer::EXTENSIONS,
5431 sync_data,
5432 scoped_ptr<syncer::SyncChangeProcessor>(
5433 new syncer::FakeSyncChangeProcessor),
5434 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5435 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5438 TEST_F(ExtensionServiceTest, DontDisableExtensionWithPendingEnableFromSync) {
5439 // Start the extensions service with one external extension already installed.
5440 base::FilePath source_install_dir =
5441 data_dir().AppendASCII("good").AppendASCII("Extensions");
5442 base::FilePath pref_path =
5443 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5445 InitializeInstalledExtensionService(pref_path, source_install_dir);
5446 InitializeExtensionSyncService();
5448 // The user has enabled sync.
5449 ProfileSyncService* sync_service =
5450 ProfileSyncServiceFactory::GetForProfile(profile());
5451 sync_service->SetSyncSetupCompleted();
5453 service()->Init();
5454 ASSERT_TRUE(service()->is_ready());
5455 ASSERT_EQ(3u, loaded_.size());
5457 const Extension* extension = service()->GetExtensionById(good0, true);
5458 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5460 // Disable extension before first sync data arrives.
5461 service()->DisableExtension(good0, Extension::DISABLE_USER_ACTION);
5462 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5464 // Enable extension - this is now the most recent state.
5465 service()->EnableExtension(good0);
5466 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5468 // Now sync data comes in that says to disable good0. This should be
5469 // ignored.
5470 extensions::ExtensionSyncData disable_good_crx(
5471 *extension, false, false, false);
5472 syncer::SyncDataList sync_data;
5473 sync_data.push_back(disable_good_crx.GetSyncData());
5474 extension_sync_service()->MergeDataAndStartSyncing(
5475 syncer::EXTENSIONS,
5476 sync_data,
5477 scoped_ptr<syncer::SyncChangeProcessor>(
5478 new syncer::FakeSyncChangeProcessor),
5479 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5481 // The extension was enabled locally before the sync data arrived, so it
5482 // should still be enabled now.
5483 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5486 TEST_F(ExtensionServiceTest, GetSyncData) {
5487 InitializeEmptyExtensionService();
5488 InitializeExtensionSyncService();
5489 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5490 const Extension* extension = service()->GetInstalledExtension(good_crx);
5491 ASSERT_TRUE(extension);
5493 extension_sync_service()->MergeDataAndStartSyncing(
5494 syncer::EXTENSIONS,
5495 syncer::SyncDataList(),
5496 scoped_ptr<syncer::SyncChangeProcessor>(
5497 new syncer::FakeSyncChangeProcessor),
5498 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5500 syncer::SyncDataList list =
5501 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5502 ASSERT_EQ(list.size(), 1U);
5503 extensions::ExtensionSyncData data(list[0]);
5504 EXPECT_EQ(extension->id(), data.id());
5505 EXPECT_FALSE(data.uninstalled());
5506 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data.enabled());
5507 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
5508 data.incognito_enabled());
5509 EXPECT_TRUE(data.version().Equals(*extension->version()));
5510 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
5511 data.update_url());
5512 EXPECT_EQ(extension->name(), data.name());
5515 TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
5516 InitializeEmptyExtensionService();
5517 InitializeExtensionSyncService();
5518 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5519 TerminateExtension(good_crx);
5520 const Extension* extension = service()->GetInstalledExtension(good_crx);
5521 ASSERT_TRUE(extension);
5523 syncer::FakeSyncChangeProcessor processor;
5524 extension_sync_service()->MergeDataAndStartSyncing(
5525 syncer::EXTENSIONS,
5526 syncer::SyncDataList(),
5527 scoped_ptr<syncer::SyncChangeProcessor>(
5528 new syncer::FakeSyncChangeProcessor),
5529 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5531 syncer::SyncDataList list =
5532 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5533 ASSERT_EQ(list.size(), 1U);
5534 extensions::ExtensionSyncData data(list[0]);
5535 EXPECT_EQ(extension->id(), data.id());
5536 EXPECT_FALSE(data.uninstalled());
5537 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data.enabled());
5538 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
5539 data.incognito_enabled());
5540 EXPECT_TRUE(data.version().Equals(*extension->version()));
5541 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
5542 data.update_url());
5543 EXPECT_EQ(extension->name(), data.name());
5546 TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
5547 InitializeEmptyExtensionService();
5548 InitializeExtensionSyncService();
5549 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5550 const Extension* extension = service()->GetInstalledExtension(good_crx);
5551 ASSERT_TRUE(extension);
5553 syncer::FakeSyncChangeProcessor processor;
5554 extension_sync_service()->MergeDataAndStartSyncing(
5555 syncer::APPS,
5556 syncer::SyncDataList(),
5557 scoped_ptr<syncer::SyncChangeProcessor>(
5558 new syncer::FakeSyncChangeProcessor),
5559 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5561 syncer::SyncDataList list =
5562 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5563 ASSERT_EQ(list.size(), 0U);
5566 TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
5567 InitializeEmptyExtensionService();
5568 InitializeProcessManager();
5569 InitializeExtensionSyncService();
5570 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5571 const Extension* extension = service()->GetInstalledExtension(good_crx);
5572 ASSERT_TRUE(extension);
5574 syncer::FakeSyncChangeProcessor processor;
5575 extension_sync_service()->MergeDataAndStartSyncing(
5576 syncer::EXTENSIONS,
5577 syncer::SyncDataList(),
5578 scoped_ptr<syncer::SyncChangeProcessor>(
5579 new syncer::FakeSyncChangeProcessor),
5580 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5583 syncer::SyncDataList list =
5584 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5585 ASSERT_EQ(list.size(), 1U);
5586 extensions::ExtensionSyncData data(list[0]);
5587 EXPECT_TRUE(data.enabled());
5588 EXPECT_FALSE(data.incognito_enabled());
5591 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
5593 syncer::SyncDataList list =
5594 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5595 ASSERT_EQ(list.size(), 1U);
5596 extensions::ExtensionSyncData data(list[0]);
5597 EXPECT_FALSE(data.enabled());
5598 EXPECT_FALSE(data.incognito_enabled());
5601 extensions::util::SetIsIncognitoEnabled(good_crx, profile(), true);
5603 syncer::SyncDataList list =
5604 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5605 ASSERT_EQ(list.size(), 1U);
5606 extensions::ExtensionSyncData data(list[0]);
5607 EXPECT_FALSE(data.enabled());
5608 EXPECT_TRUE(data.incognito_enabled());
5611 service()->EnableExtension(good_crx);
5613 syncer::SyncDataList list =
5614 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5615 ASSERT_EQ(list.size(), 1U);
5616 extensions::ExtensionSyncData data(list[0]);
5617 EXPECT_TRUE(data.enabled());
5618 EXPECT_TRUE(data.incognito_enabled());
5622 TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
5623 InitializeEmptyExtensionService();
5624 InitializeExtensionSyncService();
5625 InstallCRXWithLocation(
5626 data_dir().AppendASCII("good.crx"), Manifest::EXTERNAL_PREF, INSTALL_NEW);
5627 const Extension* extension = service()->GetInstalledExtension(good_crx);
5628 ASSERT_TRUE(extension);
5630 syncer::FakeSyncChangeProcessor processor;
5631 extension_sync_service()->MergeDataAndStartSyncing(
5632 syncer::EXTENSIONS,
5633 syncer::SyncDataList(),
5634 scoped_ptr<syncer::SyncChangeProcessor>(
5635 new syncer::FakeSyncChangeProcessor),
5636 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5638 UninstallExtension(good_crx, false);
5639 EXPECT_TRUE(
5640 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
5642 sync_pb::EntitySpecifics specifics;
5643 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
5644 sync_pb::ExtensionSpecifics* extension_specifics =
5645 app_specifics->mutable_extension();
5646 extension_specifics->set_id(good_crx);
5647 extension_specifics->set_version("1.0");
5648 extension_specifics->set_enabled(true);
5650 syncer::SyncData sync_data =
5651 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5652 syncer::SyncChange sync_change(FROM_HERE,
5653 syncer::SyncChange::ACTION_UPDATE,
5654 sync_data);
5655 syncer::SyncChangeList list(1);
5656 list[0] = sync_change;
5658 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5659 EXPECT_TRUE(
5660 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
5663 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
5664 InitializeEmptyExtensionService();
5665 InitializeExtensionSyncService();
5666 const Extension* app =
5667 PackAndInstallCRX(data_dir().AppendASCII("app"), INSTALL_NEW);
5668 ASSERT_TRUE(app);
5669 ASSERT_TRUE(app->is_app());
5671 syncer::FakeSyncChangeProcessor processor;
5672 extension_sync_service()->MergeDataAndStartSyncing(
5673 syncer::APPS,
5674 syncer::SyncDataList(),
5675 scoped_ptr<syncer::SyncChangeProcessor>(
5676 new syncer::FakeSyncChangeProcessor),
5677 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5679 syncer::StringOrdinal initial_ordinal =
5680 syncer::StringOrdinal::CreateInitialOrdinal();
5682 syncer::SyncDataList list =
5683 extension_sync_service()->GetAllSyncData(syncer::APPS);
5684 ASSERT_EQ(list.size(), 1U);
5686 extensions::AppSyncData app_sync_data(list[0]);
5687 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.app_launch_ordinal()));
5688 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
5691 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
5692 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
5694 syncer::SyncDataList list =
5695 extension_sync_service()->GetAllSyncData(syncer::APPS);
5696 ASSERT_EQ(list.size(), 1U);
5698 extensions::AppSyncData app_sync_data(list[0]);
5699 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
5700 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
5703 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
5705 syncer::SyncDataList list =
5706 extension_sync_service()->GetAllSyncData(syncer::APPS);
5707 ASSERT_EQ(list.size(), 1U);
5709 extensions::AppSyncData app_sync_data(list[0]);
5710 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
5711 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.page_ordinal()));
5715 // TODO (rdevlin.cronin): The OnExtensionMoved() method has been removed from
5716 // ExtensionService, so this test probably needs a new home. Unfortunately, it
5717 // relies pretty heavily on things like InitializeExtension[Sync]Service() and
5718 // PackAndInstallCRX(). When we clean up a bit more, this should move out.
5719 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
5720 InitializeEmptyExtensionService();
5721 InitializeExtensionSyncService();
5722 const size_t kAppCount = 3;
5723 const Extension* apps[kAppCount];
5724 apps[0] = PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
5725 apps[1] = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
5726 apps[2] = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
5727 for (size_t i = 0; i < kAppCount; ++i) {
5728 ASSERT_TRUE(apps[i]);
5729 ASSERT_TRUE(apps[i]->is_app());
5732 syncer::FakeSyncChangeProcessor processor;
5733 extension_sync_service()->MergeDataAndStartSyncing(
5734 syncer::APPS,
5735 syncer::SyncDataList(),
5736 scoped_ptr<syncer::SyncChangeProcessor>(
5737 new syncer::FakeSyncChangeProcessor),
5738 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5740 ExtensionPrefs::Get(service()->GetBrowserContext())
5741 ->app_sorting()
5742 ->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
5744 syncer::SyncDataList list =
5745 extension_sync_service()->GetAllSyncData(syncer::APPS);
5746 ASSERT_EQ(list.size(), 3U);
5748 extensions::AppSyncData data[kAppCount];
5749 for (size_t i = 0; i < kAppCount; ++i) {
5750 data[i] = extensions::AppSyncData(list[i]);
5753 // The sync data is not always in the same order our apps were installed in,
5754 // so we do that sorting here so we can make sure the values are changed as
5755 // expected.
5756 syncer::StringOrdinal app_launch_ordinals[kAppCount];
5757 for (size_t i = 0; i < kAppCount; ++i) {
5758 for (size_t j = 0; j < kAppCount; ++j) {
5759 if (apps[i]->id() == data[j].id())
5760 app_launch_ordinals[i] = data[j].app_launch_ordinal();
5764 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
5765 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
5769 TEST_F(ExtensionServiceTest, GetSyncDataList) {
5770 InitializeEmptyExtensionService();
5771 InitializeExtensionSyncService();
5772 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5773 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
5774 InstallCRX(data_dir().AppendASCII("theme.crx"), INSTALL_NEW);
5775 InstallCRX(data_dir().AppendASCII("theme2.crx"), INSTALL_NEW);
5777 syncer::FakeSyncChangeProcessor processor;
5778 extension_sync_service()->MergeDataAndStartSyncing(
5779 syncer::APPS,
5780 syncer::SyncDataList(),
5781 scoped_ptr<syncer::SyncChangeProcessor>(
5782 new syncer::FakeSyncChangeProcessor),
5783 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5784 extension_sync_service()->MergeDataAndStartSyncing(
5785 syncer::EXTENSIONS,
5786 syncer::SyncDataList(),
5787 scoped_ptr<syncer::SyncChangeProcessor>(
5788 new syncer::FakeSyncChangeProcessor),
5789 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5791 service()->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
5792 TerminateExtension(theme2_crx);
5794 EXPECT_EQ(0u, extension_sync_service()->GetAllSyncData(syncer::APPS).size());
5795 EXPECT_EQ(
5796 2u, extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS).size());
5799 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
5800 InitializeEmptyExtensionService();
5801 InitializeExtensionSyncService();
5802 syncer::FakeSyncChangeProcessor processor;
5803 extension_sync_service()->MergeDataAndStartSyncing(
5804 syncer::EXTENSIONS,
5805 syncer::SyncDataList(),
5806 scoped_ptr<syncer::SyncChangeProcessor>(
5807 new syncer::FakeSyncChangeProcessor),
5808 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5810 sync_pb::EntitySpecifics specifics;
5811 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5812 ext_specifics->set_id(good_crx);
5813 ext_specifics->set_version("1.0");
5814 syncer::SyncData sync_data =
5815 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5816 syncer::SyncChange sync_change(FROM_HERE,
5817 syncer::SyncChange::ACTION_DELETE,
5818 sync_data);
5819 syncer::SyncChangeList list(1);
5820 list[0] = sync_change;
5822 // Should do nothing.
5823 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5824 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
5826 // Install the extension.
5827 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
5828 InstallCRX(extension_path, INSTALL_NEW);
5829 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
5831 // Should uninstall the extension.
5832 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5833 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
5835 // Should again do nothing.
5836 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5837 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
5840 TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
5841 InitializeEmptyExtensionService();
5842 InitializeExtensionSyncService();
5844 // Install the extension.
5845 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
5846 InstallCRX(extension_path, INSTALL_NEW);
5847 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
5849 sync_pb::EntitySpecifics specifics;
5850 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
5851 sync_pb::ExtensionSpecifics* extension_specifics =
5852 app_specifics->mutable_extension();
5853 extension_specifics->set_id(good_crx);
5854 extension_specifics->set_version(
5855 service()->GetInstalledExtension(good_crx)->version()->GetString());
5858 extension_specifics->set_enabled(true);
5859 syncer::SyncData sync_data =
5860 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5861 syncer::SyncChange sync_change(FROM_HERE,
5862 syncer::SyncChange::ACTION_DELETE,
5863 sync_data);
5864 syncer::SyncChangeList list(1);
5865 list[0] = sync_change;
5867 // Should do nothing
5868 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5869 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
5873 extension_specifics->set_enabled(false);
5874 syncer::SyncData sync_data =
5875 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5876 syncer::SyncChange sync_change(FROM_HERE,
5877 syncer::SyncChange::ACTION_UPDATE,
5878 sync_data);
5879 syncer::SyncChangeList list(1);
5880 list[0] = sync_change;
5882 // Should again do nothing.
5883 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5884 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
5888 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
5889 InitializeEmptyExtensionService();
5890 InitializeProcessManager();
5891 InitializeExtensionSyncService();
5892 syncer::FakeSyncChangeProcessor processor;
5893 extension_sync_service()->MergeDataAndStartSyncing(
5894 syncer::EXTENSIONS,
5895 syncer::SyncDataList(),
5896 scoped_ptr<syncer::SyncChangeProcessor>(
5897 new syncer::FakeSyncChangeProcessor),
5898 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5900 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5901 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
5902 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
5904 sync_pb::EntitySpecifics specifics;
5905 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5906 ext_specifics->set_id(good_crx);
5907 ext_specifics->set_version(
5908 service()->GetInstalledExtension(good_crx)->version()->GetString());
5909 ext_specifics->set_enabled(false);
5912 syncer::SyncData sync_data =
5913 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5914 syncer::SyncChange sync_change(FROM_HERE,
5915 syncer::SyncChange::ACTION_UPDATE,
5916 sync_data);
5917 syncer::SyncChangeList list(1);
5918 list[0] = sync_change;
5919 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5920 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
5921 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
5925 ext_specifics->set_enabled(true);
5926 ext_specifics->set_incognito_enabled(true);
5927 syncer::SyncData sync_data =
5928 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5929 syncer::SyncChange sync_change(FROM_HERE,
5930 syncer::SyncChange::ACTION_UPDATE,
5931 sync_data);
5932 syncer::SyncChangeList list(1);
5933 list[0] = sync_change;
5934 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5935 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
5936 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
5940 ext_specifics->set_enabled(false);
5941 ext_specifics->set_incognito_enabled(true);
5942 syncer::SyncData sync_data =
5943 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5944 syncer::SyncChange sync_change(FROM_HERE,
5945 syncer::SyncChange::ACTION_UPDATE,
5946 sync_data);
5947 syncer::SyncChangeList list(1);
5948 list[0] = sync_change;
5949 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5950 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
5951 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
5954 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
5957 TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
5958 InitializeExtensionServiceWithUpdater();
5959 InitializeExtensionSyncService();
5960 syncer::FakeSyncChangeProcessor processor;
5961 extension_sync_service()->MergeDataAndStartSyncing(
5962 syncer::EXTENSIONS,
5963 syncer::SyncDataList(),
5964 scoped_ptr<syncer::SyncChangeProcessor>(
5965 new syncer::FakeSyncChangeProcessor),
5966 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5968 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5969 TerminateExtension(good_crx);
5970 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
5971 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
5973 sync_pb::EntitySpecifics specifics;
5974 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5975 ext_specifics->set_id(good_crx);
5976 ext_specifics->set_version(
5977 service()->GetInstalledExtension(good_crx)->version()->GetString());
5978 ext_specifics->set_enabled(false);
5979 ext_specifics->set_incognito_enabled(true);
5980 syncer::SyncData sync_data =
5981 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5982 syncer::SyncChange sync_change(FROM_HERE,
5983 syncer::SyncChange::ACTION_UPDATE,
5984 sync_data);
5985 syncer::SyncChangeList list(1);
5986 list[0] = sync_change;
5988 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
5989 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
5990 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
5992 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
5995 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
5996 InitializeExtensionServiceWithUpdater();
5997 InitializeExtensionSyncService();
5998 syncer::FakeSyncChangeProcessor processor;
5999 extension_sync_service()->MergeDataAndStartSyncing(
6000 syncer::EXTENSIONS,
6001 syncer::SyncDataList(),
6002 scoped_ptr<syncer::SyncChangeProcessor>(
6003 new syncer::FakeSyncChangeProcessor),
6004 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6006 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6007 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6008 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6010 sync_pb::EntitySpecifics specifics;
6011 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6012 ext_specifics->set_id(good_crx);
6013 ext_specifics->set_enabled(true);
6016 ext_specifics->set_version(
6017 service()->GetInstalledExtension(good_crx)->version()->GetString());
6018 syncer::SyncData sync_data =
6019 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6020 syncer::SyncChange sync_change(FROM_HERE,
6021 syncer::SyncChange::ACTION_UPDATE,
6022 sync_data);
6023 syncer::SyncChangeList list(1);
6024 list[0] = sync_change;
6026 // Should do nothing if extension version == sync version.
6027 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6028 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6031 // Should do nothing if extension version > sync version (but see
6032 // the TODO in ProcessExtensionSyncData).
6034 ext_specifics->set_version("0.0.0.0");
6035 syncer::SyncData sync_data =
6036 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6037 syncer::SyncChange sync_change(FROM_HERE,
6038 syncer::SyncChange::ACTION_UPDATE,
6039 sync_data);
6040 syncer::SyncChangeList list(1);
6041 list[0] = sync_change;
6043 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6044 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6047 // Should kick off an update if extension version < sync version.
6049 ext_specifics->set_version("9.9.9.9");
6050 syncer::SyncData sync_data =
6051 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6052 syncer::SyncChange sync_change(FROM_HERE,
6053 syncer::SyncChange::ACTION_UPDATE,
6054 sync_data);
6055 syncer::SyncChangeList list(1);
6056 list[0] = sync_change;
6058 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6059 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6062 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6065 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
6066 InitializeExtensionServiceWithUpdater();
6067 InitializeExtensionSyncService();
6068 syncer::FakeSyncChangeProcessor processor;
6069 extension_sync_service()->MergeDataAndStartSyncing(
6070 syncer::EXTENSIONS,
6071 syncer::SyncDataList(),
6072 scoped_ptr<syncer::SyncChangeProcessor>(
6073 new syncer::FakeSyncChangeProcessor),
6074 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6076 sync_pb::EntitySpecifics specifics;
6077 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6078 ext_specifics->set_id(good_crx);
6079 ext_specifics->set_enabled(false);
6080 ext_specifics->set_incognito_enabled(true);
6081 ext_specifics->set_update_url("http://www.google.com/");
6082 ext_specifics->set_version("1.2.3.4");
6083 syncer::SyncData sync_data =
6084 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6085 syncer::SyncChange sync_change(FROM_HERE,
6086 syncer::SyncChange::ACTION_UPDATE,
6087 sync_data);
6088 syncer::SyncChangeList list(1);
6089 list[0] = sync_change;
6091 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6092 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6093 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6094 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6095 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6096 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6098 const extensions::PendingExtensionInfo* info;
6099 EXPECT_TRUE(
6100 (info = service()->pending_extension_manager()->GetById(good_crx)));
6101 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
6102 EXPECT_TRUE(info->is_from_sync());
6103 EXPECT_EQ(Manifest::INTERNAL, info->install_source());
6104 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
6107 #if defined(ENABLE_MANAGED_USERS)
6108 TEST_F(ExtensionServiceTest, SupervisedUser_InstallOnlyAllowedByCustodian) {
6109 ExtensionServiceInitParams params = CreateDefaultInitParams();
6110 params.profile_is_supervised = true;
6111 InitializeExtensionService(params);
6113 SupervisedUserService* supervised_user_service =
6114 SupervisedUserServiceFactory::GetForProfile(profile());
6115 GetManagementPolicy()->RegisterProvider(supervised_user_service);
6117 base::FilePath path1 = data_dir().AppendASCII("good.crx");
6118 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
6119 const Extension* extensions[] = {
6120 InstallCRX(path1, INSTALL_FAILED),
6121 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
6124 // Only the extension with the "installed by custodian" flag should have been
6125 // installed and enabled.
6126 EXPECT_FALSE(extensions[0]);
6127 ASSERT_TRUE(extensions[1]);
6128 EXPECT_TRUE(registry()->enabled_extensions().Contains(extensions[1]->id()));
6131 TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithoutPermissionIncrease) {
6132 ExtensionServiceInitParams params = CreateDefaultInitParams();
6133 params.profile_is_supervised = true;
6134 InitializeExtensionService(params);
6136 SupervisedUserService* supervised_user_service =
6137 SupervisedUserServiceFactory::GetForProfile(profile());
6138 GetManagementPolicy()->RegisterProvider(supervised_user_service);
6140 base::FilePath base_path = data_dir().AppendASCII("autoupdate");
6141 base::FilePath pem_path = base_path.AppendASCII("key.pem");
6143 base::FilePath path = base_path.AppendASCII("v1");
6144 const Extension* extension =
6145 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
6146 Extension::WAS_INSTALLED_BY_CUSTODIAN);
6147 // The extension must now be installed and enabled.
6148 ASSERT_TRUE(extension);
6149 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
6151 // Save the id, as the extension object will be destroyed during updating.
6152 std::string id = extension->id();
6154 std::string old_version = extension->VersionString();
6156 // Update to a new version.
6157 path = base_path.AppendASCII("v2");
6158 PackCRXAndUpdateExtension(id, path, pem_path, ENABLED);
6160 // The extension should still be there and enabled.
6161 extension = registry()->enabled_extensions().GetByID(id);
6162 ASSERT_TRUE(extension);
6163 // The version should have changed.
6164 EXPECT_NE(extension->VersionString(), old_version);
6167 TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithPermissionIncrease) {
6168 ExtensionServiceInitParams params = CreateDefaultInitParams();
6169 params.profile_is_supervised = true;
6170 InitializeExtensionService(params);
6172 SupervisedUserService* supervised_user_service =
6173 SupervisedUserServiceFactory::GetForProfile(profile());
6174 GetManagementPolicy()->RegisterProvider(supervised_user_service);
6176 base::FilePath base_path = data_dir().AppendASCII("permissions_increase");
6177 base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
6179 base::FilePath path = base_path.AppendASCII("v1");
6180 const Extension* extension =
6181 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
6182 Extension::WAS_INSTALLED_BY_CUSTODIAN);
6183 // The extension must now be installed and enabled.
6184 ASSERT_TRUE(extension);
6185 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
6187 // Save the id, as the extension object will be destroyed during updating.
6188 std::string id = extension->id();
6190 std::string old_version = extension->VersionString();
6192 // Update to a new version with increased permissions.
6193 path = base_path.AppendASCII("v2");
6194 PackCRXAndUpdateExtension(id, path, pem_path, DISABLED);
6196 // The extension should still be there, but disabled.
6197 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
6198 extension = registry()->disabled_extensions().GetByID(id);
6199 ASSERT_TRUE(extension);
6200 // The version should have changed.
6201 EXPECT_NE(extension->VersionString(), old_version);
6204 TEST_F(ExtensionServiceTest,
6205 SupervisedUser_SyncUninstallByCustodianSkipsPolicy) {
6206 InitializeEmptyExtensionService();
6207 InitializeExtensionSyncService();
6208 extension_sync_service()->MergeDataAndStartSyncing(
6209 syncer::EXTENSIONS,
6210 syncer::SyncDataList(),
6211 scoped_ptr<syncer::SyncChangeProcessor>(
6212 new syncer::FakeSyncChangeProcessor),
6213 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6215 // Install two extensions.
6216 base::FilePath path1 = data_dir().AppendASCII("good.crx");
6217 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
6218 const Extension* extensions[] = {
6219 InstallCRX(path1, INSTALL_NEW),
6220 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
6223 // Add a policy provider that will disallow any changes.
6224 extensions::TestManagementPolicyProvider provider(
6225 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
6226 GetManagementPolicy()->RegisterProvider(&provider);
6228 // Create a sync deletion for each extension.
6229 syncer::SyncChangeList change_list;
6230 for (size_t i = 0; i < arraysize(extensions); i++) {
6231 const std::string& id = extensions[i]->id();
6232 sync_pb::EntitySpecifics specifics;
6233 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6234 ext_specifics->set_id(id);
6235 ext_specifics->set_version("1.0");
6236 ext_specifics->set_installed_by_custodian(
6237 extensions[i]->was_installed_by_custodian());
6238 syncer::SyncData sync_data =
6239 syncer::SyncData::CreateLocalData(id, "Name", specifics);
6240 change_list.push_back(syncer::SyncChange(FROM_HERE,
6241 syncer::SyncChange::ACTION_DELETE,
6242 sync_data));
6245 // Save the extension ids, as uninstalling destroys the Extension instance.
6246 std::string extension_ids[] = {
6247 extensions[0]->id(),
6248 extensions[1]->id()
6251 // Now apply the uninstallations.
6252 extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
6254 // Uninstalling the extension without installed_by_custodian should have been
6255 // blocked by policy, so it should still be there.
6256 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_ids[0]));
6258 // But installed_by_custodian should result in bypassing the policy check.
6259 EXPECT_FALSE(
6260 registry()->GenerateInstalledExtensionsSet()->Contains(extension_ids[1]));
6262 #endif // defined(ENABLE_MANAGED_USERS)
6264 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
6265 InitializeEmptyExtensionService();
6267 base::FilePath path = data_dir().AppendASCII("good.crx");
6268 InstallCRX(path, INSTALL_NEW);
6269 ValidatePrefKeyCount(1u);
6270 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
6271 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
6273 extensions::PendingExtensionManager* pending =
6274 service()->pending_extension_manager();
6275 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6277 // Skip install when the location is the same.
6278 EXPECT_FALSE(
6279 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
6280 std::string(),
6281 GURL(kGoodUpdateURL),
6282 Manifest::INTERNAL,
6283 Extension::NO_FLAGS,
6284 false));
6285 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6287 // Install when the location has higher priority.
6288 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
6289 kGoodId,
6290 std::string(),
6291 GURL(kGoodUpdateURL),
6292 Manifest::EXTERNAL_POLICY_DOWNLOAD,
6293 Extension::NO_FLAGS,
6294 false));
6295 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6297 // Try the low priority again. Should be rejected.
6298 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(
6299 kGoodId,
6300 std::string(),
6301 GURL(kGoodUpdateURL),
6302 Manifest::EXTERNAL_PREF_DOWNLOAD,
6303 Extension::NO_FLAGS,
6304 false));
6305 // The existing record should still be present in the pending extension
6306 // manager.
6307 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6309 pending->Remove(kGoodId);
6311 // Skip install when the location has the same priority as the installed
6312 // location.
6313 EXPECT_FALSE(
6314 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
6315 std::string(),
6316 GURL(kGoodUpdateURL),
6317 Manifest::INTERNAL,
6318 Extension::NO_FLAGS,
6319 false));
6321 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6324 TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
6325 Version older_version("0.1.0.0");
6326 Version newer_version("2.0.0.0");
6328 // We don't want the extension to be installed. A path that doesn't
6329 // point to a valid CRX ensures this.
6330 const base::FilePath kInvalidPathToCrx = base::FilePath();
6332 const int kCreationFlags = 0;
6333 const bool kDontMarkAcknowledged = false;
6335 InitializeEmptyExtensionService();
6337 // The test below uses install source constants to test that
6338 // priority is enforced. It assumes a specific ranking of install
6339 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
6340 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
6341 // The following assertions verify these assumptions:
6342 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
6343 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
6344 Manifest::EXTERNAL_PREF));
6345 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
6346 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
6347 Manifest::INTERNAL));
6348 ASSERT_EQ(Manifest::EXTERNAL_PREF,
6349 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
6350 Manifest::INTERNAL));
6352 extensions::PendingExtensionManager* pending =
6353 service()->pending_extension_manager();
6354 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6357 // Simulate an external source adding the extension as INTERNAL.
6358 content::WindowedNotificationObserver observer(
6359 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6360 content::NotificationService::AllSources());
6361 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId,
6362 &older_version,
6363 kInvalidPathToCrx,
6364 Manifest::INTERNAL,
6365 kCreationFlags,
6366 kDontMarkAcknowledged));
6367 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6368 observer.Wait();
6369 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6373 // Simulate an external source adding the extension as EXTERNAL_PREF.
6374 content::WindowedNotificationObserver observer(
6375 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6376 content::NotificationService::AllSources());
6377 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId,
6378 &older_version,
6379 kInvalidPathToCrx,
6380 Manifest::EXTERNAL_PREF,
6381 kCreationFlags,
6382 kDontMarkAcknowledged));
6383 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6384 observer.Wait();
6385 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6388 // Simulate an external source adding as EXTERNAL_PREF again.
6389 // This is rejected because the version and the location are the same as
6390 // the previous installation, which is still pending.
6391 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId,
6392 &older_version,
6393 kInvalidPathToCrx,
6394 Manifest::EXTERNAL_PREF,
6395 kCreationFlags,
6396 kDontMarkAcknowledged));
6397 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6399 // Try INTERNAL again. Should fail.
6400 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId,
6401 &older_version,
6402 kInvalidPathToCrx,
6403 Manifest::INTERNAL,
6404 kCreationFlags,
6405 kDontMarkAcknowledged));
6406 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6409 // Now the registry adds the extension.
6410 content::WindowedNotificationObserver observer(
6411 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6412 content::NotificationService::AllSources());
6413 EXPECT_TRUE(
6414 service()->OnExternalExtensionFileFound(kGoodId,
6415 &older_version,
6416 kInvalidPathToCrx,
6417 Manifest::EXTERNAL_REGISTRY,
6418 kCreationFlags,
6419 kDontMarkAcknowledged));
6420 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6421 observer.Wait();
6422 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6425 // Registry outranks both external pref and internal, so both fail.
6426 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId,
6427 &older_version,
6428 kInvalidPathToCrx,
6429 Manifest::EXTERNAL_PREF,
6430 kCreationFlags,
6431 kDontMarkAcknowledged));
6432 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6434 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId,
6435 &older_version,
6436 kInvalidPathToCrx,
6437 Manifest::INTERNAL,
6438 kCreationFlags,
6439 kDontMarkAcknowledged));
6440 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6442 pending->Remove(kGoodId);
6444 // Install the extension.
6445 base::FilePath path = data_dir().AppendASCII("good.crx");
6446 const Extension* ext = InstallCRX(path, INSTALL_NEW);
6447 ValidatePrefKeyCount(1u);
6448 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
6449 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
6451 // Now test the logic of OnExternalExtensionFileFound() when the extension
6452 // being added is already installed.
6454 // Tests assume |older_version| is less than the installed version, and
6455 // |newer_version| is greater. Verify this:
6456 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
6457 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
6459 // An external install for the same location should fail if the version is
6460 // older, or the same, and succeed if the version is newer.
6462 // Older than the installed version...
6463 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId,
6464 &older_version,
6465 kInvalidPathToCrx,
6466 Manifest::INTERNAL,
6467 kCreationFlags,
6468 kDontMarkAcknowledged));
6469 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6471 // Same version as the installed version...
6472 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId,
6473 ext->version(),
6474 kInvalidPathToCrx,
6475 Manifest::INTERNAL,
6476 kCreationFlags,
6477 kDontMarkAcknowledged));
6478 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6480 // Newer than the installed version...
6481 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId,
6482 &newer_version,
6483 kInvalidPathToCrx,
6484 Manifest::INTERNAL,
6485 kCreationFlags,
6486 kDontMarkAcknowledged));
6487 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6489 // An external install for a higher priority install source should succeed
6490 // if the version is greater. |older_version| is not...
6491 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId,
6492 &older_version,
6493 kInvalidPathToCrx,
6494 Manifest::EXTERNAL_PREF,
6495 kCreationFlags,
6496 kDontMarkAcknowledged));
6497 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6499 // |newer_version| is newer.
6500 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId,
6501 &newer_version,
6502 kInvalidPathToCrx,
6503 Manifest::EXTERNAL_PREF,
6504 kCreationFlags,
6505 kDontMarkAcknowledged));
6506 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6508 // An external install for an even higher priority install source should
6509 // succeed if the version is greater.
6510 EXPECT_TRUE(
6511 service()->OnExternalExtensionFileFound(kGoodId,
6512 &newer_version,
6513 kInvalidPathToCrx,
6514 Manifest::EXTERNAL_REGISTRY,
6515 kCreationFlags,
6516 kDontMarkAcknowledged));
6517 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6519 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
6520 // adding from external pref will now fail.
6521 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId,
6522 &newer_version,
6523 kInvalidPathToCrx,
6524 Manifest::EXTERNAL_PREF,
6525 kCreationFlags,
6526 kDontMarkAcknowledged));
6527 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6530 TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
6531 Version kVersion123("1.2.3");
6532 Version kVersion124("1.2.4");
6533 Version kVersion125("1.2.5");
6534 const base::FilePath kInvalidPathToCrx = base::FilePath();
6535 const int kCreationFlags = 0;
6536 const bool kDontMarkAcknowledged = false;
6538 InitializeEmptyExtensionService();
6540 extensions::PendingExtensionManager* pending =
6541 service()->pending_extension_manager();
6542 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6544 // An external provider starts installing from a local crx.
6545 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId,
6546 &kVersion123,
6547 kInvalidPathToCrx,
6548 Manifest::EXTERNAL_PREF,
6549 kCreationFlags,
6550 kDontMarkAcknowledged));
6551 const extensions::PendingExtensionInfo* info;
6552 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6553 EXPECT_TRUE(info->version().IsValid());
6554 EXPECT_TRUE(info->version().Equals(kVersion123));
6556 // Adding a newer version overrides the currently pending version.
6557 EXPECT_TRUE(service()->OnExternalExtensionFileFound(kGoodId,
6558 &kVersion124,
6559 kInvalidPathToCrx,
6560 Manifest::EXTERNAL_PREF,
6561 kCreationFlags,
6562 kDontMarkAcknowledged));
6563 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6564 EXPECT_TRUE(info->version().IsValid());
6565 EXPECT_TRUE(info->version().Equals(kVersion124));
6567 // Adding an older version fails.
6568 EXPECT_FALSE(service()->OnExternalExtensionFileFound(kGoodId,
6569 &kVersion123,
6570 kInvalidPathToCrx,
6571 Manifest::EXTERNAL_PREF,
6572 kCreationFlags,
6573 kDontMarkAcknowledged));
6574 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6575 EXPECT_TRUE(info->version().IsValid());
6576 EXPECT_TRUE(info->version().Equals(kVersion124));
6578 // Adding an older version fails even when coming from a higher-priority
6579 // location.
6580 EXPECT_FALSE(
6581 service()->OnExternalExtensionFileFound(kGoodId,
6582 &kVersion123,
6583 kInvalidPathToCrx,
6584 Manifest::EXTERNAL_REGISTRY,
6585 kCreationFlags,
6586 kDontMarkAcknowledged));
6587 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6588 EXPECT_TRUE(info->version().IsValid());
6589 EXPECT_TRUE(info->version().Equals(kVersion124));
6591 // Adding the latest version from the webstore overrides a specific version.
6592 GURL kUpdateUrl("http://example.com/update");
6593 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
6594 kGoodId,
6595 std::string(),
6596 kUpdateUrl,
6597 Manifest::EXTERNAL_POLICY_DOWNLOAD,
6598 Extension::NO_FLAGS,
6599 false));
6600 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6601 EXPECT_FALSE(info->version().IsValid());
6604 // This makes sure we can package and install CRX files that use whitelisted
6605 // permissions.
6606 TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
6607 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
6608 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6609 extensions::switches::kWhitelistedExtensionID, test_id);
6611 InitializeEmptyExtensionService();
6612 base::FilePath path = data_dir().AppendASCII("permissions");
6613 base::FilePath pem_path = path
6614 .AppendASCII("whitelist.pem");
6615 path = path
6616 .AppendASCII("whitelist");
6618 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
6619 EXPECT_EQ(0u, GetErrors().size());
6620 ASSERT_EQ(1u, registry()->enabled_extensions().size());
6621 EXPECT_EQ(test_id, extension->id());
6624 // Test that when multiple sources try to install an extension,
6625 // we consistently choose the right one. To make tests easy to read,
6626 // methods that fake requests to install crx files in several ways
6627 // are provided.
6628 class ExtensionSourcePriorityTest : public ExtensionServiceTest {
6629 public:
6630 virtual void SetUp() {
6631 ExtensionServiceTest::SetUp();
6633 // All tests use a single extension. Put the id and path in member vars
6634 // that all methods can read.
6635 crx_id_ = kGoodId;
6636 crx_path_ = data_dir().AppendASCII("good.crx");
6639 // Fake an external source adding a URL to fetch an extension from.
6640 bool AddPendingExternalPrefUrl() {
6641 return service()->pending_extension_manager()->AddFromExternalUpdateUrl(
6642 crx_id_,
6643 std::string(),
6644 GURL(),
6645 Manifest::EXTERNAL_PREF_DOWNLOAD,
6646 Extension::NO_FLAGS,
6647 false);
6650 // Fake an external file from external_extensions.json.
6651 bool AddPendingExternalPrefFileInstall() {
6652 Version version("1.0.0.0");
6654 return service()->OnExternalExtensionFileFound(crx_id_,
6655 &version,
6656 crx_path_,
6657 Manifest::EXTERNAL_PREF,
6658 Extension::NO_FLAGS,
6659 false);
6662 // Fake a request from sync to install an extension.
6663 bool AddPendingSyncInstall() {
6664 return service()->pending_extension_manager()->AddFromSync(
6665 crx_id_,
6666 GURL(kGoodUpdateURL),
6667 &IsExtension,
6668 kGoodRemoteInstall,
6669 kGoodInstalledByCustodian);
6672 // Fake a policy install.
6673 bool AddPendingPolicyInstall() {
6674 // Get path to the CRX with id |kGoodId|.
6675 return service()->OnExternalExtensionUpdateUrlFound(
6676 crx_id_,
6677 std::string(),
6678 GURL(),
6679 Manifest::EXTERNAL_POLICY_DOWNLOAD,
6680 Extension::NO_FLAGS,
6681 false);
6684 // Get the install source of a pending extension.
6685 Manifest::Location GetPendingLocation() {
6686 const extensions::PendingExtensionInfo* info;
6687 EXPECT_TRUE(
6688 (info = service()->pending_extension_manager()->GetById(crx_id_)));
6689 return info->install_source();
6692 // Is an extension pending from a sync request?
6693 bool GetPendingIsFromSync() {
6694 const extensions::PendingExtensionInfo* info;
6695 EXPECT_TRUE(
6696 (info = service()->pending_extension_manager()->GetById(crx_id_)));
6697 return info->is_from_sync();
6700 // Is the CRX id these tests use pending?
6701 bool IsCrxPending() {
6702 return service()->pending_extension_manager()->IsIdPending(crx_id_);
6705 // Is an extension installed?
6706 bool IsCrxInstalled() {
6707 return (service()->GetExtensionById(crx_id_, true) != NULL);
6710 protected:
6711 // All tests use a single extension. Making the id and path member
6712 // vars avoids pasing the same argument to every method.
6713 std::string crx_id_;
6714 base::FilePath crx_path_;
6717 // Test that a pending request for installation of an external CRX from
6718 // an update URL overrides a pending request to install the same extension
6719 // from sync.
6720 TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
6721 InitializeEmptyExtensionService();
6723 ASSERT_FALSE(IsCrxInstalled());
6725 // Install pending extension from sync.
6726 content::WindowedNotificationObserver observer(
6727 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6728 content::NotificationService::AllSources());
6729 EXPECT_TRUE(AddPendingSyncInstall());
6730 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
6731 EXPECT_TRUE(GetPendingIsFromSync());
6732 ASSERT_FALSE(IsCrxInstalled());
6734 // Install pending as external prefs json would.
6735 AddPendingExternalPrefFileInstall();
6736 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
6737 ASSERT_FALSE(IsCrxInstalled());
6739 // Another request from sync should be ignored.
6740 EXPECT_FALSE(AddPendingSyncInstall());
6741 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
6742 ASSERT_FALSE(IsCrxInstalled());
6744 observer.Wait();
6745 VerifyCrxInstall(crx_path_, INSTALL_NEW);
6746 ASSERT_TRUE(IsCrxInstalled());
6749 // Test that an install of an external CRX from an update overrides
6750 // an install of the same extension from sync.
6751 TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
6752 InitializeEmptyExtensionService();
6753 ASSERT_FALSE(IsCrxInstalled());
6755 EXPECT_TRUE(AddPendingSyncInstall());
6756 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
6757 EXPECT_TRUE(GetPendingIsFromSync());
6758 ASSERT_FALSE(IsCrxInstalled());
6760 ASSERT_TRUE(AddPendingExternalPrefUrl());
6761 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
6762 EXPECT_FALSE(GetPendingIsFromSync());
6763 ASSERT_FALSE(IsCrxInstalled());
6765 EXPECT_FALSE(AddPendingSyncInstall());
6766 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
6767 EXPECT_FALSE(GetPendingIsFromSync());
6768 ASSERT_FALSE(IsCrxInstalled());
6771 // Test that an external install request stops sync from installing
6772 // the same extension.
6773 TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
6774 InitializeEmptyExtensionService();
6775 ASSERT_FALSE(IsCrxInstalled());
6777 // External prefs starts an install.
6778 AddPendingExternalPrefFileInstall();
6780 // Crx installer was made, but has not yet run.
6781 ASSERT_FALSE(IsCrxInstalled());
6783 // Before the CRX installer runs, Sync requests that the same extension
6784 // be installed. Should fail, because an external source is pending.
6785 content::WindowedNotificationObserver observer(
6786 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6787 content::NotificationService::AllSources());
6788 ASSERT_FALSE(AddPendingSyncInstall());
6790 // Wait for the external source to install.
6791 observer.Wait();
6792 VerifyCrxInstall(crx_path_, INSTALL_NEW);
6793 ASSERT_TRUE(IsCrxInstalled());
6795 // Now that the extension is installed, sync request should fail
6796 // because the extension is already installed.
6797 ASSERT_FALSE(AddPendingSyncInstall());
6800 // Test that installing an external extension displays a GlobalError.
6801 TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
6802 FeatureSwitch::ScopedOverride prompt(
6803 FeatureSwitch::prompt_for_external_extensions(), true);
6805 InitializeEmptyExtensionService();
6806 MockExtensionProvider* provider =
6807 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
6808 AddMockExternalProvider(provider);
6810 service()->external_install_manager()->UpdateExternalExtensionAlert();
6811 // Should return false, meaning there aren't any extensions that the user
6812 // needs to know about.
6813 EXPECT_FALSE(
6814 service()->external_install_manager()->HasExternalInstallError());
6816 // This is a normal extension, installed normally.
6817 // This should NOT trigger an alert.
6818 service()->set_extensions_enabled(true);
6819 base::FilePath path = data_dir().AppendASCII("good.crx");
6820 InstallCRX(path, INSTALL_NEW);
6822 service()->CheckForExternalUpdates();
6823 base::RunLoop().RunUntilIdle();
6824 EXPECT_FALSE(
6825 service()->external_install_manager()->HasExternalInstallError());
6827 // A hosted app, installed externally.
6828 // This should NOT trigger an alert.
6829 provider->UpdateOrAddExtension(
6830 hosted_app, "1.0.0.0", data_dir().AppendASCII("hosted_app.crx"));
6832 content::WindowedNotificationObserver observer(
6833 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6834 content::NotificationService::AllSources());
6835 service()->CheckForExternalUpdates();
6836 observer.Wait();
6837 EXPECT_FALSE(
6838 service()->external_install_manager()->HasExternalInstallError());
6840 // Another normal extension, but installed externally.
6841 // This SHOULD trigger an alert.
6842 provider->UpdateOrAddExtension(
6843 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
6845 content::WindowedNotificationObserver observer2(
6846 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6847 content::NotificationService::AllSources());
6848 service()->CheckForExternalUpdates();
6849 observer2.Wait();
6850 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
6853 // Test that external extensions are initially disabled, and that enabling
6854 // them clears the prompt.
6855 TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
6856 FeatureSwitch::ScopedOverride prompt(
6857 FeatureSwitch::prompt_for_external_extensions(), true);
6859 InitializeEmptyExtensionService();
6860 MockExtensionProvider* provider =
6861 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
6862 AddMockExternalProvider(provider);
6864 provider->UpdateOrAddExtension(
6865 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
6867 content::WindowedNotificationObserver observer(
6868 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6869 content::NotificationService::AllSources());
6870 service()->CheckForExternalUpdates();
6871 observer.Wait();
6872 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
6873 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
6875 const Extension* extension =
6876 registry()->disabled_extensions().GetByID(page_action);
6877 EXPECT_TRUE(extension);
6878 EXPECT_EQ(page_action, extension->id());
6880 service()->EnableExtension(page_action);
6881 EXPECT_FALSE(
6882 service()->external_install_manager()->HasExternalInstallError());
6883 EXPECT_TRUE(service()->IsExtensionEnabled(page_action));
6886 // Test that installing multiple external extensions works.
6887 // Flaky on windows; http://crbug.com/295757 .
6888 #if defined(OS_WIN)
6889 #define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
6890 #else
6891 #define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
6892 #endif
6893 TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
6894 FeatureSwitch::ScopedOverride prompt(
6895 FeatureSwitch::prompt_for_external_extensions(), true);
6897 InitializeEmptyExtensionService();
6898 MockExtensionProvider* provider =
6899 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
6900 AddMockExternalProvider(provider);
6902 provider->UpdateOrAddExtension(
6903 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
6904 provider->UpdateOrAddExtension(
6905 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
6906 provider->UpdateOrAddExtension(
6907 theme_crx, "2.0", data_dir().AppendASCII("theme.crx"));
6909 int count = 3;
6910 content::WindowedNotificationObserver observer(
6911 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6912 base::Bind(&WaitForCountNotificationsCallback, &count));
6913 service()->CheckForExternalUpdates();
6914 observer.Wait();
6915 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
6916 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
6917 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6918 EXPECT_FALSE(service()->IsExtensionEnabled(theme_crx));
6920 service()->EnableExtension(page_action);
6921 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
6922 EXPECT_FALSE(service()
6923 ->external_install_manager()
6924 ->HasExternalInstallBubbleForTesting());
6926 service()->EnableExtension(theme_crx);
6927 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
6928 EXPECT_FALSE(service()
6929 ->external_install_manager()
6930 ->HasExternalInstallBubbleForTesting());
6932 service()->EnableExtension(good_crx);
6933 EXPECT_FALSE(
6934 service()->external_install_manager()->HasExternalInstallError());
6935 EXPECT_FALSE(service()
6936 ->external_install_manager()
6937 ->HasExternalInstallBubbleForTesting());
6940 // Test that there is a bubble for external extensions that update
6941 // from the webstore if the profile is not new.
6942 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
6943 FeatureSwitch::ScopedOverride prompt(
6944 FeatureSwitch::prompt_for_external_extensions(), true);
6946 // This sets up the ExtensionPrefs used by our ExtensionService to be
6947 // post-first run.
6948 ExtensionServiceInitParams params = CreateDefaultInitParams();
6949 params.is_first_run = false;
6950 InitializeExtensionService(params);
6952 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
6953 PackCRX(data_dir().AppendASCII("update_from_webstore"),
6954 data_dir().AppendASCII("update_from_webstore.pem"),
6955 crx_path);
6957 MockExtensionProvider* provider =
6958 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
6959 AddMockExternalProvider(provider);
6960 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
6962 content::WindowedNotificationObserver observer(
6963 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6964 content::NotificationService::AllSources());
6965 service()->CheckForExternalUpdates();
6966 observer.Wait();
6967 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
6968 EXPECT_TRUE(service()
6969 ->external_install_manager()
6970 ->HasExternalInstallBubbleForTesting());
6971 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
6974 // Test that there is no bubble for external extensions if the profile is new.
6975 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
6976 FeatureSwitch::ScopedOverride prompt(
6977 FeatureSwitch::prompt_for_external_extensions(), true);
6979 InitializeEmptyExtensionService();
6981 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
6982 PackCRX(data_dir().AppendASCII("update_from_webstore"),
6983 data_dir().AppendASCII("update_from_webstore.pem"),
6984 crx_path);
6986 MockExtensionProvider* provider =
6987 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
6988 AddMockExternalProvider(provider);
6989 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
6991 content::WindowedNotificationObserver observer(
6992 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
6993 content::NotificationService::AllSources());
6994 service()->CheckForExternalUpdates();
6995 observer.Wait();
6996 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
6997 EXPECT_FALSE(service()
6998 ->external_install_manager()
6999 ->HasExternalInstallBubbleForTesting());
7000 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7003 // Test that clicking to remove the extension on an external install warning
7004 // uninstalls the extension.
7005 TEST_F(ExtensionServiceTest, ExternalInstallClickToRemove) {
7006 FeatureSwitch::ScopedOverride prompt(
7007 FeatureSwitch::prompt_for_external_extensions(), true);
7009 ExtensionServiceInitParams params = CreateDefaultInitParams();
7010 params.is_first_run = false;
7011 InitializeExtensionService(params);
7013 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7014 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7015 data_dir().AppendASCII("update_from_webstore.pem"),
7016 crx_path);
7018 MockExtensionProvider* provider =
7019 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
7020 AddMockExternalProvider(provider);
7021 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7023 content::WindowedNotificationObserver observer(
7024 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7025 content::NotificationService::AllSources());
7026 service_->CheckForExternalUpdates();
7027 observer.Wait();
7028 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
7030 // We check both enabled and disabled, since these are "eventually exclusive"
7031 // sets.
7032 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
7033 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7035 // Click the negative response.
7036 service_->external_install_manager()->error_for_testing()->InstallUIAbort(
7037 true);
7038 // The Extension should be uninstalled.
7039 EXPECT_FALSE(registry()->GetExtensionById(updates_from_webstore,
7040 ExtensionRegistry::EVERYTHING));
7041 // The error should be removed.
7042 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
7045 // Test that clicking to keep the extension on an external install warning
7046 // re-enables the extension.
7047 TEST_F(ExtensionServiceTest, ExternalInstallClickToKeep) {
7048 FeatureSwitch::ScopedOverride prompt(
7049 FeatureSwitch::prompt_for_external_extensions(), true);
7051 ExtensionServiceInitParams params = CreateDefaultInitParams();
7052 params.is_first_run = false;
7053 InitializeExtensionService(params);
7055 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7056 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7057 data_dir().AppendASCII("update_from_webstore.pem"),
7058 crx_path);
7060 MockExtensionProvider* provider =
7061 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
7062 AddMockExternalProvider(provider);
7063 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7065 content::WindowedNotificationObserver observer(
7066 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7067 content::NotificationService::AllSources());
7068 service_->CheckForExternalUpdates();
7069 observer.Wait();
7070 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
7072 // We check both enabled and disabled, since these are "eventually exclusive"
7073 // sets.
7074 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
7075 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7077 // Accept the extension.
7078 service_->external_install_manager()->error_for_testing()->InstallUIProceed();
7080 // It should be enabled again.
7081 EXPECT_TRUE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7082 EXPECT_FALSE(
7083 registry()->disabled_extensions().GetByID(updates_from_webstore));
7085 // The error should be removed.
7086 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
7089 TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) {
7090 InitializeEmptyExtensionService();
7092 scoped_refptr<Extension> extension = extensions::ExtensionBuilder()
7093 .SetManifest(extensions::DictionaryBuilder()
7094 .Set("name", "extension")
7095 .Set("version", "1.0")
7096 .Set("manifest_version", 2).Build())
7097 .Build();
7098 ASSERT_TRUE(extension.get());
7099 const std::string& id = extension->id();
7101 std::set<std::string> id_set;
7102 id_set.insert(id);
7103 extensions::ExtensionNotificationObserver notifications(
7104 content::NotificationService::AllSources(), id_set);
7106 // Installation should be allowed but the extension should never have been
7107 // loaded and it should be blacklisted in prefs.
7108 service()->OnExtensionInstalled(
7109 extension.get(),
7110 syncer::StringOrdinal(),
7111 (extensions::kInstallFlagIsBlacklistedForMalware |
7112 extensions::kInstallFlagInstallImmediately));
7113 base::RunLoop().RunUntilIdle();
7115 // Extension was installed but not loaded.
7116 EXPECT_TRUE(notifications.CheckNotifications(
7117 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED));
7118 EXPECT_TRUE(service()->GetInstalledExtension(id));
7120 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7121 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(id));
7123 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlacklisted(id));
7124 EXPECT_TRUE(
7125 ExtensionPrefs::Get(profile())->IsBlacklistedExtensionAcknowledged(id));
7128 // Tests a profile being destroyed correctly disables extensions.
7129 TEST_F(ExtensionServiceTest, DestroyingProfileClearsExtensions) {
7130 InitializeEmptyExtensionService();
7132 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
7133 EXPECT_NE(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
7134 EXPECT_EQ(1u, registry()->enabled_extensions().size());
7135 EXPECT_EQ(0u, registry()->disabled_extensions().size());
7136 EXPECT_EQ(0u, registry()->terminated_extensions().size());
7137 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
7139 service()->Observe(chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
7140 content::Source<Profile>(profile()),
7141 content::NotificationService::NoDetails());
7142 EXPECT_EQ(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
7143 EXPECT_EQ(0u, registry()->enabled_extensions().size());
7144 EXPECT_EQ(0u, registry()->disabled_extensions().size());
7145 EXPECT_EQ(0u, registry()->terminated_extensions().size());
7146 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());