Remove ExtensionPrefs::SetDidExtensionEscalatePermissions.
[chromium-blink-merge.git] / chrome / browser / extensions / extension_service_unittest.cc
blob919f925b850cb99871f49fcaad7dadaa5906fe97
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/permissions_updater.h"
59 #include "chrome/browser/extensions/test_blacklist.h"
60 #include "chrome/browser/extensions/test_extension_system.h"
61 #include "chrome/browser/extensions/unpacked_installer.h"
62 #include "chrome/browser/extensions/updater/extension_updater.h"
63 #include "chrome/browser/prefs/pref_service_syncable.h"
64 #include "chrome/browser/sync/profile_sync_service.h"
65 #include "chrome/browser/sync/profile_sync_service_factory.h"
66 #include "chrome/common/chrome_constants.h"
67 #include "chrome/common/chrome_switches.h"
68 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
69 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
70 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
71 #include "chrome/common/pref_names.h"
72 #include "chrome/common/url_constants.h"
73 #include "chrome/test/base/scoped_browser_locale.h"
74 #include "chrome/test/base/testing_pref_service_syncable.h"
75 #include "chrome/test/base/testing_profile.h"
76 #include "components/crx_file/id_util.h"
77 #include "components/pref_registry/pref_registry_syncable.h"
78 #include "content/public/browser/dom_storage_context.h"
79 #include "content/public/browser/gpu_data_manager.h"
80 #include "content/public/browser/indexed_db_context.h"
81 #include "content/public/browser/notification_registrar.h"
82 #include "content/public/browser/notification_service.h"
83 #include "content/public/browser/plugin_service.h"
84 #include "content/public/browser/render_process_host.h"
85 #include "content/public/browser/storage_partition.h"
86 #include "content/public/common/content_constants.h"
87 #include "content/public/test/test_browser_thread_bundle.h"
88 #include "content/public/test/test_utils.h"
89 #include "extensions/browser/extension_prefs.h"
90 #include "extensions/browser/extension_registry.h"
91 #include "extensions/browser/extension_system.h"
92 #include "extensions/browser/external_provider_interface.h"
93 #include "extensions/browser/install_flag.h"
94 #include "extensions/browser/management_policy.h"
95 #include "extensions/browser/test_management_policy.h"
96 #include "extensions/browser/uninstall_reason.h"
97 #include "extensions/common/constants.h"
98 #include "extensions/common/extension.h"
99 #include "extensions/common/extension_builder.h"
100 #include "extensions/common/extension_l10n_util.h"
101 #include "extensions/common/extension_resource.h"
102 #include "extensions/common/feature_switch.h"
103 #include "extensions/common/manifest_constants.h"
104 #include "extensions/common/manifest_handlers/background_info.h"
105 #include "extensions/common/manifest_handlers/permissions_parser.h"
106 #include "extensions/common/manifest_url_handlers.h"
107 #include "extensions/common/permissions/permission_set.h"
108 #include "extensions/common/permissions/permissions_data.h"
109 #include "extensions/common/switches.h"
110 #include "extensions/common/url_pattern.h"
111 #include "extensions/common/value_builder.h"
112 #include "gpu/config/gpu_info.h"
113 #include "grit/browser_resources.h"
114 #include "grit/generated_resources.h"
115 #include "net/cookies/canonical_cookie.h"
116 #include "net/cookies/cookie_monster.h"
117 #include "net/cookies/cookie_options.h"
118 #include "net/url_request/url_request_context.h"
119 #include "net/url_request/url_request_context_getter.h"
120 #include "storage/browser/database/database_tracker.h"
121 #include "storage/browser/quota/quota_manager.h"
122 #include "storage/common/database/database_identifier.h"
123 #include "sync/api/fake_sync_change_processor.h"
124 #include "sync/api/string_ordinal.h"
125 #include "sync/api/sync_data.h"
126 #include "sync/api/sync_error_factory.h"
127 #include "sync/api/sync_error_factory_mock.h"
128 #include "sync/api/syncable_service.h"
129 #include "sync/protocol/app_specifics.pb.h"
130 #include "sync/protocol/extension_specifics.pb.h"
131 #include "sync/protocol/sync.pb.h"
132 #include "testing/gtest/include/gtest/gtest.h"
133 #include "testing/platform_test.h"
134 #include "ui/base/l10n/l10n_util.h"
135 #include "url/gurl.h"
137 #if defined(ENABLE_SUPERVISED_USERS)
138 #include "chrome/browser/supervised_user/permission_request_creator.h"
139 #include "chrome/browser/supervised_user/supervised_user_constants.h"
140 #include "chrome/browser/supervised_user/supervised_user_service.h"
141 #include "chrome/browser/supervised_user/supervised_user_service_factory.h"
142 #endif
144 #if defined(OS_CHROMEOS)
145 #include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
146 #include "chrome/browser/chromeos/settings/cros_settings.h"
147 #include "chrome/browser/chromeos/settings/device_settings_service.h"
148 #endif
150 // The blacklist tests rely on the safe-browsing database.
151 #if defined(SAFE_BROWSING_DB_LOCAL)
152 #define ENABLE_BLACKLIST_TESTS
153 #endif
155 using base::DictionaryValue;
156 using base::ListValue;
157 using base::Value;
158 using content::BrowserContext;
159 using content::BrowserThread;
160 using content::DOMStorageContext;
161 using content::IndexedDBContext;
162 using content::PluginService;
163 using extensions::APIPermission;
164 using extensions::APIPermissionSet;
165 using extensions::AppSorting;
166 using extensions::AppSyncData;
167 using extensions::Blacklist;
168 using extensions::CrxInstaller;
169 using extensions::Extension;
170 using extensions::ExtensionCreator;
171 using extensions::ExtensionPrefs;
172 using extensions::ExtensionRegistry;
173 using extensions::ExtensionResource;
174 using extensions::ExtensionSyncData;
175 using extensions::ExtensionSystem;
176 using extensions::FakeSafeBrowsingDatabaseManager;
177 using extensions::FeatureSwitch;
178 using extensions::Manifest;
179 using extensions::PermissionSet;
180 using extensions::TestExtensionSystem;
181 using extensions::UnloadedExtensionInfo;
182 using extensions::URLPatternSet;
184 namespace keys = extensions::manifest_keys;
186 namespace {
188 // Extension ids used during testing.
189 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
190 const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
191 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
192 const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
193 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
194 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
195 const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
196 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
197 const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad";
198 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
199 const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
200 const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
201 const char permissions_blocklist[] = "noffkehfcaggllbcojjbopcmlhcnhcdn";
203 struct ExtensionsOrder {
204 bool operator()(const scoped_refptr<const Extension>& a,
205 const scoped_refptr<const Extension>& b) {
206 return a->name() < b->name();
210 static std::vector<base::string16> GetErrors() {
211 const std::vector<base::string16>* errors =
212 ExtensionErrorReporter::GetInstance()->GetErrors();
213 std::vector<base::string16> ret_val;
215 for (std::vector<base::string16>::const_iterator iter = errors->begin();
216 iter != errors->end(); ++iter) {
217 std::string utf8_error = base::UTF16ToUTF8(*iter);
218 if (utf8_error.find(".svn") == std::string::npos) {
219 ret_val.push_back(*iter);
223 // The tests rely on the errors being in a certain order, which can vary
224 // depending on how filesystem iteration works.
225 std::stable_sort(ret_val.begin(), ret_val.end());
227 return ret_val;
230 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
231 int schemes = URLPattern::SCHEME_ALL;
232 extent->AddPattern(URLPattern(schemes, pattern));
235 base::FilePath GetTemporaryFile() {
236 base::FilePath temp_file;
237 CHECK(base::CreateTemporaryFile(&temp_file));
238 return temp_file;
241 bool WaitForCountNotificationsCallback(int *count) {
242 return --(*count) == 0;
245 } // namespace
247 class MockExtensionProvider : public extensions::ExternalProviderInterface {
248 public:
249 MockExtensionProvider(
250 VisitorInterface* visitor,
251 Manifest::Location location)
252 : location_(location), visitor_(visitor), visit_count_(0) {
255 ~MockExtensionProvider() override {}
257 void UpdateOrAddExtension(const std::string& id,
258 const std::string& version,
259 const base::FilePath& path) {
260 extension_map_[id] = std::make_pair(version, path);
263 void RemoveExtension(const std::string& id) {
264 extension_map_.erase(id);
267 // ExternalProvider implementation:
268 void VisitRegisteredExtension() override {
269 visit_count_++;
270 for (DataMap::const_iterator i = extension_map_.begin();
271 i != extension_map_.end(); ++i) {
272 Version version(i->second.first);
274 visitor_->OnExternalExtensionFileFound(
275 i->first, &version, i->second.second, location_,
276 Extension::NO_FLAGS, false, false);
278 visitor_->OnExternalProviderReady(this);
281 bool HasExtension(const std::string& id) const override {
282 return extension_map_.find(id) != extension_map_.end();
285 bool GetExtensionDetails(const std::string& id,
286 Manifest::Location* location,
287 scoped_ptr<Version>* version) const override {
288 DataMap::const_iterator it = extension_map_.find(id);
289 if (it == extension_map_.end())
290 return false;
292 if (version)
293 version->reset(new Version(it->second.first));
295 if (location)
296 *location = location_;
298 return true;
301 bool IsReady() const override { return true; }
303 void ServiceShutdown() override {}
305 int visit_count() const { return visit_count_; }
306 void set_visit_count(int visit_count) {
307 visit_count_ = visit_count;
310 private:
311 typedef std::map< std::string, std::pair<std::string, base::FilePath> >
312 DataMap;
313 DataMap extension_map_;
314 Manifest::Location location_;
315 VisitorInterface* visitor_;
317 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
318 // Mutable because it must be incremented on each call to
319 // VisitRegisteredExtension(), which must be a const method to inherit
320 // from the class being mocked.
321 mutable int visit_count_;
323 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
326 class MockProviderVisitor
327 : public extensions::ExternalProviderInterface::VisitorInterface {
328 public:
329 // The provider will return |fake_base_path| from
330 // GetBaseCrxFilePath(). User can test the behavior with
331 // and without an empty path using this parameter.
332 explicit MockProviderVisitor(base::FilePath fake_base_path)
333 : ids_found_(0),
334 fake_base_path_(fake_base_path),
335 expected_creation_flags_(Extension::NO_FLAGS) {
336 profile_.reset(new TestingProfile);
339 MockProviderVisitor(base::FilePath fake_base_path,
340 int expected_creation_flags)
341 : ids_found_(0),
342 fake_base_path_(fake_base_path),
343 expected_creation_flags_(expected_creation_flags) {
346 int Visit(const std::string& json_data) {
347 // Give the test json file to the provider for parsing.
348 provider_.reset(new extensions::ExternalProviderImpl(
349 this,
350 new extensions::ExternalTestingLoader(json_data, fake_base_path_),
351 profile_.get(),
352 Manifest::EXTERNAL_PREF,
353 Manifest::EXTERNAL_PREF_DOWNLOAD,
354 Extension::NO_FLAGS));
356 // We also parse the file into a dictionary to compare what we get back
357 // from the provider.
358 JSONStringValueDeserializer deserializer(json_data);
359 base::Value* json_value = deserializer.Deserialize(NULL, NULL);
361 if (!json_value || !json_value->IsType(base::Value::TYPE_DICTIONARY)) {
362 NOTREACHED() << "Unable to deserialize json data";
363 return -1;
364 } else {
365 base::DictionaryValue* external_extensions =
366 static_cast<base::DictionaryValue*>(json_value);
367 prefs_.reset(external_extensions);
370 // Reset our counter.
371 ids_found_ = 0;
372 // Ask the provider to look up all extensions and return them.
373 provider_->VisitRegisteredExtension();
375 return ids_found_;
378 bool OnExternalExtensionFileFound(const std::string& id,
379 const Version* version,
380 const base::FilePath& path,
381 Manifest::Location unused,
382 int creation_flags,
383 bool mark_acknowledged,
384 bool install_immediately) override {
385 EXPECT_EQ(expected_creation_flags_, creation_flags);
387 ++ids_found_;
388 base::DictionaryValue* pref;
389 // This tests is to make sure that the provider only notifies us of the
390 // values we gave it. So if the id we doesn't exist in our internal
391 // dictionary then something is wrong.
392 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
393 << "Got back ID (" << id.c_str() << ") we weren't expecting";
395 EXPECT_TRUE(path.IsAbsolute());
396 if (!fake_base_path_.empty())
397 EXPECT_TRUE(fake_base_path_.IsParent(path));
399 if (pref) {
400 EXPECT_TRUE(provider_->HasExtension(id));
402 // Ask provider if the extension we got back is registered.
403 Manifest::Location location = Manifest::INVALID_LOCATION;
404 scoped_ptr<Version> v1;
405 base::FilePath crx_path;
407 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
408 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
410 scoped_ptr<Version> v2;
411 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
412 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
413 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
414 EXPECT_EQ(Manifest::EXTERNAL_PREF, location);
416 // Remove it so we won't count it ever again.
417 prefs_->Remove(id, NULL);
419 return true;
422 bool OnExternalExtensionUpdateUrlFound(const std::string& id,
423 const std::string& install_parameter,
424 const GURL& update_url,
425 Manifest::Location location,
426 int creation_flags,
427 bool mark_acknowledged) override {
428 ++ids_found_;
429 base::DictionaryValue* pref;
430 // This tests is to make sure that the provider only notifies us of the
431 // values we gave it. So if the id we doesn't exist in our internal
432 // dictionary then something is wrong.
433 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
434 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
435 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location);
437 if (pref) {
438 EXPECT_TRUE(provider_->HasExtension(id));
440 // External extensions with update URLs do not have versions.
441 scoped_ptr<Version> v1;
442 Manifest::Location location1 = Manifest::INVALID_LOCATION;
443 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
444 EXPECT_FALSE(v1.get());
445 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1);
447 std::string parsed_install_parameter;
448 pref->GetString("install_parameter", &parsed_install_parameter);
449 EXPECT_EQ(parsed_install_parameter, install_parameter);
451 // Remove it so we won't count it again.
452 prefs_->Remove(id, NULL);
454 return true;
457 void OnExternalProviderReady(
458 const extensions::ExternalProviderInterface* provider) override {
459 EXPECT_EQ(provider, provider_.get());
460 EXPECT_TRUE(provider->IsReady());
463 Profile* profile() { return profile_.get(); }
465 private:
466 int ids_found_;
467 base::FilePath fake_base_path_;
468 int expected_creation_flags_;
469 scoped_ptr<extensions::ExternalProviderImpl> provider_;
470 scoped_ptr<base::DictionaryValue> prefs_;
471 scoped_ptr<TestingProfile> profile_;
473 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
476 class ExtensionServiceTest : public extensions::ExtensionServiceTestBase,
477 public content::NotificationObserver {
478 public:
479 ExtensionServiceTest()
480 : unloaded_reason_(UnloadedExtensionInfo::REASON_UNDEFINED),
481 installed_(NULL),
482 was_update_(false),
483 override_external_install_prompt_(
484 FeatureSwitch::prompt_for_external_extensions(),
485 false),
486 expected_extensions_count_(0) {
487 registrar_.Add(this,
488 extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED,
489 content::NotificationService::AllSources());
490 registrar_.Add(this,
491 extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED,
492 content::NotificationService::AllSources());
493 registrar_.Add(
494 this,
495 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED,
496 content::NotificationService::AllSources());
499 void Observe(int type,
500 const content::NotificationSource& source,
501 const content::NotificationDetails& details) override {
502 switch (type) {
503 case extensions::NOTIFICATION_EXTENSION_LOADED_DEPRECATED: {
504 const Extension* extension =
505 content::Details<const Extension>(details).ptr();
506 loaded_.push_back(make_scoped_refptr(extension));
507 // The tests rely on the errors being in a certain order, which can vary
508 // depending on how filesystem iteration works.
509 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
510 break;
513 case extensions::NOTIFICATION_EXTENSION_UNLOADED_DEPRECATED: {
514 UnloadedExtensionInfo* unloaded_info =
515 content::Details<UnloadedExtensionInfo>(details).ptr();
516 const Extension* e = unloaded_info->extension;
517 unloaded_id_ = e->id();
518 unloaded_reason_ = unloaded_info->reason;
519 extensions::ExtensionList::iterator i =
520 std::find(loaded_.begin(), loaded_.end(), e);
521 // TODO(erikkay) fix so this can be an assert. Right now the tests
522 // are manually calling clear() on loaded_, so this isn't doable.
523 if (i == loaded_.end())
524 return;
525 loaded_.erase(i);
526 break;
528 case extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED: {
529 const extensions::InstalledExtensionInfo* installed_info =
530 content::Details<const extensions::InstalledExtensionInfo>(details)
531 .ptr();
532 installed_ = installed_info->extension;
533 was_update_ = installed_info->is_update;
534 old_name_ = installed_info->old_name;
535 break;
538 default:
539 DCHECK(false);
543 void AddMockExternalProvider(
544 extensions::ExternalProviderInterface* provider) {
545 service()->AddProviderForTesting(provider);
548 void MockSyncStartFlare(bool* was_called,
549 syncer::ModelType* model_type_passed_in,
550 syncer::ModelType model_type) {
551 *was_called = true;
552 *model_type_passed_in = model_type;
555 protected:
556 // Paths to some of the fake extensions.
557 base::FilePath good0_path() {
558 return data_dir()
559 .AppendASCII("good")
560 .AppendASCII("Extensions")
561 .AppendASCII(good0)
562 .AppendASCII("1.0.0.0");
565 base::FilePath good1_path() {
566 return data_dir()
567 .AppendASCII("good")
568 .AppendASCII("Extensions")
569 .AppendASCII(good1)
570 .AppendASCII("2");
573 base::FilePath good2_path() {
574 return data_dir()
575 .AppendASCII("good")
576 .AppendASCII("Extensions")
577 .AppendASCII(good2)
578 .AppendASCII("1.0");
581 void TestExternalProvider(MockExtensionProvider* provider,
582 Manifest::Location location);
584 void PackCRX(const base::FilePath& dir_path,
585 const base::FilePath& pem_path,
586 const base::FilePath& crx_path) {
587 // Use the existing pem key, if provided.
588 base::FilePath pem_output_path;
589 if (pem_path.value().empty()) {
590 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
591 } else {
592 ASSERT_TRUE(base::PathExists(pem_path));
595 ASSERT_TRUE(base::DeleteFile(crx_path, false));
597 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
598 ASSERT_TRUE(creator->Run(dir_path,
599 crx_path,
600 pem_path,
601 pem_output_path,
602 ExtensionCreator::kOverwriteCRX));
604 ASSERT_TRUE(base::PathExists(crx_path));
607 enum InstallState {
608 INSTALL_FAILED,
609 INSTALL_UPDATED,
610 INSTALL_NEW,
611 INSTALL_WITHOUT_LOAD,
614 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
615 const base::FilePath& pem_path,
616 InstallState install_state,
617 int creation_flags) {
618 base::FilePath crx_path;
619 base::ScopedTempDir temp_dir;
620 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
621 crx_path = temp_dir.path().AppendASCII("temp.crx");
623 PackCRX(dir_path, pem_path, crx_path);
624 return InstallCRX(crx_path, install_state, creation_flags);
627 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
628 const base::FilePath& pem_path,
629 InstallState install_state) {
630 return PackAndInstallCRX(dir_path, pem_path, install_state,
631 Extension::NO_FLAGS);
634 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
635 InstallState install_state) {
636 return PackAndInstallCRX(dir_path, base::FilePath(), install_state,
637 Extension::NO_FLAGS);
640 // Attempts to install an extension. Use INSTALL_FAILED if the installation
641 // is expected to fail.
642 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
643 // non-empty, expects that the existing extension's title was
644 // |expected_old_name|.
645 const Extension* InstallCRX(const base::FilePath& path,
646 InstallState install_state,
647 int creation_flags,
648 const std::string& expected_old_name) {
649 InstallCRXInternal(path, creation_flags);
650 return VerifyCrxInstall(path, install_state, expected_old_name);
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 int creation_flags) {
658 return InstallCRX(path, install_state, creation_flags, std::string());
661 // Attempts to install an extension. Use INSTALL_FAILED if the installation
662 // is expected to fail.
663 const Extension* InstallCRX(const base::FilePath& path,
664 InstallState install_state) {
665 return InstallCRX(path, install_state, Extension::NO_FLAGS);
668 const Extension* InstallCRXFromWebStore(const base::FilePath& path,
669 InstallState install_state) {
670 InstallCRXInternal(path, Extension::FROM_WEBSTORE);
671 return VerifyCrxInstall(path, install_state);
674 const Extension* InstallCRXWithLocation(const base::FilePath& crx_path,
675 Manifest::Location install_location,
676 InstallState install_state) {
677 EXPECT_TRUE(base::PathExists(crx_path))
678 << "Path does not exist: "<< crx_path.value().c_str();
679 // no client (silent install)
680 scoped_refptr<CrxInstaller> installer(
681 CrxInstaller::CreateSilent(service()));
682 installer->set_install_source(install_location);
684 content::WindowedNotificationObserver observer(
685 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
686 content::NotificationService::AllSources());
687 installer->InstallCrx(crx_path);
688 observer.Wait();
690 return VerifyCrxInstall(crx_path, install_state);
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 // Returns an Extension pointer if the install succeeded, NULL otherwise.
696 const Extension* VerifyCrxInstall(const base::FilePath& path,
697 InstallState install_state) {
698 return VerifyCrxInstall(path, install_state, std::string());
701 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
702 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
703 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
704 // non-empty, expects that the existing extension's title was
705 // |expected_old_name|.
706 // Returns an Extension pointer if the install succeeded, NULL otherwise.
707 const Extension* VerifyCrxInstall(const base::FilePath& path,
708 InstallState install_state,
709 const std::string& expected_old_name) {
710 std::vector<base::string16> errors = GetErrors();
711 const Extension* extension = NULL;
712 if (install_state != INSTALL_FAILED) {
713 if (install_state == INSTALL_NEW)
714 ++expected_extensions_count_;
716 EXPECT_TRUE(installed_) << path.value();
717 // If and only if INSTALL_UPDATED, it should have the is_update flag.
718 EXPECT_EQ(install_state == INSTALL_UPDATED, was_update_)
719 << path.value();
720 // If INSTALL_UPDATED, old_name_ should match the given string.
721 if (install_state == INSTALL_UPDATED && !expected_old_name.empty())
722 EXPECT_EQ(expected_old_name, old_name_);
723 EXPECT_EQ(0u, errors.size()) << path.value();
725 if (install_state == INSTALL_WITHOUT_LOAD) {
726 EXPECT_EQ(0u, loaded_.size()) << path.value();
727 } else {
728 EXPECT_EQ(1u, loaded_.size()) << path.value();
729 size_t actual_extension_count =
730 registry()->enabled_extensions().size() +
731 registry()->disabled_extensions().size();
732 EXPECT_EQ(expected_extensions_count_, actual_extension_count) <<
733 path.value();
734 extension = loaded_[0].get();
735 EXPECT_TRUE(service()->GetExtensionById(extension->id(), false))
736 << path.value();
739 for (std::vector<base::string16>::iterator err = errors.begin();
740 err != errors.end(); ++err) {
741 LOG(ERROR) << *err;
743 } else {
744 EXPECT_FALSE(installed_) << path.value();
745 EXPECT_EQ(0u, loaded_.size()) << path.value();
746 EXPECT_EQ(1u, errors.size()) << path.value();
749 installed_ = NULL;
750 was_update_ = false;
751 old_name_ = "";
752 loaded_.clear();
753 ExtensionErrorReporter::GetInstance()->ClearErrors();
754 return extension;
757 enum UpdateState {
758 FAILED_SILENTLY,
759 FAILED,
760 UPDATED,
761 INSTALLED,
762 DISABLED,
763 ENABLED
766 void BlackListWebGL() {
767 static const std::string json_blacklist =
768 "{\n"
769 " \"name\": \"gpu blacklist\",\n"
770 " \"version\": \"1.0\",\n"
771 " \"entries\": [\n"
772 " {\n"
773 " \"id\": 1,\n"
774 " \"features\": [\"webgl\"]\n"
775 " }\n"
776 " ]\n"
777 "}";
778 gpu::GPUInfo gpu_info;
779 content::GpuDataManager::GetInstance()->InitializeForTesting(
780 json_blacklist, gpu_info);
783 // Grants all optional permissions stated in manifest to active permission
784 // set for extension |id|.
785 void GrantAllOptionalPermissions(const std::string& id) {
786 const Extension* extension = service()->GetInstalledExtension(id);
787 scoped_refptr<const PermissionSet> all_optional_permissions =
788 extensions::PermissionsParser::GetOptionalPermissions(extension);
789 extensions::PermissionsUpdater perms_updater(profile());
790 perms_updater.AddPermissions(extension, all_optional_permissions.get());
793 // Helper method to set up a WindowedNotificationObserver to wait for a
794 // specific CrxInstaller to finish if we don't know the value of the
795 // |installer| yet.
796 static bool IsCrxInstallerDone(extensions::CrxInstaller** installer,
797 const content::NotificationSource& source,
798 const content::NotificationDetails& details) {
799 return content::Source<extensions::CrxInstaller>(source).ptr() ==
800 *installer;
803 void PackCRXAndUpdateExtension(const std::string& id,
804 const base::FilePath& dir_path,
805 const base::FilePath& pem_path,
806 UpdateState expected_state) {
807 base::ScopedTempDir temp_dir;
808 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
809 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
811 PackCRX(dir_path, pem_path, crx_path);
812 UpdateExtension(id, crx_path, expected_state);
815 void UpdateExtension(const std::string& id,
816 const base::FilePath& in_path,
817 UpdateState expected_state) {
818 ASSERT_TRUE(base::PathExists(in_path));
820 // We need to copy this to a temporary location because Update() will delete
821 // it.
822 base::FilePath path = temp_dir().path();
823 path = path.Append(in_path.BaseName());
824 ASSERT_TRUE(base::CopyFile(in_path, path));
826 int previous_enabled_extension_count =
827 registry()->enabled_extensions().size();
828 int previous_installed_extension_count =
829 previous_enabled_extension_count +
830 registry()->disabled_extensions().size();
832 extensions::CrxInstaller* installer = NULL;
833 content::WindowedNotificationObserver observer(
834 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
835 base::Bind(&IsCrxInstallerDone, &installer));
836 service()->UpdateExtension(extensions::CRXFileInfo(id, path), true,
837 &installer);
839 if (installer)
840 observer.Wait();
841 else
842 base::RunLoop().RunUntilIdle();
844 std::vector<base::string16> errors = GetErrors();
845 int error_count = errors.size();
846 int enabled_extension_count = registry()->enabled_extensions().size();
847 int installed_extension_count =
848 enabled_extension_count + registry()->disabled_extensions().size();
850 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
851 EXPECT_EQ(expected_error_count, error_count) << path.value();
853 if (expected_state <= FAILED) {
854 EXPECT_EQ(previous_enabled_extension_count,
855 enabled_extension_count);
856 EXPECT_EQ(previous_installed_extension_count,
857 installed_extension_count);
858 } else {
859 int expected_installed_extension_count =
860 (expected_state >= INSTALLED) ? 1 : 0;
861 int expected_enabled_extension_count =
862 (expected_state >= ENABLED) ? 1 : 0;
863 EXPECT_EQ(expected_installed_extension_count,
864 installed_extension_count);
865 EXPECT_EQ(expected_enabled_extension_count,
866 enabled_extension_count);
869 // Update() should the temporary input file.
870 EXPECT_FALSE(base::PathExists(path));
873 void TerminateExtension(const std::string& id) {
874 const Extension* extension = service()->GetInstalledExtension(id);
875 if (!extension) {
876 ADD_FAILURE();
877 return;
879 service()->TrackTerminatedExtensionForTest(extension);
882 testing::AssertionResult IsBlocked(const std::string& id) {
883 scoped_ptr<extensions::ExtensionSet> all_unblocked_extensions =
884 registry()->GenerateInstalledExtensionsSet(
885 ExtensionRegistry::EVERYTHING & ~ExtensionRegistry::BLOCKED);
886 if (all_unblocked_extensions.get()->Contains(id))
887 return testing::AssertionFailure() << id << " is still unblocked!";
888 if (!registry()->blocked_extensions().Contains(id))
889 return testing::AssertionFailure() << id << " is not blocked!";
890 return testing::AssertionSuccess();
893 // Helper method to test that an extension moves through being blocked and
894 // unblocked as appropriate for its type.
895 void AssertExtensionBlocksAndUnblocks(
896 bool should_block, const std::string extension_id) {
897 // Assume we start in an unblocked state.
898 EXPECT_FALSE(IsBlocked(extension_id));
900 // Block the extensions.
901 service()->BlockAllExtensions();
902 base::RunLoop().RunUntilIdle();
904 if (should_block)
905 ASSERT_TRUE(IsBlocked(extension_id));
906 else
907 ASSERT_FALSE(IsBlocked(extension_id));
909 service()->UnblockAllExtensions();
910 base::RunLoop().RunUntilIdle();
912 ASSERT_FALSE(IsBlocked(extension_id));
915 size_t GetPrefKeyCount() {
916 const base::DictionaryValue* dict =
917 profile()->GetPrefs()->GetDictionary("extensions.settings");
918 if (!dict) {
919 ADD_FAILURE();
920 return 0;
922 return dict->size();
925 void UninstallExtension(const std::string& id, bool use_helper) {
926 UninstallExtension(id, use_helper, Extension::ENABLED);
929 void UninstallExtension(const std::string& id, bool use_helper,
930 Extension::State expected_state) {
931 // Verify that the extension is installed.
932 base::FilePath extension_path = extensions_install_dir().AppendASCII(id);
933 EXPECT_TRUE(base::PathExists(extension_path));
934 size_t pref_key_count = GetPrefKeyCount();
935 EXPECT_GT(pref_key_count, 0u);
936 ValidateIntegerPref(id, "state", expected_state);
938 // Uninstall it.
939 if (use_helper) {
940 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(
941 service(), id, extensions::UNINSTALL_REASON_FOR_TESTING));
942 } else {
943 EXPECT_TRUE(service()->UninstallExtension(
945 extensions::UNINSTALL_REASON_FOR_TESTING,
946 base::Bind(&base::DoNothing),
947 NULL));
949 --expected_extensions_count_;
951 // We should get an unload notification.
952 EXPECT_FALSE(unloaded_id_.empty());
953 EXPECT_EQ(id, unloaded_id_);
955 // Verify uninstalled state.
956 size_t new_pref_key_count = GetPrefKeyCount();
957 if (new_pref_key_count == pref_key_count) {
958 ValidateIntegerPref(id, "state",
959 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
960 } else {
961 EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
964 // The extension should not be in the service anymore.
965 EXPECT_FALSE(service()->GetInstalledExtension(id));
966 base::RunLoop().RunUntilIdle();
968 // The directory should be gone.
969 EXPECT_FALSE(base::PathExists(extension_path));
972 void ValidatePrefKeyCount(size_t count) {
973 EXPECT_EQ(count, GetPrefKeyCount());
976 testing::AssertionResult ValidateBooleanPref(
977 const std::string& extension_id,
978 const std::string& pref_path,
979 bool expected_val) {
980 std::string msg = "while checking: ";
981 msg += extension_id;
982 msg += " ";
983 msg += pref_path;
984 msg += " == ";
985 msg += expected_val ? "true" : "false";
987 PrefService* prefs = profile()->GetPrefs();
988 const base::DictionaryValue* dict =
989 prefs->GetDictionary("extensions.settings");
990 if (!dict) {
991 return testing::AssertionFailure()
992 << "extension.settings does not exist " << msg;
995 const base::DictionaryValue* pref = NULL;
996 if (!dict->GetDictionary(extension_id, &pref)) {
997 return testing::AssertionFailure()
998 << "extension pref does not exist " << msg;
1001 bool val;
1002 if (!pref->GetBoolean(pref_path, &val)) {
1003 return testing::AssertionFailure()
1004 << pref_path << " pref not found " << msg;
1007 return expected_val == val
1008 ? testing::AssertionSuccess()
1009 : testing::AssertionFailure() << "base::Value is incorrect " << msg;
1012 bool IsPrefExist(const std::string& extension_id,
1013 const std::string& pref_path) {
1014 const base::DictionaryValue* dict =
1015 profile()->GetPrefs()->GetDictionary("extensions.settings");
1016 if (dict == NULL) return false;
1017 const base::DictionaryValue* pref = NULL;
1018 if (!dict->GetDictionary(extension_id, &pref)) {
1019 return false;
1021 if (pref == NULL) {
1022 return false;
1024 bool val;
1025 if (!pref->GetBoolean(pref_path, &val)) {
1026 return false;
1028 return true;
1031 void ValidateIntegerPref(const std::string& extension_id,
1032 const std::string& pref_path,
1033 int expected_val) {
1034 std::string msg = " while checking: ";
1035 msg += extension_id;
1036 msg += " ";
1037 msg += pref_path;
1038 msg += " == ";
1039 msg += base::IntToString(expected_val);
1041 PrefService* prefs = profile()->GetPrefs();
1042 const base::DictionaryValue* dict =
1043 prefs->GetDictionary("extensions.settings");
1044 ASSERT_TRUE(dict != NULL) << msg;
1045 const base::DictionaryValue* pref = NULL;
1046 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1047 EXPECT_TRUE(pref != NULL) << msg;
1048 int val;
1049 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
1050 EXPECT_EQ(expected_val, val) << msg;
1053 void ValidateStringPref(const std::string& extension_id,
1054 const std::string& pref_path,
1055 const std::string& expected_val) {
1056 std::string msg = " while checking: ";
1057 msg += extension_id;
1058 msg += ".manifest.";
1059 msg += pref_path;
1060 msg += " == ";
1061 msg += expected_val;
1063 const base::DictionaryValue* dict =
1064 profile()->GetPrefs()->GetDictionary("extensions.settings");
1065 ASSERT_TRUE(dict != NULL) << msg;
1066 const base::DictionaryValue* pref = NULL;
1067 std::string manifest_path = extension_id + ".manifest";
1068 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
1069 EXPECT_TRUE(pref != NULL) << msg;
1070 std::string val;
1071 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
1072 EXPECT_EQ(expected_val, val) << msg;
1075 void SetPref(const std::string& extension_id,
1076 const std::string& pref_path,
1077 base::Value* value,
1078 const std::string& msg) {
1079 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1080 base::DictionaryValue* dict = update.Get();
1081 ASSERT_TRUE(dict != NULL) << msg;
1082 base::DictionaryValue* pref = NULL;
1083 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1084 EXPECT_TRUE(pref != NULL) << msg;
1085 pref->Set(pref_path, value);
1088 void SetPrefInteg(const std::string& extension_id,
1089 const std::string& pref_path,
1090 int value) {
1091 std::string msg = " while setting: ";
1092 msg += extension_id;
1093 msg += " ";
1094 msg += pref_path;
1095 msg += " = ";
1096 msg += base::IntToString(value);
1098 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1101 void SetPrefBool(const std::string& extension_id,
1102 const std::string& pref_path,
1103 bool value) {
1104 std::string msg = " while setting: ";
1105 msg += extension_id + " " + pref_path;
1106 msg += " = ";
1107 msg += (value ? "true" : "false");
1109 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1112 void ClearPref(const std::string& extension_id,
1113 const std::string& pref_path) {
1114 std::string msg = " while clearing: ";
1115 msg += extension_id + " " + pref_path;
1117 DictionaryPrefUpdate update(profile()->GetPrefs(), "extensions.settings");
1118 base::DictionaryValue* dict = update.Get();
1119 ASSERT_TRUE(dict != NULL) << msg;
1120 base::DictionaryValue* pref = NULL;
1121 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1122 EXPECT_TRUE(pref != NULL) << msg;
1123 pref->Remove(pref_path, NULL);
1126 void SetPrefStringSet(const std::string& extension_id,
1127 const std::string& pref_path,
1128 const std::set<std::string>& value) {
1129 std::string msg = " while setting: ";
1130 msg += extension_id + " " + pref_path;
1132 base::ListValue* list_value = new base::ListValue();
1133 for (std::set<std::string>::const_iterator iter = value.begin();
1134 iter != value.end(); ++iter)
1135 list_value->Append(new base::StringValue(*iter));
1137 SetPref(extension_id, pref_path, list_value, msg);
1140 void InitPluginService() {
1141 #if defined(ENABLE_PLUGINS)
1142 PluginService::GetInstance()->Init();
1143 #endif
1146 void InitializeExtensionSyncService() {
1147 extension_sync_service_.reset(new ExtensionSyncService(
1148 profile(), ExtensionPrefs::Get(browser_context()), service()));
1151 void InitializeEmptyExtensionServiceWithTestingPrefs() {
1152 ExtensionServiceTestBase::ExtensionServiceInitParams params =
1153 CreateDefaultInitParams();
1154 params.pref_file = base::FilePath();
1155 InitializeExtensionService(params);
1158 extensions::ManagementPolicy* GetManagementPolicy() {
1159 return ExtensionSystem::Get(browser_context())->management_policy();
1162 ExtensionSyncService* extension_sync_service() {
1163 return extension_sync_service_.get();
1166 protected:
1167 typedef extensions::ExtensionManagementPrefUpdater<TestingPrefServiceSyncable>
1168 ManagementPrefUpdater;
1169 scoped_ptr<ExtensionSyncService> extension_sync_service_;
1170 extensions::ExtensionList loaded_;
1171 std::string unloaded_id_;
1172 UnloadedExtensionInfo::Reason unloaded_reason_;
1173 const Extension* installed_;
1174 bool was_update_;
1175 std::string old_name_;
1176 FeatureSwitch::ScopedOverride override_external_install_prompt_;
1178 private:
1179 // Create a CrxInstaller and install the CRX file.
1180 // Instead of calling this method yourself, use InstallCRX(), which does extra
1181 // error checking.
1182 void InstallCRXInternal(const base::FilePath& crx_path) {
1183 InstallCRXInternal(crx_path, Extension::NO_FLAGS);
1186 void InstallCRXInternal(const base::FilePath& crx_path, int creation_flags) {
1187 ASSERT_TRUE(base::PathExists(crx_path))
1188 << "Path does not exist: "<< crx_path.value().c_str();
1189 scoped_refptr<CrxInstaller> installer(
1190 CrxInstaller::CreateSilent(service()));
1191 installer->set_creation_flags(creation_flags);
1192 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT))
1193 installer->set_allow_silent_install(true);
1195 content::WindowedNotificationObserver observer(
1196 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1197 content::Source<extensions::CrxInstaller>(installer.get()));
1199 installer->InstallCrx(crx_path);
1201 observer.Wait();
1204 size_t expected_extensions_count_;
1205 content::NotificationRegistrar registrar_;
1208 // Receives notifications from a PackExtensionJob, indicating either that
1209 // packing succeeded or that there was some error.
1210 class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
1211 public:
1212 PackExtensionTestClient(const base::FilePath& expected_crx_path,
1213 const base::FilePath& expected_private_key_path);
1214 void OnPackSuccess(const base::FilePath& crx_path,
1215 const base::FilePath& private_key_path) override;
1216 void OnPackFailure(const std::string& error_message,
1217 ExtensionCreator::ErrorType type) override;
1219 private:
1220 const base::FilePath expected_crx_path_;
1221 const base::FilePath expected_private_key_path_;
1222 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
1225 PackExtensionTestClient::PackExtensionTestClient(
1226 const base::FilePath& expected_crx_path,
1227 const base::FilePath& expected_private_key_path)
1228 : expected_crx_path_(expected_crx_path),
1229 expected_private_key_path_(expected_private_key_path) {}
1231 // If packing succeeded, we make sure that the package names match our
1232 // expectations.
1233 void PackExtensionTestClient::OnPackSuccess(
1234 const base::FilePath& crx_path,
1235 const base::FilePath& private_key_path) {
1236 // We got the notification and processed it; we don't expect any further tasks
1237 // to be posted to the current thread, so we should stop blocking and continue
1238 // on with the rest of the test.
1239 // This call to |Quit()| matches the call to |Run()| in the
1240 // |PackPunctuatedExtension| test.
1241 base::MessageLoop::current()->Quit();
1242 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
1243 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
1244 ASSERT_TRUE(base::PathExists(private_key_path));
1247 // The tests are designed so that we never expect to see a packing error.
1248 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1249 ExtensionCreator::ErrorType type) {
1250 if (type == ExtensionCreator::kCRXExists)
1251 FAIL() << "Packing should not fail.";
1252 else
1253 FAIL() << "Existing CRX should have been overwritten.";
1256 // Test loading good extensions from the profile directory.
1257 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1258 InitPluginService();
1259 InitializeGoodInstalledExtensionService();
1260 service()->Init();
1262 uint32 expected_num_extensions = 3u;
1263 ASSERT_EQ(expected_num_extensions, loaded_.size());
1265 EXPECT_EQ(std::string(good0), loaded_[0]->id());
1266 EXPECT_EQ(std::string("My extension 1"),
1267 loaded_[0]->name());
1268 EXPECT_EQ(std::string("The first extension that I made."),
1269 loaded_[0]->description());
1270 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
1271 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false));
1272 EXPECT_EQ(expected_num_extensions, registry()->enabled_extensions().size());
1274 ValidatePrefKeyCount(3);
1275 ValidateIntegerPref(good0, "state", Extension::ENABLED);
1276 ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
1277 ValidateIntegerPref(good1, "state", Extension::ENABLED);
1278 ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
1279 ValidateIntegerPref(good2, "state", Extension::ENABLED);
1280 ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
1282 URLPatternSet expected_patterns;
1283 AddPattern(&expected_patterns, "file:///*");
1284 AddPattern(&expected_patterns, "http://*.google.com/*");
1285 AddPattern(&expected_patterns, "https://*.google.com/*");
1286 const Extension* extension = loaded_[0].get();
1287 const extensions::UserScriptList& scripts =
1288 extensions::ContentScriptsInfo::GetContentScripts(extension);
1289 ASSERT_EQ(2u, scripts.size());
1290 EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
1291 EXPECT_EQ(2u, scripts[0].js_scripts().size());
1292 ExtensionResource resource00(extension->id(),
1293 scripts[0].js_scripts()[0].extension_root(),
1294 scripts[0].js_scripts()[0].relative_path());
1295 base::FilePath expected_path =
1296 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
1297 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
1298 ExtensionResource resource01(extension->id(),
1299 scripts[0].js_scripts()[1].extension_root(),
1300 scripts[0].js_scripts()[1].relative_path());
1301 expected_path =
1302 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
1303 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
1304 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension));
1305 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
1306 EXPECT_EQ("http://*.news.com/*",
1307 scripts[1].url_patterns().begin()->GetAsString());
1308 ExtensionResource resource10(extension->id(),
1309 scripts[1].js_scripts()[0].extension_root(),
1310 scripts[1].js_scripts()[0].relative_path());
1311 expected_path =
1312 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
1313 expected_path = base::MakeAbsoluteFilePath(expected_path);
1314 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
1316 expected_patterns.ClearPatterns();
1317 AddPattern(&expected_patterns, "http://*.google.com/*");
1318 AddPattern(&expected_patterns, "https://*.google.com/*");
1319 EXPECT_EQ(
1320 expected_patterns,
1321 extension->permissions_data()->active_permissions()->explicit_hosts());
1323 EXPECT_EQ(std::string(good1), loaded_[1]->id());
1324 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
1325 EXPECT_EQ(std::string(), loaded_[1]->description());
1326 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
1327 extensions::BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
1328 EXPECT_EQ(0u,
1329 extensions::ContentScriptsInfo::GetContentScripts(loaded_[1].get())
1330 .size());
1332 // We don't parse the plugins section on Chrome OS.
1333 #if defined(OS_CHROMEOS)
1334 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1335 #else
1336 ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1337 const std::vector<extensions::PluginInfo>* plugins =
1338 extensions::PluginInfo::GetPlugins(loaded_[1].get());
1339 ASSERT_TRUE(plugins);
1340 ASSERT_EQ(2u, plugins->size());
1341 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
1342 plugins->at(0).path.value());
1343 EXPECT_TRUE(plugins->at(0).is_public);
1344 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1345 plugins->at(1).path.value());
1346 EXPECT_FALSE(plugins->at(1).is_public);
1347 #endif
1349 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
1351 int index = expected_num_extensions - 1;
1352 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1353 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1354 EXPECT_EQ(std::string(), loaded_[index]->description());
1355 EXPECT_EQ(0u,
1356 extensions::ContentScriptsInfo::GetContentScripts(
1357 loaded_[index].get()).size());
1358 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
1361 // Test loading bad extensions from the profile directory.
1362 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
1363 // Initialize the test dir with a bad Preferences/extensions.
1364 base::FilePath source_install_dir =
1365 data_dir().AppendASCII("bad").AppendASCII("Extensions");
1366 base::FilePath pref_path =
1367 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1369 InitializeInstalledExtensionService(pref_path, source_install_dir);
1371 service()->Init();
1373 ASSERT_EQ(4u, GetErrors().size());
1374 ASSERT_EQ(0u, loaded_.size());
1376 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[0]),
1377 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1378 extensions::manifest_errors::kManifestUnreadable)) <<
1379 base::UTF16ToUTF8(GetErrors()[0]);
1381 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[1]),
1382 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1383 extensions::manifest_errors::kManifestUnreadable)) <<
1384 base::UTF16ToUTF8(GetErrors()[1]);
1386 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[2]),
1387 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1388 extensions::manifest_errors::kMissingFile)) <<
1389 base::UTF16ToUTF8(GetErrors()[2]);
1391 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[3]),
1392 l10n_util::GetStringUTF8(IDS_EXTENSIONS_LOAD_ERROR_MESSAGE) + " *. " +
1393 extensions::manifest_errors::kManifestUnreadable)) <<
1394 base::UTF16ToUTF8(GetErrors()[3]);
1397 // Test various cases for delayed install because of missing imports.
1398 TEST_F(ExtensionServiceTest, PendingImports) {
1399 InitPluginService();
1401 base::FilePath source_install_dir =
1402 data_dir().AppendASCII("pending_updates_with_imports").AppendASCII(
1403 "Extensions");
1404 base::FilePath pref_path =
1405 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
1407 InitializeInstalledExtensionService(pref_path, source_install_dir);
1409 // Verify there are no pending extensions initially.
1410 EXPECT_FALSE(service()->pending_extension_manager()->HasPendingExtensions());
1412 service()->Init();
1413 // Wait for GarbageCollectExtensions task to complete.
1414 base::RunLoop().RunUntilIdle();
1416 // These extensions are used by the extensions we test below, they must be
1417 // installed.
1418 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1419 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1420 EXPECT_TRUE(base::PathExists(extensions_install_dir().AppendASCII(
1421 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1423 // Each of these extensions should have been rejected because of dependencies
1424 // that cannot be satisfied.
1425 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1426 EXPECT_FALSE(
1427 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1428 EXPECT_FALSE(
1429 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1430 EXPECT_FALSE(
1431 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1432 EXPECT_FALSE(
1433 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1434 EXPECT_FALSE(
1435 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
1436 EXPECT_FALSE(
1437 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
1439 // Make sure the import started for the extension with a dependency.
1440 EXPECT_TRUE(
1441 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1442 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1443 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1445 EXPECT_FALSE(base::PathExists(extensions_install_dir().AppendASCII(
1446 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
1448 EXPECT_TRUE(service()->pending_extension_manager()->HasPendingExtensions());
1449 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
1450 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(pending_id));
1451 // Remove it because we are not testing the pending extension manager's
1452 // ability to download and install extensions.
1453 EXPECT_TRUE(service()->pending_extension_manager()->Remove(pending_id));
1456 // Test installing extensions. This test tries to install few extensions using
1457 // crx files. If you need to change those crx files, feel free to repackage
1458 // them, throw away the key used and change the id's above.
1459 TEST_F(ExtensionServiceTest, InstallExtension) {
1460 InitializeEmptyExtensionService();
1462 // Extensions not enabled.
1463 service()->set_extensions_enabled(false);
1464 base::FilePath path = data_dir().AppendASCII("good.crx");
1465 InstallCRX(path, INSTALL_FAILED);
1466 service()->set_extensions_enabled(true);
1468 ValidatePrefKeyCount(0);
1470 // A simple extension that should install without error.
1471 path = data_dir().AppendASCII("good.crx");
1472 InstallCRX(path, INSTALL_NEW);
1473 // TODO(erikkay): verify the contents of the installed extension.
1475 int pref_count = 0;
1476 ValidatePrefKeyCount(++pref_count);
1477 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1478 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
1480 // An extension with page actions.
1481 path = data_dir().AppendASCII("page_action.crx");
1482 InstallCRX(path, INSTALL_NEW);
1483 ValidatePrefKeyCount(++pref_count);
1484 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1485 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
1487 // Bad signature.
1488 path = data_dir().AppendASCII("bad_signature.crx");
1489 InstallCRX(path, INSTALL_FAILED);
1490 ValidatePrefKeyCount(pref_count);
1492 // 0-length extension file.
1493 path = data_dir().AppendASCII("not_an_extension.crx");
1494 InstallCRX(path, INSTALL_FAILED);
1495 ValidatePrefKeyCount(pref_count);
1497 // Bad magic number.
1498 path = data_dir().AppendASCII("bad_magic.crx");
1499 InstallCRX(path, INSTALL_FAILED);
1500 ValidatePrefKeyCount(pref_count);
1502 // Packed extensions may have folders or files that have underscores.
1503 // This will only cause a warning, rather than a fatal error.
1504 path = data_dir().AppendASCII("bad_underscore.crx");
1505 InstallCRX(path, INSTALL_NEW);
1506 ValidatePrefKeyCount(++pref_count);
1508 // A test for an extension with a 2048-bit public key.
1509 path = data_dir().AppendASCII("good2048.crx");
1510 InstallCRX(path, INSTALL_NEW);
1511 ValidatePrefKeyCount(++pref_count);
1512 ValidateIntegerPref(good2048, "state", Extension::ENABLED);
1513 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
1515 // TODO(erikkay): add more tests for many of the failure cases.
1516 // TODO(erikkay): add tests for upgrade cases.
1519 struct MockExtensionRegistryObserver
1520 : public extensions::ExtensionRegistryObserver {
1521 void OnExtensionWillBeInstalled(content::BrowserContext* browser_context,
1522 const Extension* extension,
1523 bool is_update,
1524 bool from_ephemeral,
1525 const std::string& old_name) override {
1526 last_extension_installed = extension->id();
1529 void OnExtensionUninstalled(content::BrowserContext* browser_context,
1530 const Extension* extension,
1531 extensions::UninstallReason reason) override {
1532 last_extension_uninstalled = extension->id();
1535 std::string last_extension_installed;
1536 std::string last_extension_uninstalled;
1539 // Test that correct notifications are sent to ExtensionRegistryObserver on
1540 // extension install and uninstall.
1541 TEST_F(ExtensionServiceTest, InstallObserverNotified) {
1542 InitializeEmptyExtensionService();
1544 extensions::ExtensionRegistry* registry(
1545 extensions::ExtensionRegistry::Get(profile()));
1546 MockExtensionRegistryObserver observer;
1547 registry->AddObserver(&observer);
1549 // A simple extension that should install without error.
1550 ASSERT_TRUE(observer.last_extension_installed.empty());
1551 base::FilePath path = data_dir().AppendASCII("good.crx");
1552 InstallCRX(path, INSTALL_NEW);
1553 ASSERT_EQ(good_crx, observer.last_extension_installed);
1555 // Uninstall the extension.
1556 ASSERT_TRUE(observer.last_extension_uninstalled.empty());
1557 UninstallExtension(good_crx, false);
1558 ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
1560 registry->RemoveObserver(&observer);
1563 // Tests that flags passed to OnExternalExtensionFileFound() make it to the
1564 // extension object.
1565 TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
1566 const char kPrefFromBookmark[] = "from_bookmark";
1568 InitializeEmptyExtensionService();
1570 base::FilePath path = data_dir().AppendASCII("good.crx");
1571 service()->set_extensions_enabled(true);
1573 // Register and install an external extension.
1574 Version version("1.0.0.0");
1575 content::WindowedNotificationObserver observer(
1576 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1577 content::NotificationService::AllSources());
1578 if (service()->OnExternalExtensionFileFound(
1579 good_crx,
1580 &version,
1581 path,
1582 Manifest::EXTERNAL_PREF,
1583 Extension::FROM_BOOKMARK,
1584 false /* mark_acknowledged */,
1585 false /* install_immediately */)) {
1586 observer.Wait();
1589 const Extension* extension = service()->GetExtensionById(good_crx, false);
1590 ASSERT_TRUE(extension);
1591 ASSERT_TRUE(extension->from_bookmark());
1592 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1594 // Upgrade to version 2.0, the flag should be preserved.
1595 path = data_dir().AppendASCII("good2.crx");
1596 UpdateExtension(good_crx, path, ENABLED);
1597 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1598 extension = service()->GetExtensionById(good_crx, false);
1599 ASSERT_TRUE(extension);
1600 ASSERT_TRUE(extension->from_bookmark());
1603 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1604 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
1605 InitializeEmptyExtensionService();
1607 base::FilePath path = data_dir().AppendASCII("good.crx");
1608 service()->set_extensions_enabled(true);
1610 // Install an external extension.
1611 Version version("1.0.0.0");
1612 content::WindowedNotificationObserver observer(
1613 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1614 content::NotificationService::AllSources());
1615 if (service()->OnExternalExtensionFileFound(good_crx,
1616 &version,
1617 path,
1618 Manifest::EXTERNAL_PREF,
1619 Extension::NO_FLAGS,
1620 false,
1621 false)) {
1622 observer.Wait();
1625 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1627 // Uninstall it and check that its killbit gets set.
1628 UninstallExtension(good_crx, false);
1629 ValidateIntegerPref(good_crx, "state",
1630 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1632 // Try to re-install it externally. This should fail because of the killbit.
1633 service()->OnExternalExtensionFileFound(good_crx,
1634 &version,
1635 path,
1636 Manifest::EXTERNAL_PREF,
1637 Extension::NO_FLAGS,
1638 false,
1639 false);
1640 base::RunLoop().RunUntilIdle();
1641 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1642 ValidateIntegerPref(good_crx, "state",
1643 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1645 version = Version("1.0.0.1");
1646 // Repeat the same thing with a newer version of the extension.
1647 path = data_dir().AppendASCII("good2.crx");
1648 service()->OnExternalExtensionFileFound(good_crx,
1649 &version,
1650 path,
1651 Manifest::EXTERNAL_PREF,
1652 Extension::NO_FLAGS,
1653 false,
1654 false);
1655 base::RunLoop().RunUntilIdle();
1656 ASSERT_TRUE(NULL == service()->GetExtensionById(good_crx, false));
1657 ValidateIntegerPref(good_crx, "state",
1658 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1660 // Try adding the same extension from an external update URL.
1661 ASSERT_FALSE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
1662 good_crx,
1663 std::string(),
1664 GURL("http:://fake.update/url"),
1665 Manifest::EXTERNAL_PREF_DOWNLOAD,
1666 Extension::NO_FLAGS,
1667 false));
1669 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
1672 // Test that uninstalling an external extension does not crash when
1673 // the extension could not be loaded.
1674 // This extension shown in preferences file requires an experimental permission.
1675 // It could not be loaded without such permission.
1676 TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
1677 base::FilePath source_install_dir =
1678 data_dir().AppendASCII("good").AppendASCII("Extensions");
1679 // The preference contains an external extension
1680 // that requires 'experimental' permission.
1681 base::FilePath pref_path = source_install_dir
1682 .DirName()
1683 .AppendASCII("PreferencesExperimental");
1685 // Aforementioned extension will not be loaded if
1686 // there is no '--enable-experimental-extension-apis' command line flag.
1687 InitializeInstalledExtensionService(pref_path, source_install_dir);
1689 service()->Init();
1691 // Check and try to uninstall it.
1692 // If we don't check whether the extension is loaded before we uninstall it
1693 // in CheckExternalUninstall, a crash will happen here because we will get or
1694 // dereference a NULL pointer (extension) inside UninstallExtension.
1695 MockExtensionProvider provider(NULL, Manifest::EXTERNAL_REGISTRY);
1696 service()->OnExternalProviderReady(&provider);
1699 // Test that external extensions with incorrect IDs are not installed.
1700 TEST_F(ExtensionServiceTest, FailOnWrongId) {
1701 InitializeEmptyExtensionService();
1702 base::FilePath path = data_dir().AppendASCII("good.crx");
1703 service()->set_extensions_enabled(true);
1705 Version version("1.0.0.0");
1707 const std::string wrong_id = all_zero;
1708 const std::string correct_id = good_crx;
1709 ASSERT_NE(correct_id, wrong_id);
1711 // Install an external extension with an ID from the external
1712 // source that is not equal to the ID in the extension manifest.
1713 content::WindowedNotificationObserver observer(
1714 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1715 content::NotificationService::AllSources());
1716 service()->OnExternalExtensionFileFound(wrong_id,
1717 &version,
1718 path,
1719 Manifest::EXTERNAL_PREF,
1720 Extension::NO_FLAGS,
1721 false,
1722 false);
1724 observer.Wait();
1725 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1727 // Try again with the right ID. Expect success.
1728 content::WindowedNotificationObserver observer2(
1729 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1730 content::NotificationService::AllSources());
1731 if (service()->OnExternalExtensionFileFound(correct_id,
1732 &version,
1733 path,
1734 Manifest::EXTERNAL_PREF,
1735 Extension::NO_FLAGS,
1736 false,
1737 false)) {
1738 observer2.Wait();
1740 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1743 // Test that external extensions with incorrect versions are not installed.
1744 TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1745 InitializeEmptyExtensionService();
1746 base::FilePath path = data_dir().AppendASCII("good.crx");
1747 service()->set_extensions_enabled(true);
1749 // Install an external extension with a version from the external
1750 // source that is not equal to the version in the extension manifest.
1751 Version wrong_version("1.2.3.4");
1752 content::WindowedNotificationObserver observer(
1753 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1754 content::NotificationService::AllSources());
1755 service()->OnExternalExtensionFileFound(good_crx,
1756 &wrong_version,
1757 path,
1758 Manifest::EXTERNAL_PREF,
1759 Extension::NO_FLAGS,
1760 false,
1761 false);
1763 observer.Wait();
1764 ASSERT_FALSE(service()->GetExtensionById(good_crx, false));
1766 // Try again with the right version. Expect success.
1767 service()->pending_extension_manager()->Remove(good_crx);
1768 Version correct_version("1.0.0.0");
1769 content::WindowedNotificationObserver observer2(
1770 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
1771 content::NotificationService::AllSources());
1772 if (service()->OnExternalExtensionFileFound(good_crx,
1773 &correct_version,
1774 path,
1775 Manifest::EXTERNAL_PREF,
1776 Extension::NO_FLAGS,
1777 false,
1778 false)) {
1779 observer2.Wait();
1781 ASSERT_TRUE(service()->GetExtensionById(good_crx, false));
1784 // Install a user script (they get converted automatically to an extension)
1785 TEST_F(ExtensionServiceTest, InstallUserScript) {
1786 // The details of script conversion are tested elsewhere, this just tests
1787 // integration with ExtensionService.
1788 InitializeEmptyExtensionService();
1790 base::FilePath path = data_dir().AppendASCII("user_script_basic.user.js");
1792 ASSERT_TRUE(base::PathExists(path));
1793 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1794 installer->set_allow_silent_install(true);
1795 installer->InstallUserScript(
1796 path,
1797 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1799 base::RunLoop().RunUntilIdle();
1800 std::vector<base::string16> errors = GetErrors();
1801 EXPECT_TRUE(installed_) << "Nothing was installed.";
1802 EXPECT_FALSE(was_update_) << path.value();
1803 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1804 EXPECT_EQ(0u, errors.size()) << "There were errors: "
1805 << JoinString(errors, ',');
1806 EXPECT_TRUE(service()->GetExtensionById(loaded_[0]->id(), false))
1807 << path.value();
1809 installed_ = NULL;
1810 was_update_ = false;
1811 loaded_.clear();
1812 ExtensionErrorReporter::GetInstance()->ClearErrors();
1815 // Extensions don't install during shutdown.
1816 TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
1817 InitializeEmptyExtensionService();
1819 // Simulate shutdown.
1820 service()->set_browser_terminating_for_test(true);
1822 base::FilePath path = data_dir().AppendASCII("good.crx");
1823 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service()));
1824 installer->set_allow_silent_install(true);
1825 installer->InstallCrx(path);
1826 base::RunLoop().RunUntilIdle();
1828 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
1829 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
1832 // This tests that the granted permissions preferences are correctly set when
1833 // installing an extension.
1834 TEST_F(ExtensionServiceTest, GrantedPermissions) {
1835 InitializeEmptyExtensionService();
1836 base::FilePath path = data_dir().AppendASCII("permissions");
1838 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1839 path = path.AppendASCII("unknown");
1841 ASSERT_TRUE(base::PathExists(pem_path));
1842 ASSERT_TRUE(base::PathExists(path));
1844 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1846 APIPermissionSet expected_api_perms;
1847 URLPatternSet expected_host_perms;
1849 // Make sure there aren't any granted permissions before the
1850 // extension is installed.
1851 scoped_refptr<PermissionSet> known_perms(
1852 prefs->GetGrantedPermissions(permissions_crx));
1853 EXPECT_FALSE(known_perms.get());
1855 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
1857 EXPECT_EQ(0u, GetErrors().size());
1858 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1859 EXPECT_EQ(permissions_crx, extension->id());
1861 // Verify that the valid API permissions have been recognized.
1862 expected_api_perms.insert(APIPermission::kTab);
1864 AddPattern(&expected_host_perms, "http://*.google.com/*");
1865 AddPattern(&expected_host_perms, "https://*.google.com/*");
1866 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
1867 AddPattern(&expected_host_perms, "http://www.example.com/*");
1869 known_perms = prefs->GetGrantedPermissions(extension->id());
1870 EXPECT_TRUE(known_perms.get());
1871 EXPECT_FALSE(known_perms->IsEmpty());
1872 EXPECT_EQ(expected_api_perms, known_perms->apis());
1873 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1874 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
1878 #if !defined(OS_CHROMEOS)
1879 // This tests that the granted permissions preferences are correctly set for
1880 // default apps.
1881 TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
1882 InitializeEmptyExtensionService();
1883 base::FilePath path = data_dir().AppendASCII("permissions");
1885 base::FilePath pem_path = path.AppendASCII("unknown.pem");
1886 path = path.AppendASCII("unknown");
1888 ASSERT_TRUE(base::PathExists(pem_path));
1889 ASSERT_TRUE(base::PathExists(path));
1891 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1893 APIPermissionSet expected_api_perms;
1894 URLPatternSet expected_host_perms;
1896 // Make sure there aren't any granted permissions before the
1897 // extension is installed.
1898 scoped_refptr<PermissionSet> known_perms(
1899 prefs->GetGrantedPermissions(permissions_crx));
1900 EXPECT_FALSE(known_perms.get());
1902 const Extension* extension = PackAndInstallCRX(
1903 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
1905 EXPECT_EQ(0u, GetErrors().size());
1906 ASSERT_EQ(1u, registry()->enabled_extensions().size());
1907 EXPECT_EQ(permissions_crx, extension->id());
1909 // Verify that the valid API permissions have been recognized.
1910 expected_api_perms.insert(APIPermission::kTab);
1912 known_perms = prefs->GetGrantedPermissions(extension->id());
1913 EXPECT_TRUE(known_perms.get());
1914 EXPECT_FALSE(known_perms->IsEmpty());
1915 EXPECT_EQ(expected_api_perms, known_perms->apis());
1916 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
1918 #endif
1920 #if !defined(OS_POSIX) || defined(OS_MACOSX)
1921 // Tests that the granted permissions full_access bit gets set correctly when
1922 // an extension contains an NPAPI plugin.
1923 // Only run this on platforms that support NPAPI plugins.
1924 TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
1925 InitPluginService();
1927 InitializeEmptyExtensionService();
1929 ASSERT_TRUE(base::PathExists(good1_path()));
1930 const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW);
1931 EXPECT_EQ(0u, GetErrors().size());
1932 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1933 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1935 scoped_refptr<PermissionSet> permissions(
1936 prefs->GetGrantedPermissions(extension->id()));
1937 EXPECT_FALSE(permissions->IsEmpty());
1938 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
1939 EXPECT_FALSE(permissions->apis().empty());
1940 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
1942 // Full access implies full host access too...
1943 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
1945 #endif
1947 // Tests that the extension is disabled when permissions are missing from
1948 // the extension's granted permissions preferences. (This simulates updating
1949 // the browser to a version which recognizes more permissions).
1950 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
1951 InitializeEmptyExtensionService();
1953 base::FilePath path =
1954 data_dir().AppendASCII("permissions").AppendASCII("unknown");
1956 ASSERT_TRUE(base::PathExists(path));
1958 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
1960 EXPECT_EQ(0u, GetErrors().size());
1961 EXPECT_EQ(1u, registry()->enabled_extensions().size());
1962 std::string extension_id = extension->id();
1964 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
1966 APIPermissionSet expected_api_permissions;
1967 URLPatternSet expected_host_permissions;
1969 expected_api_permissions.insert(APIPermission::kTab);
1970 AddPattern(&expected_host_permissions, "http://*.google.com/*");
1971 AddPattern(&expected_host_permissions, "https://*.google.com/*");
1972 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
1973 AddPattern(&expected_host_permissions, "http://www.example.com/*");
1975 std::set<std::string> host_permissions;
1977 // Test that the extension is disabled when an API permission is missing from
1978 // the extension's granted api permissions preference. (This simulates
1979 // updating the browser to a version which recognizes a new API permission).
1980 SetPref(extension_id, "granted_permissions.api",
1981 new base::ListValue(), "granted_permissions.api");
1982 service()->ReloadExtensionsForTest();
1984 EXPECT_EQ(1u, registry()->disabled_extensions().size());
1985 extension = registry()->disabled_extensions().begin()->get();
1987 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
1988 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
1989 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
1991 // Now grant and re-enable the extension, making sure the prefs are updated.
1992 service()->GrantPermissionsAndEnableExtension(extension);
1994 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
1995 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
1996 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
1998 scoped_refptr<PermissionSet> current_perms(
1999 prefs->GetGrantedPermissions(extension_id));
2000 ASSERT_TRUE(current_perms.get());
2001 ASSERT_FALSE(current_perms->IsEmpty());
2002 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2003 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2004 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2006 // Tests that the extension is disabled when a host permission is missing from
2007 // the extension's granted host permissions preference. (This simulates
2008 // updating the browser to a version which recognizes additional host
2009 // permissions).
2010 host_permissions.clear();
2011 current_perms = NULL;
2013 host_permissions.insert("http://*.google.com/*");
2014 host_permissions.insert("https://*.google.com/*");
2015 host_permissions.insert("http://*.google.com.hk/*");
2017 base::ListValue* api_permissions = new base::ListValue();
2018 api_permissions->Append(
2019 new base::StringValue("tabs"));
2020 SetPref(extension_id, "granted_permissions.api",
2021 api_permissions, "granted_permissions.api");
2022 SetPrefStringSet(
2023 extension_id, "granted_permissions.scriptable_host", host_permissions);
2025 service()->ReloadExtensionsForTest();
2027 EXPECT_EQ(1u, registry()->disabled_extensions().size());
2028 extension = registry()->disabled_extensions().begin()->get();
2030 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2031 ASSERT_FALSE(service()->IsExtensionEnabled(extension_id));
2032 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2034 // Now grant and re-enable the extension, making sure the prefs are updated.
2035 service()->GrantPermissionsAndEnableExtension(extension);
2037 ASSERT_TRUE(service()->IsExtensionEnabled(extension_id));
2038 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2040 current_perms = prefs->GetGrantedPermissions(extension_id);
2041 ASSERT_TRUE(current_perms.get());
2042 ASSERT_FALSE(current_perms->IsEmpty());
2043 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2044 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2045 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2048 // Test Packaging and installing an extension.
2049 TEST_F(ExtensionServiceTest, PackExtension) {
2050 InitializeEmptyExtensionService();
2051 base::FilePath input_directory =
2052 data_dir()
2053 .AppendASCII("good")
2054 .AppendASCII("Extensions")
2055 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2056 .AppendASCII("1.0.0.0");
2058 base::ScopedTempDir temp_dir;
2059 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2060 base::FilePath output_directory = temp_dir.path();
2062 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2063 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2065 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2066 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2067 privkey_path, ExtensionCreator::kNoRunFlags));
2068 ASSERT_TRUE(base::PathExists(crx_path));
2069 ASSERT_TRUE(base::PathExists(privkey_path));
2071 // Repeat the run with the pem file gone, and no special flags
2072 // Should refuse to overwrite the existing crx.
2073 base::DeleteFile(privkey_path, false);
2074 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2075 privkey_path, ExtensionCreator::kNoRunFlags));
2077 // OK, now try it with a flag to overwrite existing crx. Should work.
2078 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2079 privkey_path, ExtensionCreator::kOverwriteCRX));
2081 // Repeat the run allowing existing crx, but the existing pem is still
2082 // an error. Should fail.
2083 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2084 privkey_path, ExtensionCreator::kOverwriteCRX));
2086 ASSERT_TRUE(base::PathExists(privkey_path));
2087 InstallCRX(crx_path, INSTALL_NEW);
2089 // Try packing with invalid paths.
2090 creator.reset(new ExtensionCreator());
2091 ASSERT_FALSE(
2092 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
2093 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2095 // Try packing an empty directory. Should fail because an empty directory is
2096 // not a valid extension.
2097 base::ScopedTempDir temp_dir2;
2098 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
2099 creator.reset(new ExtensionCreator());
2100 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2101 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2103 // Try packing with an invalid manifest.
2104 std::string invalid_manifest_content = "I am not a manifest.";
2105 ASSERT_TRUE(base::WriteFile(
2106 temp_dir2.path().Append(extensions::kManifestFilename),
2107 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
2108 creator.reset(new ExtensionCreator());
2109 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2110 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2112 // Try packing with a private key that is a valid key, but invalid for the
2113 // extension.
2114 base::FilePath bad_private_key_dir =
2115 data_dir().AppendASCII("bad_private_key");
2116 crx_path = output_directory.AppendASCII("bad_private_key.crx");
2117 privkey_path = data_dir().AppendASCII("bad_private_key.pem");
2118 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
2119 privkey_path, ExtensionCreator::kOverwriteCRX));
2122 // Test Packaging and installing an extension whose name contains punctuation.
2123 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
2124 InitializeEmptyExtensionService();
2125 base::FilePath input_directory = data_dir()
2126 .AppendASCII("good")
2127 .AppendASCII("Extensions")
2128 .AppendASCII(good0)
2129 .AppendASCII("1.0.0.0");
2131 base::ScopedTempDir temp_dir;
2132 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2134 // Extension names containing punctuation, and the expected names for the
2135 // packed extensions.
2136 const base::FilePath punctuated_names[] = {
2137 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2138 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2139 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
2140 NormalizePathSeparators(),
2142 const base::FilePath expected_crx_names[] = {
2143 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2144 base::FilePath(
2145 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2146 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
2148 const base::FilePath expected_private_key_names[] = {
2149 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2150 base::FilePath(
2151 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2152 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
2155 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
2156 SCOPED_TRACE(punctuated_names[i].value().c_str());
2157 base::FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
2159 // Copy the extension into the output directory, as PackExtensionJob doesn't
2160 // let us choose where to output the packed extension.
2161 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
2163 base::FilePath expected_crx_path =
2164 temp_dir.path().Append(expected_crx_names[i]);
2165 base::FilePath expected_private_key_path =
2166 temp_dir.path().Append(expected_private_key_names[i]);
2167 PackExtensionTestClient pack_client(expected_crx_path,
2168 expected_private_key_path);
2169 scoped_refptr<extensions::PackExtensionJob> packer(
2170 new extensions::PackExtensionJob(&pack_client, output_dir,
2171 base::FilePath(),
2172 ExtensionCreator::kOverwriteCRX));
2173 packer->Start();
2175 // The packer will post a notification task to the current thread's message
2176 // loop when it is finished. We manually run the loop here so that we
2177 // block and catch the notification; otherwise, the process would exit.
2178 // This call to |Run()| is matched by a call to |Quit()| in the
2179 // |PackExtensionTestClient|'s notification handling code.
2180 base::MessageLoop::current()->Run();
2182 if (HasFatalFailure())
2183 return;
2185 InstallCRX(expected_crx_path, INSTALL_NEW);
2189 TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
2190 InitializeEmptyExtensionService();
2192 base::ScopedTempDir extension_temp_dir;
2193 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
2194 base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
2195 ASSERT_TRUE(
2196 base::CopyDirectory(data_dir()
2197 .AppendASCII("good")
2198 .AppendASCII("Extensions")
2199 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2200 .AppendASCII("1.0.0.0"),
2201 input_directory,
2202 /*recursive=*/true));
2204 base::ScopedTempDir output_temp_dir;
2205 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
2206 base::FilePath output_directory = output_temp_dir.path();
2208 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2209 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2211 // Pack the extension once to get a private key.
2212 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2213 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2214 privkey_path, ExtensionCreator::kNoRunFlags))
2215 << creator->error_message();
2216 ASSERT_TRUE(base::PathExists(crx_path));
2217 ASSERT_TRUE(base::PathExists(privkey_path));
2219 base::DeleteFile(crx_path, false);
2220 // Move the pem file into the extension.
2221 base::Move(privkey_path,
2222 input_directory.AppendASCII("privkey.pem"));
2224 // This pack should fail because of the contained private key.
2225 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2226 privkey_path, ExtensionCreator::kNoRunFlags));
2227 EXPECT_THAT(creator->error_message(),
2228 testing::ContainsRegex(
2229 "extension includes the key file.*privkey.pem"));
2232 // Test Packaging and installing an extension using an openssl generated key.
2233 // The openssl is generated with the following:
2234 // > openssl genrsa -out privkey.pem 1024
2235 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
2236 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
2237 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
2238 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
2239 InitializeEmptyExtensionService();
2240 base::FilePath input_directory =
2241 data_dir()
2242 .AppendASCII("good")
2243 .AppendASCII("Extensions")
2244 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2245 .AppendASCII("1.0.0.0");
2246 base::FilePath privkey_path(
2247 data_dir().AppendASCII("openssl_privkey_asn1.pem"));
2248 ASSERT_TRUE(base::PathExists(privkey_path));
2250 base::ScopedTempDir temp_dir;
2251 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2252 base::FilePath output_directory = temp_dir.path();
2254 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2256 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2257 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
2258 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2260 InstallCRX(crx_path, INSTALL_NEW);
2263 #if defined(THREAD_SANITIZER)
2264 // Flaky under Tsan. http://crbug.com/377702
2265 #define MAYBE_InstallTheme DISABLED_InstallTheme
2266 #else
2267 #define MAYBE_InstallTheme InstallTheme
2268 #endif
2270 TEST_F(ExtensionServiceTest, MAYBE_InstallTheme) {
2271 InitializeEmptyExtensionService();
2272 service()->Init();
2274 // A theme.
2275 base::FilePath path = data_dir().AppendASCII("theme.crx");
2276 InstallCRX(path, INSTALL_NEW);
2277 int pref_count = 0;
2278 ValidatePrefKeyCount(++pref_count);
2279 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2280 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2282 // A theme when extensions are disabled. Themes can be installed, even when
2283 // extensions are disabled.
2284 service()->set_extensions_enabled(false);
2285 path = data_dir().AppendASCII("theme2.crx");
2286 InstallCRX(path, INSTALL_NEW);
2287 ValidatePrefKeyCount(++pref_count);
2288 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
2289 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
2291 // A theme with extension elements. Themes cannot have extension elements,
2292 // so any such elements (like content scripts) should be ignored.
2293 service()->set_extensions_enabled(true);
2295 path = data_dir().AppendASCII("theme_with_extension.crx");
2296 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2297 ValidatePrefKeyCount(++pref_count);
2298 ASSERT_TRUE(extension);
2299 EXPECT_TRUE(extension->is_theme());
2300 EXPECT_EQ(
2302 extensions::ContentScriptsInfo::GetContentScripts(extension).size());
2305 // A theme with image resources missing (misspelt path).
2306 path = data_dir().AppendASCII("theme_missing_image.crx");
2307 InstallCRX(path, INSTALL_FAILED);
2308 ValidatePrefKeyCount(pref_count);
2311 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
2312 // Load.
2313 InitializeEmptyExtensionService();
2314 service()->Init();
2316 base::FilePath extension_path = data_dir().AppendASCII("theme_i18n");
2318 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2319 base::RunLoop().RunUntilIdle();
2320 EXPECT_EQ(0u, GetErrors().size());
2321 ASSERT_EQ(1u, loaded_.size());
2322 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2323 const Extension* theme = registry()->enabled_extensions().begin()->get();
2324 EXPECT_EQ("name", theme->name());
2325 EXPECT_EQ("description", theme->description());
2327 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a
2328 // temporary directory, but it automatically installs to the extension's
2329 // directory, and we don't want to copy the whole extension for a unittest.
2330 base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
2331 ASSERT_TRUE(base::PathExists(theme_file));
2332 ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive.
2335 #if defined(OS_POSIX)
2336 TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
2337 base::FilePath source_data_dir =
2338 data_dir().AppendASCII("unpacked").AppendASCII("symlinks_allowed");
2340 // Paths to test data files.
2341 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2342 ASSERT_TRUE(base::PathExists(source_manifest));
2343 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2344 ASSERT_TRUE(base::PathExists(source_icon));
2346 // Set up the temporary extension directory.
2347 base::ScopedTempDir temp;
2348 ASSERT_TRUE(temp.CreateUniqueTempDir());
2349 base::FilePath extension_path = temp.path();
2350 base::FilePath manifest = extension_path.Append(
2351 extensions::kManifestFilename);
2352 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2353 base::CopyFile(source_manifest, manifest);
2354 base::CreateSymbolicLink(source_icon, icon_symlink);
2356 // Load extension.
2357 InitializeEmptyExtensionService();
2358 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2359 base::RunLoop().RunUntilIdle();
2361 EXPECT_TRUE(GetErrors().empty());
2362 ASSERT_EQ(1u, loaded_.size());
2363 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2365 #endif
2367 TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
2368 InitializeEmptyExtensionService();
2369 base::FilePath extension_path = data_dir().AppendASCII("underscore_name");
2370 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2371 base::RunLoop().RunUntilIdle();
2372 EXPECT_EQ(1u, GetErrors().size());
2373 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2376 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
2377 InitializeEmptyExtensionService();
2378 service()->Init();
2380 base::FilePath theme_path = data_dir().AppendASCII("theme_i18n");
2382 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
2384 EXPECT_EQ(0u, GetErrors().size());
2385 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2386 EXPECT_EQ("name", theme->name());
2387 EXPECT_EQ("description", theme->description());
2390 TEST_F(ExtensionServiceTest, InstallApps) {
2391 InitializeEmptyExtensionService();
2393 // An empty app.
2394 const Extension* app =
2395 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2396 int pref_count = 0;
2397 ValidatePrefKeyCount(++pref_count);
2398 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2399 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2400 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
2402 // Another app with non-overlapping extent. Should succeed.
2403 PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2404 ValidatePrefKeyCount(++pref_count);
2406 // A third app whose extent overlaps the first. Should fail.
2407 PackAndInstallCRX(data_dir().AppendASCII("app3"), INSTALL_FAILED);
2408 ValidatePrefKeyCount(pref_count);
2411 // Tests that file access is OFF by default.
2412 TEST_F(ExtensionServiceTest, DefaultFileAccess) {
2413 InitializeEmptyExtensionService();
2414 const Extension* extension = PackAndInstallCRX(
2415 data_dir().AppendASCII("permissions").AppendASCII("files"), INSTALL_NEW);
2416 EXPECT_EQ(0u, GetErrors().size());
2417 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2418 EXPECT_FALSE(
2419 ExtensionPrefs::Get(profile())->AllowFileAccess(extension->id()));
2422 TEST_F(ExtensionServiceTest, UpdateApps) {
2423 InitializeEmptyExtensionService();
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 // Now try updating to v2.
2434 UpdateExtension(id,
2435 extensions_path.AppendASCII("v2.crx"),
2436 ENABLED);
2437 ASSERT_EQ(std::string("2"),
2438 service()->GetExtensionById(id, false)->version()->GetString());
2441 // Verifies that the NTP page and launch ordinals are kept when updating apps.
2442 TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
2443 InitializeEmptyExtensionService();
2444 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2445 base::FilePath extensions_path = data_dir().AppendASCII("app_update");
2447 // First install v1 of a hosted app.
2448 const Extension* extension =
2449 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2450 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2451 std::string id = extension->id();
2452 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2454 // Modify the ordinals so we can distinguish them from the defaults.
2455 syncer::StringOrdinal new_page_ordinal =
2456 sorting->GetPageOrdinal(id).CreateAfter();
2457 syncer::StringOrdinal new_launch_ordinal =
2458 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2460 sorting->SetPageOrdinal(id, new_page_ordinal);
2461 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2463 // Now try updating to v2.
2464 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2465 ASSERT_EQ(std::string("2"),
2466 service()->GetExtensionById(id, false)->version()->GetString());
2468 // Verify that the ordinals match.
2469 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2470 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
2473 // Ensures that the CWS has properly initialized ordinals.
2474 TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
2475 InitializeEmptyExtensionService();
2476 service()->component_loader()->Add(
2477 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
2478 service()->Init();
2480 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
2481 EXPECT_TRUE(
2482 sorting->GetPageOrdinal(extensions::kWebStoreAppId).IsValid());
2483 EXPECT_TRUE(
2484 sorting->GetAppLaunchOrdinal(extensions::kWebStoreAppId).IsValid());
2487 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
2488 InitializeEmptyExtensionService();
2489 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2491 int pref_count = 0;
2493 // Install app1 with unlimited storage.
2494 const Extension* extension =
2495 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2496 ValidatePrefKeyCount(++pref_count);
2497 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2498 const std::string id1 = extension->id();
2499 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2500 APIPermission::kUnlimitedStorage));
2501 EXPECT_TRUE(extension->web_extent().MatchesURL(
2502 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2503 const GURL origin1(
2504 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2505 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2506 origin1));
2508 // Install app2 from the same origin with unlimited storage.
2509 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
2510 ValidatePrefKeyCount(++pref_count);
2511 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2512 const std::string id2 = extension->id();
2513 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
2514 APIPermission::kUnlimitedStorage));
2515 EXPECT_TRUE(extension->web_extent().MatchesURL(
2516 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2517 const GURL origin2(
2518 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2519 EXPECT_EQ(origin1, origin2);
2520 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2521 origin2));
2523 // Uninstall one of them, unlimited storage should still be granted
2524 // to the origin.
2525 UninstallExtension(id1, false);
2526 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2527 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2528 origin1));
2530 // Uninstall the other, unlimited storage should be revoked.
2531 UninstallExtension(id2, false);
2532 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2533 EXPECT_FALSE(
2534 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
2535 origin2));
2538 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
2539 InitializeEmptyExtensionService();
2540 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2542 int pref_count = 0;
2544 const Extension* extension =
2545 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
2546 ValidatePrefKeyCount(++pref_count);
2547 ASSERT_EQ(1u, registry()->enabled_extensions().size());
2548 EXPECT_TRUE(extension->is_app());
2549 const std::string id1 = extension->id();
2550 const GURL origin1(
2551 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2552 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2553 origin1));
2555 // App 4 has a different origin (maps.google.com).
2556 extension = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
2557 ValidatePrefKeyCount(++pref_count);
2558 ASSERT_EQ(2u, registry()->enabled_extensions().size());
2559 const std::string id2 = extension->id();
2560 const GURL origin2(
2561 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2562 ASSERT_NE(origin1, origin2);
2563 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2564 origin2));
2566 UninstallExtension(id1, false);
2567 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2569 UninstallExtension(id2, false);
2571 EXPECT_TRUE(registry()->enabled_extensions().is_empty());
2572 EXPECT_FALSE(
2573 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2574 origin1));
2575 EXPECT_FALSE(
2576 profile()->GetExtensionSpecialStoragePolicy()->IsStorageProtected(
2577 origin2));
2580 // Test that when an extension version is reinstalled, nothing happens.
2581 TEST_F(ExtensionServiceTest, Reinstall) {
2582 InitializeEmptyExtensionService();
2584 // A simple extension that should install without error.
2585 base::FilePath path = data_dir().AppendASCII("good.crx");
2586 InstallCRX(path, INSTALL_NEW);
2588 ValidatePrefKeyCount(1);
2589 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2590 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2592 // Reinstall the same version, it should overwrite the previous one.
2593 InstallCRX(path, INSTALL_UPDATED);
2595 ValidatePrefKeyCount(1);
2596 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2597 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2600 // Test that we can determine if extensions came from the
2601 // Chrome web store.
2602 TEST_F(ExtensionServiceTest, FromWebStore) {
2603 InitializeEmptyExtensionService();
2605 // A simple extension that should install without error.
2606 base::FilePath path = data_dir().AppendASCII("good.crx");
2607 // Not from web store.
2608 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2609 std::string id = extension->id();
2611 ValidatePrefKeyCount(1);
2612 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
2613 ASSERT_FALSE(extension->from_webstore());
2615 // Test install from web store.
2616 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
2618 ValidatePrefKeyCount(1);
2619 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2621 // Reload so extension gets reinitialized with new value.
2622 service()->ReloadExtensionsForTest();
2623 extension = service()->GetExtensionById(id, false);
2624 ASSERT_TRUE(extension->from_webstore());
2626 // Upgrade to version 2.0
2627 path = data_dir().AppendASCII("good2.crx");
2628 UpdateExtension(good_crx, path, ENABLED);
2629 ValidatePrefKeyCount(1);
2630 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2633 // Test upgrading a signed extension.
2634 TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
2635 InitializeEmptyExtensionService();
2637 base::FilePath path = data_dir().AppendASCII("good.crx");
2638 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2639 std::string id = extension->id();
2641 ASSERT_EQ("1.0.0.0", extension->version()->GetString());
2642 ASSERT_EQ(0u, GetErrors().size());
2644 // Upgrade to version 1.0.0.1.
2645 // Also test that the extension's old and new title are correctly retrieved.
2646 path = data_dir().AppendASCII("good2.crx");
2647 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
2648 extension = service()->GetExtensionById(id, false);
2650 ASSERT_EQ("1.0.0.1", extension->version()->GetString());
2651 ASSERT_EQ("My updated extension 1", extension->name());
2652 ASSERT_EQ(0u, GetErrors().size());
2655 // Test upgrading a signed extension with a bad signature.
2656 TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
2657 InitializeEmptyExtensionService();
2659 base::FilePath path = data_dir().AppendASCII("good.crx");
2660 InstallCRX(path, INSTALL_NEW);
2662 // Try upgrading with a bad signature. This should fail during the unpack,
2663 // because the key will not match the signature.
2664 path = data_dir().AppendASCII("bad_signature.crx");
2665 InstallCRX(path, INSTALL_FAILED);
2668 // Test a normal update via the UpdateExtension API
2669 TEST_F(ExtensionServiceTest, UpdateExtension) {
2670 InitializeEmptyExtensionService();
2672 base::FilePath path = data_dir().AppendASCII("good.crx");
2674 const Extension* good = InstallCRX(path, INSTALL_NEW);
2675 ASSERT_EQ("1.0.0.0", good->VersionString());
2676 ASSERT_EQ(good_crx, good->id());
2678 path = data_dir().AppendASCII("good2.crx");
2679 UpdateExtension(good_crx, path, ENABLED);
2680 ASSERT_EQ(
2681 "1.0.0.1",
2682 service()->GetExtensionById(good_crx, false)->version()->GetString());
2685 // Extensions should not be updated during browser shutdown.
2686 TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
2687 InitializeEmptyExtensionService();
2689 // Install an extension.
2690 base::FilePath path = data_dir().AppendASCII("good.crx");
2691 const Extension* good = InstallCRX(path, INSTALL_NEW);
2692 ASSERT_EQ(good_crx, good->id());
2694 // Simulate shutdown.
2695 service()->set_browser_terminating_for_test(true);
2697 // Update should fail and extension should not be updated.
2698 path = data_dir().AppendASCII("good2.crx");
2699 bool updated = service()->UpdateExtension(
2700 extensions::CRXFileInfo(good_crx, path), true, NULL);
2701 ASSERT_FALSE(updated);
2702 ASSERT_EQ(
2703 "1.0.0.0",
2704 service()->GetExtensionById(good_crx, false)->version()->GetString());
2707 // Test updating a not-already-installed extension - this should fail
2708 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
2709 InitializeEmptyExtensionService();
2711 base::FilePath path = data_dir().AppendASCII("good.crx");
2712 UpdateExtension(good_crx, path, UPDATED);
2713 base::RunLoop().RunUntilIdle();
2715 ASSERT_EQ(0u, registry()->enabled_extensions().size());
2716 ASSERT_FALSE(installed_);
2717 ASSERT_EQ(0u, loaded_.size());
2720 // Makes sure you can't downgrade an extension via UpdateExtension
2721 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
2722 InitializeEmptyExtensionService();
2724 base::FilePath path = data_dir().AppendASCII("good2.crx");
2726 const Extension* good = InstallCRX(path, INSTALL_NEW);
2727 ASSERT_EQ("1.0.0.1", good->VersionString());
2728 ASSERT_EQ(good_crx, good->id());
2730 // Change path from good2.crx -> good.crx
2731 path = data_dir().AppendASCII("good.crx");
2732 UpdateExtension(good_crx, path, FAILED);
2733 ASSERT_EQ(
2734 "1.0.0.1",
2735 service()->GetExtensionById(good_crx, false)->version()->GetString());
2738 // Make sure calling update with an identical version does nothing
2739 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
2740 InitializeEmptyExtensionService();
2742 base::FilePath path = data_dir().AppendASCII("good.crx");
2744 const Extension* good = InstallCRX(path, INSTALL_NEW);
2745 ASSERT_EQ(good_crx, good->id());
2746 UpdateExtension(good_crx, path, FAILED_SILENTLY);
2749 // Tests that updating an extension does not clobber old state.
2750 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
2751 InitializeEmptyExtensionService();
2753 base::FilePath path = data_dir().AppendASCII("good.crx");
2755 const Extension* good = InstallCRX(path, INSTALL_NEW);
2756 ASSERT_EQ("1.0.0.0", good->VersionString());
2757 ASSERT_EQ(good_crx, good->id());
2759 // Disable it and allow it to run in incognito. These settings should carry
2760 // over to the updated version.
2761 service()->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
2762 extensions::util::SetIsIncognitoEnabled(good->id(), profile(), true);
2764 path = data_dir().AppendASCII("good2.crx");
2765 UpdateExtension(good_crx, path, INSTALLED);
2766 ASSERT_EQ(1u, registry()->disabled_extensions().size());
2767 const Extension* good2 = service()->GetExtensionById(good_crx, true);
2768 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2769 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good2->id(), profile()));
2770 EXPECT_EQ(Extension::DISABLE_USER_ACTION,
2771 ExtensionPrefs::Get(profile())->GetDisableReasons(good2->id()));
2774 // Tests that updating preserves extension location.
2775 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
2776 InitializeEmptyExtensionService();
2778 base::FilePath path = data_dir().AppendASCII("good.crx");
2780 const Extension* good =
2781 InstallCRXWithLocation(path, Manifest::EXTERNAL_PREF, INSTALL_NEW);
2783 ASSERT_EQ("1.0.0.0", good->VersionString());
2784 ASSERT_EQ(good_crx, good->id());
2786 path = data_dir().AppendASCII("good2.crx");
2787 UpdateExtension(good_crx, path, ENABLED);
2788 const Extension* good2 = service()->GetExtensionById(good_crx, false);
2789 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2790 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
2793 // Makes sure that LOAD extension types can downgrade.
2794 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
2795 InitializeEmptyExtensionService();
2797 base::ScopedTempDir temp;
2798 ASSERT_TRUE(temp.CreateUniqueTempDir());
2800 // We'll write the extension manifest dynamically to a temporary path
2801 // to make it easier to change the version number.
2802 base::FilePath extension_path = temp.path();
2803 base::FilePath manifest_path =
2804 extension_path.Append(extensions::kManifestFilename);
2805 ASSERT_FALSE(base::PathExists(manifest_path));
2807 // Start with version 2.0.
2808 base::DictionaryValue manifest;
2809 manifest.SetString("version", "2.0");
2810 manifest.SetString("name", "LOAD Downgrade Test");
2811 manifest.SetInteger("manifest_version", 2);
2813 JSONFileValueSerializer serializer(manifest_path);
2814 ASSERT_TRUE(serializer.Serialize(manifest));
2816 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2817 base::RunLoop().RunUntilIdle();
2819 EXPECT_EQ(0u, GetErrors().size());
2820 ASSERT_EQ(1u, loaded_.size());
2821 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2822 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2823 EXPECT_EQ("2.0", loaded_[0]->VersionString());
2825 // Now set the version number to 1.0, reload the extensions and verify that
2826 // the downgrade was accepted.
2827 manifest.SetString("version", "1.0");
2828 ASSERT_TRUE(serializer.Serialize(manifest));
2830 extensions::UnpackedInstaller::Create(service())->Load(extension_path);
2831 base::RunLoop().RunUntilIdle();
2833 EXPECT_EQ(0u, GetErrors().size());
2834 ASSERT_EQ(1u, loaded_.size());
2835 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
2836 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2837 EXPECT_EQ("1.0", loaded_[0]->VersionString());
2840 #if !defined(OS_POSIX) || defined(OS_MACOSX)
2841 // LOAD extensions with plugins require approval.
2842 // Only run this on platforms that support NPAPI plugins.
2843 TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
2844 base::FilePath extension_with_plugin_path = good1_path();
2845 base::FilePath extension_no_plugin_path = good2_path();
2847 InitPluginService();
2848 InitializeEmptyExtensionService();
2849 service()->set_show_extensions_prompts(true);
2851 // Start by canceling any install prompts.
2852 ExtensionInstallPrompt::g_auto_confirm_for_tests =
2853 ExtensionInstallPrompt::CANCEL;
2855 // The extension that has a plugin should not install.
2856 extensions::UnpackedInstaller::Create(service())
2857 ->Load(extension_with_plugin_path);
2858 base::RunLoop().RunUntilIdle();
2859 EXPECT_EQ(0u, GetErrors().size());
2860 EXPECT_EQ(0u, loaded_.size());
2861 EXPECT_EQ(0u, registry()->enabled_extensions().size());
2862 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2864 // But the extension with no plugin should since there's no prompt.
2865 ExtensionErrorReporter::GetInstance()->ClearErrors();
2866 extensions::UnpackedInstaller::Create(service())
2867 ->Load(extension_no_plugin_path);
2868 base::RunLoop().RunUntilIdle();
2869 EXPECT_EQ(0u, GetErrors().size());
2870 EXPECT_EQ(1u, loaded_.size());
2871 EXPECT_EQ(1u, registry()->enabled_extensions().size());
2872 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2873 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2875 // The plugin extension should install if we accept the dialog.
2876 ExtensionInstallPrompt::g_auto_confirm_for_tests =
2877 ExtensionInstallPrompt::ACCEPT;
2879 ExtensionErrorReporter::GetInstance()->ClearErrors();
2880 extensions::UnpackedInstaller::Create(service())
2881 ->Load(extension_with_plugin_path);
2882 base::RunLoop().RunUntilIdle();
2883 EXPECT_EQ(0u, GetErrors().size());
2884 EXPECT_EQ(2u, loaded_.size());
2885 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2886 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2887 EXPECT_TRUE(registry()->enabled_extensions().Contains(good1));
2888 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
2890 // Make sure the granted permissions have been setup.
2891 scoped_refptr<PermissionSet> permissions(
2892 ExtensionPrefs::Get(profile())->GetGrantedPermissions(good1));
2893 EXPECT_FALSE(permissions->IsEmpty());
2894 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
2895 EXPECT_FALSE(permissions->apis().empty());
2896 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
2898 // We should be able to reload the extension without getting another prompt.
2899 loaded_.clear();
2900 ExtensionInstallPrompt::g_auto_confirm_for_tests =
2901 ExtensionInstallPrompt::CANCEL;
2903 service()->ReloadExtension(good1);
2904 base::RunLoop().RunUntilIdle();
2905 EXPECT_EQ(1u, loaded_.size());
2906 EXPECT_EQ(2u, registry()->enabled_extensions().size());
2907 EXPECT_EQ(0u, registry()->disabled_extensions().size());
2909 #endif // !defined(OS_POSIX) || defined(OS_MACOSX)
2911 namespace {
2913 bool IsExtension(const Extension* extension) {
2914 return extension->GetType() == Manifest::TYPE_EXTENSION;
2917 #if defined(ENABLE_BLACKLIST_TESTS)
2918 std::set<std::string> StringSet(const std::string& s) {
2919 std::set<std::string> set;
2920 set.insert(s);
2921 return set;
2923 std::set<std::string> StringSet(const std::string& s1, const std::string& s2) {
2924 std::set<std::string> set = StringSet(s1);
2925 set.insert(s2);
2926 return set;
2928 #endif // defined(ENABLE_BLACKLIST_TESTS)
2930 } // namespace
2932 // Test adding a pending extension.
2933 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
2934 InitializeEmptyExtensionService();
2936 const std::string kFakeId(all_zero);
2937 const GURL kFakeUpdateURL("http:://fake.update/url");
2938 const bool kFakeRemoteInstall(false);
2939 const bool kFakeInstalledByCustodian(false);
2941 EXPECT_TRUE(
2942 service()->pending_extension_manager()->AddFromSync(
2943 kFakeId,
2944 kFakeUpdateURL,
2945 &IsExtension,
2946 kFakeRemoteInstall,
2947 kFakeInstalledByCustodian));
2949 const extensions::PendingExtensionInfo* pending_extension_info;
2950 ASSERT_TRUE((pending_extension_info =
2951 service()->pending_extension_manager()->GetById(kFakeId)));
2952 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
2953 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
2954 // Use
2955 // EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install())
2956 // instead of
2957 // EXPECT_EQ(kFakeRemoteInstall, pending_extension_info->remote_install())
2958 // as gcc 4.7 issues the following warning on EXPECT_EQ(false, x), which is
2959 // turned into an error with -Werror=conversion-null:
2960 // converting 'false' to pointer type for argument 1 of
2961 // 'char testing::internal::IsNullLiteralHelper(testing::internal::Secret*)'
2962 // https://code.google.com/p/googletest/issues/detail?id=458
2963 EXPECT_TRUE(kFakeRemoteInstall == pending_extension_info->remote_install());
2966 namespace {
2967 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
2968 const char kGoodUpdateURL[] = "http://good.update/url";
2969 const bool kGoodIsFromSync = true;
2970 const bool kGoodRemoteInstall = false;
2971 const bool kGoodInstalledByCustodian = false;
2972 } // namespace
2974 // Test updating a pending extension.
2975 TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
2976 InitializeEmptyExtensionService();
2977 EXPECT_TRUE(
2978 service()->pending_extension_manager()->AddFromSync(
2979 kGoodId,
2980 GURL(kGoodUpdateURL),
2981 &IsExtension,
2982 kGoodRemoteInstall,
2983 kGoodInstalledByCustodian));
2984 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2986 base::FilePath path = data_dir().AppendASCII("good.crx");
2987 UpdateExtension(kGoodId, path, ENABLED);
2989 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
2991 const Extension* extension = service()->GetExtensionById(kGoodId, true);
2992 ASSERT_TRUE(extension);
2995 namespace {
2997 bool IsTheme(const Extension* extension) {
2998 return extension->is_theme();
3001 } // namespace
3003 // Test updating a pending theme.
3004 // Disabled due to ASAN failure. http://crbug.com/108320
3005 TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
3006 InitializeEmptyExtensionService();
3007 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3008 theme_crx, GURL(), &IsTheme, false, false));
3009 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3011 base::FilePath path = data_dir().AppendASCII("theme.crx");
3012 UpdateExtension(theme_crx, path, ENABLED);
3014 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3016 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3017 ASSERT_TRUE(extension);
3019 EXPECT_FALSE(
3020 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3021 EXPECT_TRUE(service()->IsExtensionEnabled(theme_crx));
3024 #if defined(OS_CHROMEOS)
3025 // Always fails on ChromeOS: http://crbug.com/79737
3026 #define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
3027 #else
3028 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
3029 #endif
3030 // Test updating a pending CRX as if the source is an external extension
3031 // with an update URL. In this case we don't know if the CRX is a theme
3032 // or not.
3033 TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
3034 InitializeEmptyExtensionService();
3035 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3036 theme_crx,
3037 std::string(),
3038 GURL(),
3039 Manifest::EXTERNAL_PREF_DOWNLOAD,
3040 Extension::NO_FLAGS,
3041 false));
3043 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3045 base::FilePath path = data_dir().AppendASCII("theme.crx");
3046 UpdateExtension(theme_crx, path, ENABLED);
3048 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3050 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3051 ASSERT_TRUE(extension);
3053 EXPECT_FALSE(
3054 ExtensionPrefs::Get(profile())->IsExtensionDisabled(extension->id()));
3055 EXPECT_TRUE(service()->IsExtensionEnabled(extension->id()));
3056 EXPECT_FALSE(
3057 extensions::util::IsIncognitoEnabled(extension->id(), profile()));
3060 // Test updating a pending CRX as if the source is an external extension
3061 // with an update URL. The external update should overwrite a sync update,
3062 // but a sync update should not overwrite a non-sync update.
3063 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
3064 InitializeEmptyExtensionService();
3066 // Add a crx to be installed from the update mechanism.
3067 EXPECT_TRUE(
3068 service()->pending_extension_manager()->AddFromSync(
3069 kGoodId,
3070 GURL(kGoodUpdateURL),
3071 &IsExtension,
3072 kGoodRemoteInstall,
3073 kGoodInstalledByCustodian));
3075 // Check that there is a pending crx, with is_from_sync set to true.
3076 const extensions::PendingExtensionInfo* pending_extension_info;
3077 ASSERT_TRUE((pending_extension_info =
3078 service()->pending_extension_manager()->GetById(kGoodId)));
3079 EXPECT_TRUE(pending_extension_info->is_from_sync());
3081 // Add a crx to be updated, with the same ID, from a non-sync source.
3082 EXPECT_TRUE(service()->pending_extension_manager()->AddFromExternalUpdateUrl(
3083 kGoodId,
3084 std::string(),
3085 GURL(kGoodUpdateURL),
3086 Manifest::EXTERNAL_PREF_DOWNLOAD,
3087 Extension::NO_FLAGS,
3088 false));
3090 // Check that there is a pending crx, with is_from_sync set to false.
3091 ASSERT_TRUE((pending_extension_info =
3092 service()->pending_extension_manager()->GetById(kGoodId)));
3093 EXPECT_FALSE(pending_extension_info->is_from_sync());
3094 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3095 pending_extension_info->install_source());
3097 // Add a crx to be installed from the update mechanism.
3098 EXPECT_FALSE(
3099 service()->pending_extension_manager()->AddFromSync(
3100 kGoodId,
3101 GURL(kGoodUpdateURL),
3102 &IsExtension,
3103 kGoodRemoteInstall,
3104 kGoodInstalledByCustodian));
3106 // Check that the external, non-sync update was not overridden.
3107 ASSERT_TRUE((pending_extension_info =
3108 service()->pending_extension_manager()->GetById(kGoodId)));
3109 EXPECT_FALSE(pending_extension_info->is_from_sync());
3110 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3111 pending_extension_info->install_source());
3114 // Updating a theme should fail if the updater is explicitly told that
3115 // the CRX is not a theme.
3116 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
3117 InitializeEmptyExtensionService();
3118 EXPECT_TRUE(service()->pending_extension_manager()->AddFromSync(
3119 theme_crx, GURL(), &IsExtension, false, false));
3121 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3123 base::FilePath path = data_dir().AppendASCII("theme.crx");
3124 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
3126 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(theme_crx));
3128 const Extension* extension = service()->GetExtensionById(theme_crx, true);
3129 ASSERT_FALSE(extension);
3132 // TODO(akalin): Test updating a pending extension non-silently once
3133 // we can mock out ExtensionInstallUI and inject our version into
3134 // UpdateExtension().
3136 // Test updating a pending extension which fails the should-install test.
3137 TEST_F(ExtensionServiceTest, UpdatePendingExtensionFailedShouldInstallTest) {
3138 InitializeEmptyExtensionService();
3139 // Add pending extension with a flipped is_theme.
3140 EXPECT_TRUE(
3141 service()->pending_extension_manager()->AddFromSync(
3142 kGoodId,
3143 GURL(kGoodUpdateURL),
3144 &IsTheme,
3145 kGoodRemoteInstall,
3146 kGoodInstalledByCustodian));
3147 EXPECT_TRUE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3149 base::FilePath path = data_dir().AppendASCII("good.crx");
3150 UpdateExtension(kGoodId, path, UPDATED);
3152 // TODO(akalin): Figure out how to check that the extensions
3153 // directory is cleaned up properly in OnExtensionInstalled().
3155 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3158 // TODO(akalin): Figure out how to test that installs of pending
3159 // unsyncable extensions are blocked.
3161 // Test updating a pending extension for one that is not pending.
3162 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
3163 InitializeEmptyExtensionService();
3165 base::FilePath path = data_dir().AppendASCII("good.crx");
3166 UpdateExtension(kGoodId, path, UPDATED);
3168 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3171 // Test updating a pending extension for one that is already
3172 // installed.
3173 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
3174 InitializeEmptyExtensionService();
3176 base::FilePath path = data_dir().AppendASCII("good.crx");
3177 const Extension* good = InstallCRX(path, INSTALL_NEW);
3178 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3180 EXPECT_FALSE(good->is_theme());
3182 // Use AddExtensionImpl() as AddFrom*() would balk.
3183 service()->pending_extension_manager()->AddExtensionImpl(
3184 good->id(),
3185 std::string(),
3186 extensions::ManifestURL::GetUpdateURL(good),
3187 Version(),
3188 &IsExtension,
3189 kGoodIsFromSync,
3190 Manifest::INTERNAL,
3191 Extension::NO_FLAGS,
3192 false,
3193 kGoodRemoteInstall);
3194 UpdateExtension(good->id(), path, ENABLED);
3196 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(kGoodId));
3199 #if defined(ENABLE_BLACKLIST_TESTS)
3200 // Tests blacklisting then unblacklisting extensions after the service has been
3201 // initialized.
3202 TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
3203 extensions::TestBlacklist test_blacklist;
3204 // A profile with 3 extensions installed: good0, good1, and good2.
3205 InitializeGoodInstalledExtensionService();
3206 test_blacklist.Attach(service()->blacklist_);
3207 service()->Init();
3209 const extensions::ExtensionSet& enabled_extensions =
3210 registry()->enabled_extensions();
3211 const extensions::ExtensionSet& blacklisted_extensions =
3212 registry()->blacklisted_extensions();
3214 EXPECT_TRUE(enabled_extensions.Contains(good0) &&
3215 !blacklisted_extensions.Contains(good0));
3216 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3217 !blacklisted_extensions.Contains(good1));
3218 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3219 !blacklisted_extensions.Contains(good2));
3221 EXPECT_FALSE(IsPrefExist(good0, "blacklist"));
3222 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3223 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3224 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3226 // Blacklist good0 and good1 (and an invalid extension ID).
3227 test_blacklist.SetBlacklistState(
3228 good0, extensions::BLACKLISTED_MALWARE, true);
3229 test_blacklist.SetBlacklistState(
3230 good1, extensions::BLACKLISTED_MALWARE, true);
3231 test_blacklist.SetBlacklistState(
3232 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3233 base::RunLoop().RunUntilIdle();
3235 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3236 blacklisted_extensions.Contains(good0));
3237 EXPECT_TRUE(!enabled_extensions.Contains(good1) &&
3238 blacklisted_extensions.Contains(good1));
3239 EXPECT_TRUE(enabled_extensions.Contains(good2) &&
3240 !blacklisted_extensions.Contains(good2));
3242 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3243 EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true));
3244 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3245 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3247 // Un-blacklist good1 and blacklist good2.
3248 test_blacklist.Clear(false);
3249 test_blacklist.SetBlacklistState(
3250 good0, extensions::BLACKLISTED_MALWARE, true);
3251 test_blacklist.SetBlacklistState(
3252 good2, extensions::BLACKLISTED_MALWARE, true);
3253 test_blacklist.SetBlacklistState(
3254 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3255 base::RunLoop().RunUntilIdle();
3257 EXPECT_TRUE(!enabled_extensions.Contains(good0) &&
3258 blacklisted_extensions.Contains(good0));
3259 EXPECT_TRUE(enabled_extensions.Contains(good1) &&
3260 !blacklisted_extensions.Contains(good1));
3261 EXPECT_TRUE(!enabled_extensions.Contains(good2) &&
3262 blacklisted_extensions.Contains(good2));
3264 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3265 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3266 EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true));
3267 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3269 #endif // defined(ENABLE_BLACKLIST_TESTS)
3271 #if defined(ENABLE_BLACKLIST_TESTS)
3272 // Tests trying to install a blacklisted extension.
3273 TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
3274 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3275 new FakeSafeBrowsingDatabaseManager(true));
3276 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3278 InitializeEmptyExtensionService();
3279 service()->Init();
3281 // After blacklisting good_crx, we cannot install it.
3282 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
3283 base::RunLoop().RunUntilIdle();
3285 base::FilePath path = data_dir().AppendASCII("good.crx");
3286 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3287 // decide to install this silently. Somebody should fix these tests, all
3288 // 6,000 lines of them. Hah!
3289 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
3290 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3292 #endif // defined(ENABLE_BLACKLIST_TESTS)
3294 #if defined(ENABLE_BLACKLIST_TESTS)
3295 // Unload blacklisted extension on policy change.
3296 TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
3297 extensions::TestBlacklist test_blacklist;
3299 // A profile with no extensions installed.
3300 InitializeEmptyExtensionServiceWithTestingPrefs();
3301 test_blacklist.Attach(service()->blacklist_);
3303 base::FilePath path = data_dir().AppendASCII("good.crx");
3305 const Extension* good = InstallCRX(path, INSTALL_NEW);
3306 EXPECT_EQ(good_crx, good->id());
3307 UpdateExtension(good_crx, path, FAILED_SILENTLY);
3308 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3311 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3312 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3315 test_blacklist.SetBlacklistState(
3316 good_crx, extensions::BLACKLISTED_MALWARE, true);
3317 base::RunLoop().RunUntilIdle();
3319 // The good_crx is blacklisted and the whitelist doesn't negate it.
3320 ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true));
3321 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3323 #endif // defined(ENABLE_BLACKLIST_TESTS)
3325 #if defined(ENABLE_BLACKLIST_TESTS)
3326 // Tests that a blacklisted extension is eventually unloaded on startup, if it
3327 // wasn't already.
3328 TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
3329 extensions::TestBlacklist test_blacklist;
3331 // A profile with 3 extensions installed: good0, good1, and good2.
3332 InitializeGoodInstalledExtensionService();
3333 test_blacklist.Attach(service()->blacklist_);
3335 // Blacklist good1 before the service initializes.
3336 test_blacklist.SetBlacklistState(
3337 good1, extensions::BLACKLISTED_MALWARE, false);
3339 // Load extensions.
3340 service()->Init();
3341 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet
3343 base::RunLoop().RunUntilIdle();
3345 ASSERT_EQ(1u, registry()->blacklisted_extensions().size());
3346 ASSERT_EQ(2u, registry()->enabled_extensions().size());
3348 ASSERT_TRUE(registry()->enabled_extensions().Contains(good0));
3349 ASSERT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3350 ASSERT_TRUE(registry()->enabled_extensions().Contains(good2));
3352 #endif // defined(ENABLE_BLACKLIST_TESTS)
3354 #if defined(ENABLE_BLACKLIST_TESTS)
3355 // Tests extensions blacklisted in prefs on startup; one still blacklisted by
3356 // safe browsing, the other not. The not-blacklisted one should recover.
3357 TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) {
3358 extensions::TestBlacklist test_blacklist;
3360 InitializeGoodInstalledExtensionService();
3361 test_blacklist.Attach(service()->blacklist_);
3362 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good0, true);
3363 ExtensionPrefs::Get(profile())->SetExtensionBlacklisted(good1, true);
3365 test_blacklist.SetBlacklistState(
3366 good1, extensions::BLACKLISTED_MALWARE, false);
3368 // Extension service hasn't loaded yet, but IsExtensionEnabled reads out of
3369 // prefs. Ensure it takes into account the blacklist state (crbug.com/373842).
3370 EXPECT_FALSE(service()->IsExtensionEnabled(good0));
3371 EXPECT_FALSE(service()->IsExtensionEnabled(good1));
3372 EXPECT_TRUE(service()->IsExtensionEnabled(good2));
3374 service()->Init();
3376 EXPECT_EQ(2u, registry()->blacklisted_extensions().size());
3377 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3379 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good0));
3380 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3381 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3383 // Give time for the blacklist to update.
3384 base::RunLoop().RunUntilIdle();
3386 EXPECT_EQ(1u, registry()->blacklisted_extensions().size());
3387 EXPECT_EQ(2u, registry()->enabled_extensions().size());
3389 EXPECT_TRUE(registry()->enabled_extensions().Contains(good0));
3390 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(good1));
3391 EXPECT_TRUE(registry()->enabled_extensions().Contains(good2));
3393 #endif // defined(ENABLE_BLACKLIST_TESTS)
3395 #if defined(ENABLE_BLACKLIST_TESTS)
3396 // Extension is added to blacklist with BLACKLISTED_POTENTIALLY_UNWANTED state
3397 // after it is installed. It is then successfully re-enabled by the user.
3398 TEST_F(ExtensionServiceTest, GreylistedExtensionDisabled) {
3399 extensions::TestBlacklist test_blacklist;
3400 // A profile with 3 extensions installed: good0, good1, and good2.
3401 InitializeGoodInstalledExtensionService();
3402 test_blacklist.Attach(service()->blacklist_);
3403 service()->Init();
3405 const extensions::ExtensionSet& enabled_extensions =
3406 registry()->enabled_extensions();
3407 const extensions::ExtensionSet& disabled_extensions =
3408 registry()->disabled_extensions();
3410 EXPECT_TRUE(enabled_extensions.Contains(good0));
3411 EXPECT_TRUE(enabled_extensions.Contains(good1));
3412 EXPECT_TRUE(enabled_extensions.Contains(good2));
3414 // Blacklist good0 and good1 (and an invalid extension ID).
3415 test_blacklist.SetBlacklistState(
3416 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3417 test_blacklist.SetBlacklistState(
3418 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3419 test_blacklist.SetBlacklistState(
3420 "invalid_id", extensions::BLACKLISTED_MALWARE, true);
3421 base::RunLoop().RunUntilIdle();
3423 EXPECT_FALSE(enabled_extensions.Contains(good0));
3424 EXPECT_TRUE(disabled_extensions.Contains(good0));
3425 EXPECT_FALSE(enabled_extensions.Contains(good1));
3426 EXPECT_TRUE(disabled_extensions.Contains(good1));
3427 EXPECT_TRUE(enabled_extensions.Contains(good2));
3428 EXPECT_FALSE(disabled_extensions.Contains(good2));
3430 ValidateIntegerPref(
3431 good0, "blacklist_state", extensions::BLACKLISTED_CWS_POLICY_VIOLATION);
3432 ValidateIntegerPref(
3433 good1, "blacklist_state", extensions::BLACKLISTED_POTENTIALLY_UNWANTED);
3435 // Now user enables good0.
3436 service()->EnableExtension(good0);
3438 EXPECT_TRUE(enabled_extensions.Contains(good0));
3439 EXPECT_FALSE(disabled_extensions.Contains(good0));
3440 EXPECT_FALSE(enabled_extensions.Contains(good1));
3441 EXPECT_TRUE(disabled_extensions.Contains(good1));
3443 // Remove extensions from blacklist.
3444 test_blacklist.SetBlacklistState(
3445 good0, extensions::NOT_BLACKLISTED, true);
3446 test_blacklist.SetBlacklistState(
3447 good1, extensions::NOT_BLACKLISTED, true);
3448 base::RunLoop().RunUntilIdle();
3450 // All extensions are enabled.
3451 EXPECT_TRUE(enabled_extensions.Contains(good0));
3452 EXPECT_FALSE(disabled_extensions.Contains(good0));
3453 EXPECT_TRUE(enabled_extensions.Contains(good1));
3454 EXPECT_FALSE(disabled_extensions.Contains(good1));
3455 EXPECT_TRUE(enabled_extensions.Contains(good2));
3456 EXPECT_FALSE(disabled_extensions.Contains(good2));
3458 #endif // defined(ENABLE_BLACKLIST_TESTS)
3460 #if defined(ENABLE_BLACKLIST_TESTS)
3461 // When extension is removed from greylist, do not re-enable it if it is
3462 // disabled by user.
3463 TEST_F(ExtensionServiceTest, GreylistDontEnableManuallyDisabled) {
3464 extensions::TestBlacklist test_blacklist;
3465 // A profile with 3 extensions installed: good0, good1, and good2.
3466 InitializeGoodInstalledExtensionService();
3467 test_blacklist.Attach(service()->blacklist_);
3468 service()->Init();
3470 const extensions::ExtensionSet& enabled_extensions =
3471 registry()->enabled_extensions();
3472 const extensions::ExtensionSet& disabled_extensions =
3473 registry()->disabled_extensions();
3475 // Manually disable.
3476 service()->DisableExtension(good0,
3477 extensions::Extension::DISABLE_USER_ACTION);
3479 test_blacklist.SetBlacklistState(
3480 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3481 test_blacklist.SetBlacklistState(
3482 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3483 test_blacklist.SetBlacklistState(
3484 good2, extensions::BLACKLISTED_SECURITY_VULNERABILITY, true);
3485 base::RunLoop().RunUntilIdle();
3487 // All extensions disabled.
3488 EXPECT_FALSE(enabled_extensions.Contains(good0));
3489 EXPECT_TRUE(disabled_extensions.Contains(good0));
3490 EXPECT_FALSE(enabled_extensions.Contains(good1));
3491 EXPECT_TRUE(disabled_extensions.Contains(good1));
3492 EXPECT_FALSE(enabled_extensions.Contains(good2));
3493 EXPECT_TRUE(disabled_extensions.Contains(good2));
3495 // Greylisted extension can be enabled.
3496 service()->EnableExtension(good1);
3497 EXPECT_TRUE(enabled_extensions.Contains(good1));
3498 EXPECT_FALSE(disabled_extensions.Contains(good1));
3500 // good1 is now manually disabled.
3501 service()->DisableExtension(good1,
3502 extensions::Extension::DISABLE_USER_ACTION);
3503 EXPECT_FALSE(enabled_extensions.Contains(good1));
3504 EXPECT_TRUE(disabled_extensions.Contains(good1));
3506 // Remove extensions from blacklist.
3507 test_blacklist.SetBlacklistState(
3508 good0, extensions::NOT_BLACKLISTED, true);
3509 test_blacklist.SetBlacklistState(
3510 good1, extensions::NOT_BLACKLISTED, true);
3511 test_blacklist.SetBlacklistState(
3512 good2, extensions::NOT_BLACKLISTED, true);
3513 base::RunLoop().RunUntilIdle();
3515 // good0 and good1 remain disabled.
3516 EXPECT_FALSE(enabled_extensions.Contains(good0));
3517 EXPECT_TRUE(disabled_extensions.Contains(good0));
3518 EXPECT_FALSE(enabled_extensions.Contains(good1));
3519 EXPECT_TRUE(disabled_extensions.Contains(good1));
3520 EXPECT_TRUE(enabled_extensions.Contains(good2));
3521 EXPECT_FALSE(disabled_extensions.Contains(good2));
3523 #endif // defined(ENABLE_BLACKLIST_TESTS)
3525 #if defined(ENABLE_BLACKLIST_TESTS)
3526 // Blacklisted extension with unknown state are not enabled/disabled.
3527 TEST_F(ExtensionServiceTest, GreylistUnknownDontChange) {
3528 extensions::TestBlacklist test_blacklist;
3529 // A profile with 3 extensions installed: good0, good1, and good2.
3530 InitializeGoodInstalledExtensionService();
3531 test_blacklist.Attach(service()->blacklist_);
3532 service()->Init();
3534 const extensions::ExtensionSet& enabled_extensions =
3535 registry()->enabled_extensions();
3536 const extensions::ExtensionSet& disabled_extensions =
3537 registry()->disabled_extensions();
3539 test_blacklist.SetBlacklistState(
3540 good0, extensions::BLACKLISTED_CWS_POLICY_VIOLATION, true);
3541 test_blacklist.SetBlacklistState(
3542 good1, extensions::BLACKLISTED_POTENTIALLY_UNWANTED, true);
3543 base::RunLoop().RunUntilIdle();
3545 EXPECT_FALSE(enabled_extensions.Contains(good0));
3546 EXPECT_TRUE(disabled_extensions.Contains(good0));
3547 EXPECT_FALSE(enabled_extensions.Contains(good1));
3548 EXPECT_TRUE(disabled_extensions.Contains(good1));
3549 EXPECT_TRUE(enabled_extensions.Contains(good2));
3550 EXPECT_FALSE(disabled_extensions.Contains(good2));
3552 test_blacklist.SetBlacklistState(
3553 good0, extensions::NOT_BLACKLISTED, true);
3554 test_blacklist.SetBlacklistState(
3555 good1, extensions::BLACKLISTED_UNKNOWN, true);
3556 test_blacklist.SetBlacklistState(
3557 good2, extensions::BLACKLISTED_UNKNOWN, true);
3558 base::RunLoop().RunUntilIdle();
3560 // good0 re-enabled, other remain as they were.
3561 EXPECT_TRUE(enabled_extensions.Contains(good0));
3562 EXPECT_FALSE(disabled_extensions.Contains(good0));
3563 EXPECT_FALSE(enabled_extensions.Contains(good1));
3564 EXPECT_TRUE(disabled_extensions.Contains(good1));
3565 EXPECT_TRUE(enabled_extensions.Contains(good2));
3566 EXPECT_FALSE(disabled_extensions.Contains(good2));
3569 // Tests that blacklisted extensions cannot be reloaded, both those loaded
3570 // before and after extension service startup.
3571 TEST_F(ExtensionServiceTest, ReloadBlacklistedExtension) {
3572 extensions::TestBlacklist test_blacklist;
3574 InitializeGoodInstalledExtensionService();
3575 test_blacklist.Attach(service()->blacklist_);
3577 test_blacklist.SetBlacklistState(
3578 good1, extensions::BLACKLISTED_MALWARE, false);
3579 service()->Init();
3580 test_blacklist.SetBlacklistState(
3581 good2, extensions::BLACKLISTED_MALWARE, false);
3582 base::RunLoop().RunUntilIdle();
3584 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3585 EXPECT_EQ(StringSet(good1, good2),
3586 registry()->blacklisted_extensions().GetIDs());
3588 service()->ReloadExtension(good1);
3589 service()->ReloadExtension(good2);
3590 base::RunLoop().RunUntilIdle();
3592 EXPECT_EQ(StringSet(good0), registry()->enabled_extensions().GetIDs());
3593 EXPECT_EQ(StringSet(good1, good2),
3594 registry()->blacklisted_extensions().GetIDs());
3596 #endif // defined(ENABLE_BLACKLIST_TESTS)
3598 // Tests blocking then unblocking enabled extensions after the service has been
3599 // initialized.
3600 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledExtension) {
3601 InitializeGoodInstalledExtensionService();
3602 service()->Init();
3604 AssertExtensionBlocksAndUnblocks(true, good0);
3607 // Tests blocking then unblocking disabled extensions after the service has been
3608 // initialized.
3609 TEST_F(ExtensionServiceTest, BlockAndUnblockDisabledExtension) {
3610 InitializeGoodInstalledExtensionService();
3611 service()->Init();
3613 service()->DisableExtension(good0, Extension::DISABLE_RELOAD);
3615 AssertExtensionBlocksAndUnblocks(true, good0);
3618 // Tests blocking then unblocking terminated extensions after the service has
3619 // been initialized.
3620 TEST_F(ExtensionServiceTest, BlockAndUnblockTerminatedExtension) {
3621 InitializeGoodInstalledExtensionService();
3622 service()->Init();
3624 TerminateExtension(good0);
3626 AssertExtensionBlocksAndUnblocks(true, good0);
3629 // Tests blocking then unblocking policy-forced extensions after the service has
3630 // been initialized.
3631 TEST_F(ExtensionServiceTest, BlockAndUnblockPolicyExtension) {
3632 InitializeEmptyExtensionServiceWithTestingPrefs();
3635 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3636 // // Blacklist everything.
3637 // pref.SetBlacklistedByDefault(true);
3638 // Mark good.crx for force-installation.
3639 pref.SetIndividualExtensionAutoInstalled(
3640 good_crx, "http://example.com/update_url", true);
3643 // Have policy force-install an extension.
3644 MockExtensionProvider* provider =
3645 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3646 AddMockExternalProvider(provider);
3647 provider->UpdateOrAddExtension(
3648 good_crx, "1.0.0.0", data_dir().AppendASCII("good_crx"));
3650 // Reloading extensions should find our externally registered extension
3651 // and install it.
3652 content::WindowedNotificationObserver observer(
3653 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3654 content::NotificationService::AllSources());
3655 service()->CheckForExternalUpdates();
3656 observer.Wait();
3658 AssertExtensionBlocksAndUnblocks(false, good_crx);
3662 #if defined(ENABLE_BLACKLIST_TESTS)
3663 // Tests blocking then unblocking extensions that are blacklisted both before
3664 // and after Init().
3665 TEST_F(ExtensionServiceTest, BlockAndUnblockBlacklistedExtension) {
3666 extensions::TestBlacklist test_blacklist;
3668 InitializeGoodInstalledExtensionService();
3669 test_blacklist.Attach(service()->blacklist_);
3671 test_blacklist.SetBlacklistState(
3672 good0, extensions::BLACKLISTED_MALWARE, true);
3673 base::RunLoop().RunUntilIdle();
3675 service()->Init();
3677 test_blacklist.SetBlacklistState(
3678 good1, extensions::BLACKLISTED_MALWARE, true);
3679 base::RunLoop().RunUntilIdle();
3681 // Blacklisted extensions stay blacklisted.
3682 AssertExtensionBlocksAndUnblocks(false, good0);
3683 AssertExtensionBlocksAndUnblocks(false, good1);
3685 service()->BlockAllExtensions();
3687 // Remove an extension from the blacklist while the service is blocked.
3688 test_blacklist.SetBlacklistState(
3689 good0, extensions::NOT_BLACKLISTED, true);
3690 // Add an extension to the blacklist while the service is blocked.
3691 test_blacklist.SetBlacklistState(
3692 good2, extensions::BLACKLISTED_MALWARE, true);
3693 base::RunLoop().RunUntilIdle();
3695 // Go directly to blocked, do not pass go, do not collect $200.
3696 ASSERT_TRUE(IsBlocked(good0));
3697 // Get on the blacklist - even if you were blocked!
3698 ASSERT_FALSE(IsBlocked(good2));
3700 #endif // defined(ENABLE_BLACKLIST_TESTS)
3702 // Tests blocking then unblocking enabled component extensions after the service
3703 // has been initialized.
3704 TEST_F(ExtensionServiceTest, BlockAndUnblockEnabledComponentExtension) {
3705 InitializeEmptyExtensionServiceWithTestingPrefs();
3707 // Install a component extension.
3708 base::FilePath path = data_dir()
3709 .AppendASCII("good")
3710 .AppendASCII("Extensions")
3711 .AppendASCII(good0)
3712 .AppendASCII("1.0.0.0");
3713 std::string manifest;
3714 ASSERT_TRUE(base::ReadFileToString(
3715 path.Append(extensions::kManifestFilename), &manifest));
3716 service()->component_loader()->Add(manifest, path);
3717 service()->Init();
3719 // Component extension should never block.
3720 AssertExtensionBlocksAndUnblocks(false, good0);
3723 // Tests blocking then unblocking a theme after the service has been
3724 // initialized.
3725 TEST_F(ExtensionServiceTest, BlockAndUnblockTheme) {
3726 InitializeEmptyExtensionService();
3727 service()->Init();
3729 base::FilePath path = data_dir().AppendASCII("theme.crx");
3730 InstallCRX(path, INSTALL_NEW);
3732 AssertExtensionBlocksAndUnblocks(true, theme_crx);
3735 // Tests that blocking extensions before Init() results in loading blocked
3736 // extensions.
3737 TEST_F(ExtensionServiceTest, WillNotLoadExtensionsWhenBlocked) {
3738 InitializeGoodInstalledExtensionService();
3740 service()->BlockAllExtensions();
3742 service()->Init();
3744 ASSERT_TRUE(IsBlocked(good0));
3745 ASSERT_TRUE(IsBlocked(good0));
3746 ASSERT_TRUE(IsBlocked(good0));
3749 // Tests that IsEnabledExtension won't crash on an uninstalled extension.
3750 TEST_F(ExtensionServiceTest, IsEnabledExtensionBlockedAndNotInstalled) {
3751 InitializeEmptyExtensionService();
3753 service()->BlockAllExtensions();
3755 service()->IsExtensionEnabled(theme_crx);
3758 // Will not install extension blacklisted by policy.
3759 TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
3760 InitializeEmptyExtensionServiceWithTestingPrefs();
3762 // Blacklist everything.
3764 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3765 pref.SetBlacklistedByDefault(true);
3768 // Blacklist prevents us from installing good_crx.
3769 base::FilePath path = data_dir().AppendASCII("good.crx");
3770 InstallCRX(path, INSTALL_FAILED);
3771 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3773 // Now whitelist this particular extension.
3775 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3776 pref.SetIndividualExtensionInstallationAllowed(good_crx, true);
3779 // Ensure we can now install good_crx.
3780 InstallCRX(path, INSTALL_NEW);
3781 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3784 // Extension blacklisted by policy get unloaded after installing.
3785 TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
3786 InitializeEmptyExtensionServiceWithTestingPrefs();
3788 // Install good_crx.
3789 base::FilePath path = data_dir().AppendASCII("good.crx");
3790 InstallCRX(path, INSTALL_NEW);
3791 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3794 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3795 // Blacklist this extension.
3796 pref.SetIndividualExtensionInstallationAllowed(good_crx, false);
3799 // Extension should not be running now.
3800 base::RunLoop().RunUntilIdle();
3801 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3804 // Tests that component extensions are not blacklisted by policy.
3805 TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
3806 InitializeEmptyExtensionServiceWithTestingPrefs();
3808 // Blacklist everything.
3810 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3811 pref.SetBlacklistedByDefault(true);
3814 // Install a component extension.
3815 base::FilePath path = data_dir()
3816 .AppendASCII("good")
3817 .AppendASCII("Extensions")
3818 .AppendASCII(good0)
3819 .AppendASCII("1.0.0.0");
3820 std::string manifest;
3821 ASSERT_TRUE(base::ReadFileToString(
3822 path.Append(extensions::kManifestFilename), &manifest));
3823 service()->component_loader()->Add(manifest, path);
3824 service()->Init();
3826 // Extension should be installed despite blacklist.
3827 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3828 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3830 // Poke external providers and make sure the extension is still present.
3831 service()->CheckForExternalUpdates();
3832 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3833 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3835 // Extension should not be uninstalled on blacklist changes.
3837 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3838 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3840 base::RunLoop().RunUntilIdle();
3841 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3842 EXPECT_TRUE(service()->GetExtensionById(good0, false));
3845 // Tests that policy-installed extensions are not blacklisted by policy.
3846 TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
3847 InitializeEmptyExtensionServiceWithTestingPrefs();
3850 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3851 // Blacklist everything.
3852 pref.SetBlacklistedByDefault(true);
3853 // Mark good.crx for force-installation.
3854 pref.SetIndividualExtensionAutoInstalled(
3855 good_crx, "http://example.com/update_url", true);
3858 // Have policy force-install an extension.
3859 MockExtensionProvider* provider =
3860 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
3861 AddMockExternalProvider(provider);
3862 provider->UpdateOrAddExtension(
3863 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
3865 // Reloading extensions should find our externally registered extension
3866 // and install it.
3867 content::WindowedNotificationObserver observer(
3868 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
3869 content::NotificationService::AllSources());
3870 service()->CheckForExternalUpdates();
3871 observer.Wait();
3873 // Extension should be installed despite blacklist.
3874 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3875 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3877 // Blacklist update should not uninstall the extension.
3879 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
3880 pref.SetIndividualExtensionInstallationAllowed(good0, false);
3882 base::RunLoop().RunUntilIdle();
3883 ASSERT_EQ(1u, registry()->enabled_extensions().size());
3884 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3887 // Tests that extensions cannot be installed if the policy provider prohibits
3888 // it. This functionality is implemented in CrxInstaller::ConfirmInstall().
3889 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
3890 InitializeEmptyExtensionService();
3892 GetManagementPolicy()->UnregisterAllProviders();
3893 extensions::TestManagementPolicyProvider provider_(
3894 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3895 GetManagementPolicy()->RegisterProvider(&provider_);
3897 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_FAILED);
3898 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3901 // Tests that extensions cannot be loaded from prefs if the policy provider
3902 // prohibits it. This functionality is implemented in InstalledLoader::Load().
3903 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
3904 InitializeEmptyExtensionService();
3906 // Create a fake extension to be loaded as though it were read from prefs.
3907 base::FilePath path =
3908 data_dir().AppendASCII("management").AppendASCII("simple_extension");
3909 base::DictionaryValue manifest;
3910 manifest.SetString(keys::kName, "simple_extension");
3911 manifest.SetString(keys::kVersion, "1");
3912 // UNPACKED is for extensions loaded from a directory. We use it here, even
3913 // though we're testing loading from prefs, so that we don't need to provide
3914 // an extension key.
3915 extensions::ExtensionInfo extension_info(
3916 &manifest, std::string(), path, Manifest::UNPACKED);
3918 // Ensure we can load it with no management policy in place.
3919 GetManagementPolicy()->UnregisterAllProviders();
3920 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3921 extensions::InstalledLoader(service()).Load(extension_info, false);
3922 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3924 const Extension* extension =
3925 (registry()->enabled_extensions().begin())->get();
3926 EXPECT_TRUE(
3927 service()->UninstallExtension(extension->id(),
3928 extensions::UNINSTALL_REASON_FOR_TESTING,
3929 base::Bind(&base::DoNothing),
3930 NULL));
3931 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3933 // Ensure we cannot load it if management policy prohibits installation.
3934 extensions::TestManagementPolicyProvider provider_(
3935 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3936 GetManagementPolicy()->RegisterProvider(&provider_);
3938 extensions::InstalledLoader(service()).Load(extension_info, false);
3939 EXPECT_EQ(0u, registry()->enabled_extensions().size());
3942 // Tests disabling an extension when prohibited by the ManagementPolicy.
3943 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
3944 InitializeEmptyExtensionService();
3946 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3947 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3948 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3950 GetManagementPolicy()->UnregisterAllProviders();
3951 extensions::TestManagementPolicyProvider provider(
3952 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3953 GetManagementPolicy()->RegisterProvider(&provider);
3955 // Attempt to disable it.
3956 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3958 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3959 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3960 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3963 // Tests uninstalling an extension when prohibited by the ManagementPolicy.
3964 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
3965 InitializeEmptyExtensionService();
3967 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3968 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3969 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3971 GetManagementPolicy()->UnregisterAllProviders();
3972 extensions::TestManagementPolicyProvider provider(
3973 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3974 GetManagementPolicy()->RegisterProvider(&provider);
3976 // Attempt to uninstall it.
3977 EXPECT_FALSE(
3978 service()->UninstallExtension(good_crx,
3979 extensions::UNINSTALL_REASON_FOR_TESTING,
3980 base::Bind(&base::DoNothing),
3981 NULL));
3983 EXPECT_EQ(1u, registry()->enabled_extensions().size());
3984 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
3987 // Tests that previously installed extensions that are now prohibited from
3988 // being installed are removed.
3989 TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
3990 InitializeEmptyExtensionService();
3992 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
3993 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
3994 EXPECT_EQ(2u, registry()->enabled_extensions().size());
3995 EXPECT_EQ(0u, registry()->disabled_extensions().size());
3997 GetManagementPolicy()->UnregisterAllProviders();
3998 extensions::TestManagementPolicyProvider provider(
3999 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
4000 GetManagementPolicy()->RegisterProvider(&provider);
4002 // Run the policy check.
4003 service()->CheckManagementPolicy();
4004 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4005 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4008 // Tests that previously disabled extensions that are now required to be
4009 // enabled are re-enabled on reinstall.
4010 TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
4011 InitializeEmptyExtensionService();
4013 // Install, then disable, an extension.
4014 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4015 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4016 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4017 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4019 // Register an ExtensionManagementPolicy that requires the extension to remain
4020 // enabled.
4021 GetManagementPolicy()->UnregisterAllProviders();
4022 extensions::TestManagementPolicyProvider provider(
4023 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
4024 GetManagementPolicy()->RegisterProvider(&provider);
4026 // Reinstall the extension.
4027 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_UPDATED);
4028 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4029 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4032 // Tests that extensions disabled by management policy can be installed but
4033 // will get disabled after installing.
4034 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsEnableOnInstalled) {
4035 InitializeEmptyExtensionService();
4037 // Register an ExtensionManagementPolicy that disables all extensions, with
4038 // a specified Extension::DisableReason.
4039 GetManagementPolicy()->UnregisterAllProviders();
4040 extensions::TestManagementPolicyProvider provider(
4041 extensions::TestManagementPolicyProvider::MUST_REMAIN_DISABLED);
4042 provider.SetDisableReason(Extension::DISABLE_NOT_VERIFIED);
4043 GetManagementPolicy()->RegisterProvider(&provider);
4045 // Attempts to install an extensions, it should be installed but disabled.
4046 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4047 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4048 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_WITHOUT_LOAD);
4049 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4050 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4052 // Verifies that the disable reason is set properly.
4053 EXPECT_EQ(Extension::DISABLE_NOT_VERIFIED,
4054 service()->extension_prefs_->GetDisableReasons(kGoodId));
4057 // Tests that extensions with conflicting required permissions by enterprise
4058 // policy cannot be installed.
4059 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionNewExtensionInstall) {
4060 InitializeEmptyExtensionServiceWithTestingPrefs();
4061 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4064 // Update policy to block one of the required permissions of target.
4065 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4066 pref.AddBlockedPermission("*", "tabs");
4069 // The extension should be failed to install.
4070 PackAndInstallCRX(path, INSTALL_FAILED);
4073 // Update policy to block one of the optional permissions instead.
4074 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4075 pref.ClearBlockedPermissions("*");
4076 pref.AddBlockedPermission("*", "history");
4079 // The extension should succeed to install this time.
4080 std::string id = PackAndInstallCRX(path, INSTALL_NEW)->id();
4082 // Uninstall the extension and update policy to block some arbitrary
4083 // unknown permission.
4084 UninstallExtension(id, false);
4086 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4087 pref.ClearBlockedPermissions("*");
4088 pref.AddBlockedPermission("*", "unknown.permission.for.testing");
4091 // The extension should succeed to install as well.
4092 PackAndInstallCRX(path, INSTALL_NEW);
4095 // Tests that extension supposed to be force installed but with conflicting
4096 // required permissions cannot be installed.
4097 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionConflictsWithForceInstall) {
4098 InitializeEmptyExtensionServiceWithTestingPrefs();
4100 // Pack the crx file.
4101 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4102 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4103 base::ScopedTempDir temp_dir;
4104 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4105 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
4107 PackCRX(path, pem_path, crx_path);
4110 // Block one of the required permissions.
4111 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4112 pref.AddBlockedPermission("*", "tabs");
4115 // Use MockExtensionProvider to simulate force installing extension.
4116 MockExtensionProvider* provider =
4117 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4118 AddMockExternalProvider(provider);
4119 provider->UpdateOrAddExtension(permissions_blocklist, "1.0", crx_path);
4122 // Attempts to force install this extension.
4123 content::WindowedNotificationObserver observer(
4124 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4125 content::NotificationService::AllSources());
4126 service()->CheckForExternalUpdates();
4127 observer.Wait();
4130 // The extension should not be installed.
4131 ASSERT_FALSE(service()->GetInstalledExtension(permissions_blocklist));
4133 // Remove this extension from pending extension manager as we would like to
4134 // give another attempt later.
4135 service()->pending_extension_manager()->Remove(permissions_blocklist);
4138 // Clears the permission block list.
4139 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4140 pref.ClearBlockedPermissions("*");
4144 // Attempts to force install this extension again.
4145 content::WindowedNotificationObserver observer(
4146 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4147 content::NotificationService::AllSources());
4148 service()->CheckForExternalUpdates();
4149 observer.Wait();
4152 const Extension* installed =
4153 service()->GetInstalledExtension(permissions_blocklist);
4154 ASSERT_TRUE(installed);
4155 EXPECT_EQ(installed->location(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4158 // Tests that newer versions of an extension with conflicting required
4159 // permissions by enterprise policy cannot be updated to.
4160 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionExtensionUpdate) {
4161 InitializeEmptyExtensionServiceWithTestingPrefs();
4163 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4164 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4165 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4167 // Install 'permissions_blocklist'.
4168 const Extension* installed = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
4169 EXPECT_EQ(installed->id(), permissions_blocklist);
4172 // Block one of the required permissions of 'permissions_blocklist2'.
4173 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4174 pref.AddBlockedPermission("*", "downloads");
4177 // Install 'permissions_blocklist' again, should be updated.
4178 const Extension* updated = PackAndInstallCRX(path, pem_path, INSTALL_UPDATED);
4179 EXPECT_EQ(updated->id(), permissions_blocklist);
4181 std::string old_version = updated->VersionString();
4183 // Attempts to update to 'permissions_blocklist2' should fail.
4184 PackAndInstallCRX(path2, pem_path, INSTALL_FAILED);
4186 // Verify that the old version is still enabled.
4187 updated = service()->GetExtensionById(permissions_blocklist, false);
4188 ASSERT_TRUE(updated);
4189 EXPECT_EQ(old_version, updated->VersionString());
4192 // Tests that policy update with additional permissions blocked revoke
4193 // conflicting granted optional permissions and unload extensions with
4194 // conflicting required permissions, including the force installed ones.
4195 TEST_F(ExtensionServiceTest, PolicyBlockedPermissionPolicyUpdate) {
4196 InitializeEmptyExtensionServiceWithTestingPrefs();
4198 base::FilePath path = data_dir().AppendASCII("permissions_blocklist");
4199 base::FilePath path2 = data_dir().AppendASCII("permissions_blocklist2");
4200 base::FilePath pem_path = data_dir().AppendASCII("permissions_blocklist.pem");
4202 // Pack the crx file.
4203 base::ScopedTempDir temp_dir;
4204 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
4205 base::FilePath crx_path = temp_dir.path().AppendASCII("temp.crx");
4207 PackCRX(path2, pem_path, crx_path);
4209 // Install two arbitary extensions with specified manifest.
4210 std::string ext1 = PackAndInstallCRX(path, INSTALL_NEW)->id();
4211 std::string ext2 = PackAndInstallCRX(path2, INSTALL_NEW)->id();
4212 ASSERT_NE(ext1, permissions_blocklist);
4213 ASSERT_NE(ext2, permissions_blocklist);
4214 ASSERT_NE(ext1, ext2);
4216 // Force install another extension with known id and same manifest as 'ext2'.
4217 std::string ext2_forced = permissions_blocklist;
4218 MockExtensionProvider* provider =
4219 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4220 AddMockExternalProvider(provider);
4221 provider->UpdateOrAddExtension(ext2_forced, "2.0", crx_path);
4223 content::WindowedNotificationObserver observer(
4224 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4225 content::NotificationService::AllSources());
4226 service()->CheckForExternalUpdates();
4227 observer.Wait();
4229 extensions::ExtensionRegistry* registry =
4230 extensions::ExtensionRegistry::Get(profile());
4232 // Verify all three extensions are installed and enabled.
4233 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext1));
4234 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2));
4235 ASSERT_TRUE(registry->enabled_extensions().GetByID(ext2_forced));
4237 // Grant all optional permissions to each extension.
4238 GrantAllOptionalPermissions(ext1);
4239 GrantAllOptionalPermissions(ext2);
4240 GrantAllOptionalPermissions(ext2_forced);
4242 scoped_refptr<const PermissionSet> active_permissions(
4243 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1));
4244 EXPECT_TRUE(active_permissions->HasAPIPermission(
4245 extensions::APIPermission::kDownloads));
4247 // Set policy to block 'downloads' permission.
4249 ManagementPrefUpdater pref(profile_->GetTestingPrefService());
4250 pref.AddBlockedPermission("*", "downloads");
4253 base::RunLoop().RunUntilIdle();
4255 // 'ext1' should still be enabled, but with 'downloads' permission revoked.
4256 EXPECT_TRUE(registry->enabled_extensions().GetByID(ext1));
4257 active_permissions =
4258 ExtensionPrefs::Get(profile())->GetActivePermissions(ext1);
4259 EXPECT_FALSE(active_permissions->HasAPIPermission(
4260 extensions::APIPermission::kDownloads));
4262 // 'ext2' should be disabled because one of its required permissions is
4263 // blocked.
4264 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2));
4266 // 'ext2_forced' should be handled the same as 'ext2'
4267 EXPECT_FALSE(registry->enabled_extensions().GetByID(ext2_forced));
4270 // Flaky on windows; http://crbug.com/309833
4271 #if defined(OS_WIN)
4272 #define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
4273 #else
4274 #define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
4275 #endif
4276 TEST_F(ExtensionServiceTest, MAYBE_ExternalExtensionAutoAcknowledgement) {
4277 InitializeEmptyExtensionService();
4278 service()->set_extensions_enabled(true);
4281 // Register and install an external extension.
4282 MockExtensionProvider* provider =
4283 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
4284 AddMockExternalProvider(provider);
4285 provider->UpdateOrAddExtension(
4286 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
4289 // Have policy force-install an extension.
4290 MockExtensionProvider* provider = new MockExtensionProvider(
4291 service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
4292 AddMockExternalProvider(provider);
4293 provider->UpdateOrAddExtension(
4294 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
4297 // Providers are set up. Let them run.
4298 int count = 2;
4299 content::WindowedNotificationObserver observer(
4300 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4301 base::Bind(&WaitForCountNotificationsCallback, &count));
4302 service()->CheckForExternalUpdates();
4304 observer.Wait();
4306 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4307 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4308 EXPECT_TRUE(service()->GetExtensionById(page_action, false));
4309 ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
4310 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
4311 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
4314 #if !defined(OS_CHROMEOS)
4315 // This tests if default apps are installed correctly.
4316 TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
4317 InitializeEmptyExtensionService();
4318 service()->set_extensions_enabled(true);
4321 std::string json_data =
4323 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
4324 " \"external_crx\": \"good.crx\","
4325 " \"external_version\": \"1.0.0.0\","
4326 " \"is_bookmark_app\": false"
4327 " }"
4328 "}";
4329 default_apps::Provider* provider = new default_apps::Provider(
4330 profile(),
4331 service(),
4332 new extensions::ExternalTestingLoader(json_data, data_dir()),
4333 Manifest::INTERNAL,
4334 Manifest::INVALID_LOCATION,
4335 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4337 AddMockExternalProvider(provider);
4340 ASSERT_EQ(0u, registry()->enabled_extensions().size());
4341 content::WindowedNotificationObserver observer(
4342 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
4343 content::NotificationService::AllSources());
4344 service()->CheckForExternalUpdates();
4345 observer.Wait();
4347 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4348 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4349 const Extension* extension = service()->GetExtensionById(good_crx, false);
4350 EXPECT_TRUE(extension->from_webstore());
4351 EXPECT_TRUE(extension->was_installed_by_default());
4353 #endif
4355 // Tests disabling extensions
4356 TEST_F(ExtensionServiceTest, DisableExtension) {
4357 InitializeEmptyExtensionService();
4359 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4360 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4361 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
4363 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4364 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4365 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4366 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4368 // Disable it.
4369 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4371 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4372 EXPECT_FALSE(service()->GetExtensionById(good_crx, false));
4373 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4374 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4375 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4376 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4379 TEST_F(ExtensionServiceTest, TerminateExtension) {
4380 InitializeEmptyExtensionService();
4382 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4383 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4384 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4385 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4386 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4388 TerminateExtension(good_crx);
4390 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4391 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4392 EXPECT_EQ(1u, registry()->terminated_extensions().size());
4393 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4396 TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
4397 InitializeEmptyExtensionService();
4399 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4400 TerminateExtension(good_crx);
4401 EXPECT_TRUE(registry()->GetExtensionById(
4402 good_crx, extensions::ExtensionRegistry::TERMINATED));
4404 // Disable it.
4405 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
4407 EXPECT_FALSE(registry()->GetExtensionById(
4408 good_crx, extensions::ExtensionRegistry::TERMINATED));
4409 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
4411 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4412 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4413 EXPECT_EQ(0u, registry()->terminated_extensions().size());
4414 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
4417 // Tests disabling all extensions (simulating --disable-extensions flag).
4418 TEST_F(ExtensionServiceTest, DisableAllExtensions) {
4419 InitializeEmptyExtensionService();
4421 base::FilePath path = data_dir().AppendASCII("good.crx");
4422 InstallCRX(path, INSTALL_NEW);
4424 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4425 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4427 // Disable extensions.
4428 service()->set_extensions_enabled(false);
4429 service()->ReloadExtensionsForTest();
4431 // There shouldn't be extensions in either list.
4432 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4433 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4435 // This shouldn't do anything when all extensions are disabled.
4436 service()->EnableExtension(good_crx);
4437 service()->ReloadExtensionsForTest();
4439 // There still shouldn't be extensions in either list.
4440 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4441 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4443 // And then re-enable the extensions.
4444 service()->set_extensions_enabled(true);
4445 service()->ReloadExtensionsForTest();
4447 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4448 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4451 // Tests reloading extensions.
4452 TEST_F(ExtensionServiceTest, ReloadExtensions) {
4453 InitializeEmptyExtensionService();
4455 // Simple extension that should install without error.
4456 base::FilePath path = data_dir().AppendASCII("good.crx");
4457 InstallCRX(path, INSTALL_NEW,
4458 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
4459 const char* const extension_id = good_crx;
4460 service()->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
4462 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4463 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4465 service()->ReloadExtensionsForTest();
4467 // The creation flags should not change when reloading the extension.
4468 const Extension* extension = service()->GetExtensionById(good_crx, true);
4469 EXPECT_TRUE(extension->from_webstore());
4470 EXPECT_TRUE(extension->was_installed_by_default());
4471 EXPECT_FALSE(extension->from_bookmark());
4473 // Extension counts shouldn't change.
4474 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4475 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4477 service()->EnableExtension(extension_id);
4479 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4480 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4482 // Need to clear |loaded_| manually before reloading as the
4483 // EnableExtension() call above inserted into it and
4484 // UnloadAllExtensions() doesn't send out notifications.
4485 loaded_.clear();
4486 service()->ReloadExtensionsForTest();
4488 // Extension counts shouldn't change.
4489 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4490 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4493 // Tests reloading an extension.
4494 TEST_F(ExtensionServiceTest, ReloadExtension) {
4495 InitializeEmptyExtensionService();
4497 // Simple extension that should install without error.
4498 const char extension_id[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
4499 base::FilePath ext = data_dir()
4500 .AppendASCII("good")
4501 .AppendASCII("Extensions")
4502 .AppendASCII(extension_id)
4503 .AppendASCII("1.0.0.0");
4504 extensions::UnpackedInstaller::Create(service())->Load(ext);
4505 base::RunLoop().RunUntilIdle();
4507 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4508 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4510 service()->ReloadExtension(extension_id);
4512 // Extension should be disabled now, waiting to be reloaded.
4513 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4514 EXPECT_EQ(1u, registry()->disabled_extensions().size());
4515 EXPECT_EQ(Extension::DISABLE_RELOAD,
4516 ExtensionPrefs::Get(profile())->GetDisableReasons(extension_id));
4518 // Reloading again should not crash.
4519 service()->ReloadExtension(extension_id);
4521 // Finish reloading
4522 base::RunLoop().RunUntilIdle();
4524 // Extension should be enabled again.
4525 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4526 EXPECT_EQ(0u, registry()->disabled_extensions().size());
4529 TEST_F(ExtensionServiceTest, UninstallExtension) {
4530 InitializeEmptyExtensionService();
4531 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4532 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4533 UninstallExtension(good_crx, false);
4534 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4535 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4538 TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
4539 InitializeEmptyExtensionService();
4540 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4541 TerminateExtension(good_crx);
4542 UninstallExtension(good_crx, false);
4543 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4546 // Tests the uninstaller helper.
4547 TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
4548 InitializeEmptyExtensionService();
4549 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4550 UninstallExtension(good_crx, true);
4551 EXPECT_EQ(UnloadedExtensionInfo::REASON_UNINSTALL, unloaded_reason_);
4554 TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
4555 InitializeEmptyExtensionService();
4556 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
4557 TerminateExtension(good_crx);
4558 UninstallExtension(good_crx, true);
4559 EXPECT_EQ(UnloadedExtensionInfo::REASON_TERMINATE, unloaded_reason_);
4562 // An extension disabled because of unsupported requirements should re-enabled
4563 // if updated to a version with supported requirements as long as there are no
4564 // other disable reasons.
4565 TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
4566 InitializeEmptyExtensionService();
4567 BlackListWebGL();
4569 base::FilePath path = data_dir().AppendASCII("requirements");
4570 base::FilePath pem_path =
4571 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4572 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4573 pem_path,
4574 INSTALL_NEW);
4575 std::string id = extension_v1->id();
4576 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4578 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4580 PackCRX(path.AppendASCII("v2_bad_requirements"),
4581 pem_path,
4582 v2_bad_requirements_crx);
4583 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4584 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4586 base::FilePath v3_good_crx = GetTemporaryFile();
4588 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4589 UpdateExtension(id, v3_good_crx, ENABLED);
4590 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4593 // Extensions disabled through user action should stay disabled.
4594 TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
4595 InitializeEmptyExtensionService();
4596 BlackListWebGL();
4598 base::FilePath path = data_dir().AppendASCII("requirements");
4599 base::FilePath pem_path =
4600 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4601 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4602 pem_path,
4603 INSTALL_NEW);
4604 std::string id = extension_v1->id();
4605 service()->DisableExtension(id, Extension::DISABLE_USER_ACTION);
4606 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4608 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4610 PackCRX(path.AppendASCII("v2_bad_requirements"),
4611 pem_path,
4612 v2_bad_requirements_crx);
4613 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4614 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4616 base::FilePath v3_good_crx = GetTemporaryFile();
4618 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4619 UpdateExtension(id, v3_good_crx, INSTALLED);
4620 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4623 // The extension should not re-enabled because it was disabled from a
4624 // permission increase.
4625 TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
4626 InitializeEmptyExtensionService();
4627 BlackListWebGL();
4629 base::FilePath path = data_dir().AppendASCII("requirements");
4630 base::FilePath pem_path =
4631 data_dir().AppendASCII("requirements").AppendASCII("v1_good.pem");
4632 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4633 pem_path,
4634 INSTALL_NEW);
4635 std::string id = extension_v1->id();
4636 EXPECT_TRUE(service()->IsExtensionEnabled(id));
4638 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
4640 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
4641 pem_path,
4642 v2_bad_requirements_and_permissions_crx);
4643 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
4644 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4646 base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
4648 PackCRX(path.AppendASCII("v3_bad_permissions"),
4649 pem_path,
4650 v3_bad_permissions_crx);
4651 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
4652 EXPECT_FALSE(service()->IsExtensionEnabled(id));
4655 // Unpacked extensions are not allowed to be installed if they have unsupported
4656 // requirements.
4657 TEST_F(ExtensionServiceTest, UnpackedRequirements) {
4658 InitializeEmptyExtensionService();
4659 BlackListWebGL();
4661 base::FilePath path =
4662 data_dir().AppendASCII("requirements").AppendASCII("v2_bad_requirements");
4663 extensions::UnpackedInstaller::Create(service())->Load(path);
4664 base::RunLoop().RunUntilIdle();
4665 EXPECT_EQ(1u, GetErrors().size());
4666 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4669 class ExtensionCookieCallback {
4670 public:
4671 ExtensionCookieCallback()
4672 : result_(false),
4673 weak_factory_(base::MessageLoop::current()) {}
4675 void SetCookieCallback(bool result) {
4676 base::MessageLoop::current()->PostTask(FROM_HERE,
4677 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4678 result_ = result;
4681 void GetAllCookiesCallback(const net::CookieList& list) {
4682 base::MessageLoop::current()->PostTask(FROM_HERE,
4683 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4684 list_ = list;
4686 net::CookieList list_;
4687 bool result_;
4688 base::WeakPtrFactory<base::MessageLoop> weak_factory_;
4691 // Verifies extension state is removed upon uninstall.
4692 TEST_F(ExtensionServiceTest, ClearExtensionData) {
4693 InitializeEmptyExtensionService();
4694 ExtensionCookieCallback callback;
4696 // Load a test extension.
4697 base::FilePath path = data_dir();
4698 path = path.AppendASCII("good.crx");
4699 const Extension* extension = InstallCRX(path, INSTALL_NEW);
4700 ASSERT_TRUE(extension);
4701 GURL ext_url(extension->url());
4702 std::string origin_id = storage::GetIdentifierFromOrigin(ext_url);
4704 // Set a cookie for the extension.
4705 net::CookieMonster* cookie_monster = profile()
4706 ->GetRequestContextForExtensions()
4707 ->GetURLRequestContext()
4708 ->cookie_store()
4709 ->GetCookieMonster();
4710 ASSERT_TRUE(cookie_monster);
4711 net::CookieOptions options;
4712 cookie_monster->SetCookieWithOptionsAsync(
4713 ext_url, "dummy=value", options,
4714 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4715 base::Unretained(&callback)));
4716 base::RunLoop().RunUntilIdle();
4717 EXPECT_TRUE(callback.result_);
4719 cookie_monster->GetAllCookiesForURLAsync(
4720 ext_url,
4721 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4722 base::Unretained(&callback)));
4723 base::RunLoop().RunUntilIdle();
4724 EXPECT_EQ(1U, callback.list_.size());
4726 // Open a database.
4727 storage::DatabaseTracker* db_tracker =
4728 BrowserContext::GetDefaultStoragePartition(profile())
4729 ->GetDatabaseTracker();
4730 base::string16 db_name = base::UTF8ToUTF16("db");
4731 base::string16 description = base::UTF8ToUTF16("db_description");
4732 int64 size;
4733 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4734 db_tracker->DatabaseClosed(origin_id, db_name);
4735 std::vector<storage::OriginInfo> origins;
4736 db_tracker->GetAllOriginsInfo(&origins);
4737 EXPECT_EQ(1U, origins.size());
4738 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4740 // Create local storage. We only simulate this by creating the backing files.
4741 // Note: This test depends on details of how the dom_storage library
4742 // stores data in the host file system.
4743 base::FilePath lso_dir_path =
4744 profile()->GetPath().AppendASCII("Local Storage");
4745 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4746 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4747 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4748 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4749 EXPECT_TRUE(base::PathExists(lso_file_path));
4751 // Create indexed db. Similarly, it is enough to only simulate this by
4752 // creating the directory on the disk.
4753 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4754 profile())->GetIndexedDBContext();
4755 idb_context->SetTaskRunnerForTesting(
4756 base::MessageLoop::current()->message_loop_proxy().get());
4757 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4758 EXPECT_TRUE(base::CreateDirectory(idb_path));
4759 EXPECT_TRUE(base::DirectoryExists(idb_path));
4761 // Uninstall the extension.
4762 base::RunLoop run_loop;
4763 ASSERT_TRUE(
4764 service()->UninstallExtension(good_crx,
4765 extensions::UNINSTALL_REASON_FOR_TESTING,
4766 run_loop.QuitClosure(),
4767 NULL));
4768 // The data deletion happens on the IO thread.
4769 run_loop.Run();
4771 // Check that the cookie is gone.
4772 cookie_monster->GetAllCookiesForURLAsync(
4773 ext_url,
4774 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4775 base::Unretained(&callback)));
4776 base::RunLoop().RunUntilIdle();
4777 EXPECT_EQ(0U, callback.list_.size());
4779 // The database should have vanished as well.
4780 origins.clear();
4781 db_tracker->GetAllOriginsInfo(&origins);
4782 EXPECT_EQ(0U, origins.size());
4784 // Check that the LSO file has been removed.
4785 EXPECT_FALSE(base::PathExists(lso_file_path));
4787 // Check if the indexed db has disappeared too.
4788 EXPECT_FALSE(base::DirectoryExists(idb_path));
4791 // Verifies app state is removed upon uninstall.
4792 TEST_F(ExtensionServiceTest, ClearAppData) {
4793 InitializeEmptyExtensionService();
4794 ExtensionCookieCallback callback;
4796 int pref_count = 0;
4798 // Install app1 with unlimited storage.
4799 const Extension* extension =
4800 PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
4801 ValidatePrefKeyCount(++pref_count);
4802 ASSERT_EQ(1u, registry()->enabled_extensions().size());
4803 const std::string id1 = extension->id();
4804 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4805 APIPermission::kUnlimitedStorage));
4806 const GURL origin1(
4807 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4808 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4809 origin1));
4810 std::string origin_id = storage::GetIdentifierFromOrigin(origin1);
4812 // Install app2 from the same origin with unlimited storage.
4813 extension = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
4814 ValidatePrefKeyCount(++pref_count);
4815 ASSERT_EQ(2u, registry()->enabled_extensions().size());
4816 const std::string id2 = extension->id();
4817 EXPECT_TRUE(extension->permissions_data()->HasAPIPermission(
4818 APIPermission::kUnlimitedStorage));
4819 EXPECT_TRUE(extension->web_extent().MatchesURL(
4820 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
4821 const GURL origin2(
4822 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4823 EXPECT_EQ(origin1, origin2);
4824 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4825 origin2));
4827 // Set a cookie for the extension.
4828 net::CookieMonster* cookie_monster = profile()
4829 ->GetRequestContext()
4830 ->GetURLRequestContext()
4831 ->cookie_store()
4832 ->GetCookieMonster();
4833 ASSERT_TRUE(cookie_monster);
4834 net::CookieOptions options;
4835 cookie_monster->SetCookieWithOptionsAsync(
4836 origin1, "dummy=value", options,
4837 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4838 base::Unretained(&callback)));
4839 base::RunLoop().RunUntilIdle();
4840 EXPECT_TRUE(callback.result_);
4842 cookie_monster->GetAllCookiesForURLAsync(
4843 origin1,
4844 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4845 base::Unretained(&callback)));
4846 base::RunLoop().RunUntilIdle();
4847 EXPECT_EQ(1U, callback.list_.size());
4849 // Open a database.
4850 storage::DatabaseTracker* db_tracker =
4851 BrowserContext::GetDefaultStoragePartition(profile())
4852 ->GetDatabaseTracker();
4853 base::string16 db_name = base::UTF8ToUTF16("db");
4854 base::string16 description = base::UTF8ToUTF16("db_description");
4855 int64 size;
4856 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4857 db_tracker->DatabaseClosed(origin_id, db_name);
4858 std::vector<storage::OriginInfo> origins;
4859 db_tracker->GetAllOriginsInfo(&origins);
4860 EXPECT_EQ(1U, origins.size());
4861 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4863 // Create local storage. We only simulate this by creating the backing files.
4864 // Note: This test depends on details of how the dom_storage library
4865 // stores data in the host file system.
4866 base::FilePath lso_dir_path =
4867 profile()->GetPath().AppendASCII("Local Storage");
4868 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4869 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4870 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4871 EXPECT_EQ(0, base::WriteFile(lso_file_path, NULL, 0));
4872 EXPECT_TRUE(base::PathExists(lso_file_path));
4874 // Create indexed db. Similarly, it is enough to only simulate this by
4875 // creating the directory on the disk.
4876 IndexedDBContext* idb_context = BrowserContext::GetDefaultStoragePartition(
4877 profile())->GetIndexedDBContext();
4878 idb_context->SetTaskRunnerForTesting(
4879 base::MessageLoop::current()->message_loop_proxy().get());
4880 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4881 EXPECT_TRUE(base::CreateDirectory(idb_path));
4882 EXPECT_TRUE(base::DirectoryExists(idb_path));
4884 // Uninstall one of them, unlimited storage should still be granted
4885 // to the origin.
4886 UninstallExtension(id1, false);
4887 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4888 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4889 origin1));
4891 // Check that the cookie is still there.
4892 cookie_monster->GetAllCookiesForURLAsync(
4893 origin1,
4894 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4895 base::Unretained(&callback)));
4896 base::RunLoop().RunUntilIdle();
4897 EXPECT_EQ(1U, callback.list_.size());
4899 // Now uninstall the other. Storage should be cleared for the apps.
4900 UninstallExtension(id2, false);
4901 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4902 EXPECT_FALSE(
4903 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
4904 origin1));
4906 // Check that the cookie is gone.
4907 cookie_monster->GetAllCookiesForURLAsync(
4908 origin1,
4909 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4910 base::Unretained(&callback)));
4911 base::RunLoop().RunUntilIdle();
4912 EXPECT_EQ(0U, callback.list_.size());
4914 // The database should have vanished as well.
4915 origins.clear();
4916 db_tracker->GetAllOriginsInfo(&origins);
4917 EXPECT_EQ(0U, origins.size());
4919 // Check that the LSO file has been removed.
4920 EXPECT_FALSE(base::PathExists(lso_file_path));
4922 // Check if the indexed db has disappeared too.
4923 EXPECT_FALSE(base::DirectoryExists(idb_path));
4926 // Tests loading single extensions (like --load-extension)
4927 // Flaky crashes. http://crbug.com/231806
4928 TEST_F(ExtensionServiceTest, DISABLED_LoadExtension) {
4929 InitializeEmptyExtensionService();
4931 base::FilePath ext1 = data_dir()
4932 .AppendASCII("good")
4933 .AppendASCII("Extensions")
4934 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4935 .AppendASCII("1.0.0.0");
4936 extensions::UnpackedInstaller::Create(service())->Load(ext1);
4937 base::RunLoop().RunUntilIdle();
4938 EXPECT_EQ(0u, GetErrors().size());
4939 ASSERT_EQ(1u, loaded_.size());
4940 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
4941 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4943 ValidatePrefKeyCount(1);
4945 base::FilePath no_manifest =
4946 data_dir()
4947 .AppendASCII("bad")
4948 // .AppendASCII("Extensions")
4949 .AppendASCII("cccccccccccccccccccccccccccccccc")
4950 .AppendASCII("1");
4951 extensions::UnpackedInstaller::Create(service())->Load(no_manifest);
4952 base::RunLoop().RunUntilIdle();
4953 EXPECT_EQ(1u, GetErrors().size());
4954 ASSERT_EQ(1u, loaded_.size());
4955 EXPECT_EQ(1u, registry()->enabled_extensions().size());
4957 // Test uninstall.
4958 std::string id = loaded_[0]->id();
4959 EXPECT_FALSE(unloaded_id_.length());
4960 service()->UninstallExtension(id,
4961 extensions::UNINSTALL_REASON_FOR_TESTING,
4962 base::Bind(&base::DoNothing),
4963 NULL);
4964 base::RunLoop().RunUntilIdle();
4965 EXPECT_EQ(id, unloaded_id_);
4966 ASSERT_EQ(0u, loaded_.size());
4967 EXPECT_EQ(0u, registry()->enabled_extensions().size());
4970 // Tests that we generate IDs when they are not specified in the manifest for
4971 // --load-extension.
4972 TEST_F(ExtensionServiceTest, GenerateID) {
4973 InitializeEmptyExtensionService();
4975 base::FilePath no_id_ext = data_dir().AppendASCII("no_id");
4976 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
4977 base::RunLoop().RunUntilIdle();
4978 EXPECT_EQ(0u, GetErrors().size());
4979 ASSERT_EQ(1u, loaded_.size());
4980 ASSERT_TRUE(crx_file::id_util::IdIsValid(loaded_[0]->id()));
4981 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
4983 ValidatePrefKeyCount(1);
4985 std::string previous_id = loaded_[0]->id();
4987 // If we reload the same path, we should get the same extension ID.
4988 extensions::UnpackedInstaller::Create(service())->Load(no_id_ext);
4989 base::RunLoop().RunUntilIdle();
4990 ASSERT_EQ(1u, loaded_.size());
4991 ASSERT_EQ(previous_id, loaded_[0]->id());
4994 TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
4995 InitializeEmptyExtensionService();
4997 base::FilePath bad_locale =
4998 data_dir().AppendASCII("unpacked").AppendASCII("bad_messages_file");
4999 extensions::UnpackedInstaller::Create(service())->Load(bad_locale);
5000 base::RunLoop().RunUntilIdle();
5001 EXPECT_EQ(1u, GetErrors().size());
5002 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
5003 .AppendASCII("ms")
5004 .AppendASCII("messages.json");
5005 EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
5006 testing::HasSubstr(
5007 base::UTF16ToUTF8(ms_messages_file.LossyDisplayName())),
5008 testing::HasSubstr("Dictionary keys must be quoted.")));
5009 ASSERT_EQ(0u, loaded_.size());
5012 void ExtensionServiceTest::TestExternalProvider(
5013 MockExtensionProvider* provider, Manifest::Location location) {
5014 // Verify that starting with no providers loads no extensions.
5015 service()->Init();
5016 ASSERT_EQ(0u, loaded_.size());
5018 provider->set_visit_count(0);
5020 // Register a test extension externally using the mock registry provider.
5021 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5023 // Add the extension.
5024 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5026 // Reloading extensions should find our externally registered extension
5027 // and install it.
5028 content::WindowedNotificationObserver observer(
5029 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5030 content::NotificationService::AllSources());
5031 service()->CheckForExternalUpdates();
5032 observer.Wait();
5034 ASSERT_EQ(0u, GetErrors().size());
5035 ASSERT_EQ(1u, loaded_.size());
5036 ASSERT_EQ(location, loaded_[0]->location());
5037 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
5038 ValidatePrefKeyCount(1);
5039 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5040 ValidateIntegerPref(good_crx, "location", location);
5042 // Reload extensions without changing anything. The extension should be
5043 // loaded again.
5044 loaded_.clear();
5045 service()->ReloadExtensionsForTest();
5046 base::RunLoop().RunUntilIdle();
5047 ASSERT_EQ(0u, GetErrors().size());
5048 ASSERT_EQ(1u, loaded_.size());
5049 ValidatePrefKeyCount(1);
5050 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5051 ValidateIntegerPref(good_crx, "location", location);
5053 // Now update the extension with a new version. We should get upgraded.
5054 source_path = source_path.DirName().AppendASCII("good2.crx");
5055 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5057 loaded_.clear();
5058 content::WindowedNotificationObserver observer_2(
5059 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5060 content::NotificationService::AllSources());
5061 service()->CheckForExternalUpdates();
5062 observer_2.Wait();
5063 ASSERT_EQ(0u, GetErrors().size());
5064 ASSERT_EQ(1u, loaded_.size());
5065 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
5066 ValidatePrefKeyCount(1);
5067 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5068 ValidateIntegerPref(good_crx, "location", location);
5070 // Uninstall the extension and reload. Nothing should happen because the
5071 // preference should prevent us from reinstalling.
5072 std::string id = loaded_[0]->id();
5073 bool no_uninstall =
5074 GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL);
5075 service()->UninstallExtension(id,
5076 extensions::UNINSTALL_REASON_FOR_TESTING,
5077 base::Bind(&base::DoNothing),
5078 NULL);
5079 base::RunLoop().RunUntilIdle();
5081 base::FilePath install_path = extensions_install_dir().AppendASCII(id);
5082 if (no_uninstall) {
5083 // Policy controlled extensions should not have been touched by uninstall.
5084 ASSERT_TRUE(base::PathExists(install_path));
5085 } else {
5086 // The extension should also be gone from the install directory.
5087 ASSERT_FALSE(base::PathExists(install_path));
5088 loaded_.clear();
5089 service()->CheckForExternalUpdates();
5090 base::RunLoop().RunUntilIdle();
5091 ASSERT_EQ(0u, loaded_.size());
5092 ValidatePrefKeyCount(1);
5093 ValidateIntegerPref(good_crx, "state",
5094 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
5095 ValidateIntegerPref(good_crx, "location", location);
5097 // Now clear the preference and reinstall.
5098 SetPrefInteg(good_crx, "state", Extension::ENABLED);
5100 loaded_.clear();
5101 content::WindowedNotificationObserver observer(
5102 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5103 content::NotificationService::AllSources());
5104 service()->CheckForExternalUpdates();
5105 observer.Wait();
5106 ASSERT_EQ(1u, loaded_.size());
5108 ValidatePrefKeyCount(1);
5109 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5110 ValidateIntegerPref(good_crx, "location", location);
5112 if (GetManagementPolicy()->MustRemainEnabled(loaded_[0].get(), NULL)) {
5113 EXPECT_EQ(2, provider->visit_count());
5114 } else {
5115 // Now test an externally triggered uninstall (deleting the registry key or
5116 // the pref entry).
5117 provider->RemoveExtension(good_crx);
5119 loaded_.clear();
5120 service()->OnExternalProviderReady(provider);
5121 base::RunLoop().RunUntilIdle();
5122 ASSERT_EQ(0u, loaded_.size());
5123 ValidatePrefKeyCount(0);
5125 // The extension should also be gone from the install directory.
5126 ASSERT_FALSE(base::PathExists(install_path));
5128 // Now test the case where user uninstalls and then the extension is removed
5129 // from the external provider.
5130 content::WindowedNotificationObserver observer(
5131 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5132 content::NotificationService::AllSources());
5133 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
5134 service()->CheckForExternalUpdates();
5135 observer.Wait();
5137 ASSERT_EQ(1u, loaded_.size());
5138 ASSERT_EQ(0u, GetErrors().size());
5140 // User uninstalls.
5141 loaded_.clear();
5142 service()->UninstallExtension(id,
5143 extensions::UNINSTALL_REASON_FOR_TESTING,
5144 base::Bind(&base::DoNothing),
5145 NULL);
5146 base::RunLoop().RunUntilIdle();
5147 ASSERT_EQ(0u, loaded_.size());
5149 // Then remove the extension from the extension provider.
5150 provider->RemoveExtension(good_crx);
5152 // Should still be at 0.
5153 loaded_.clear();
5154 extensions::InstalledLoader(service()).LoadAllExtensions();
5155 base::RunLoop().RunUntilIdle();
5156 ASSERT_EQ(0u, loaded_.size());
5157 ValidatePrefKeyCount(1);
5159 EXPECT_EQ(5, provider->visit_count());
5163 // Tests the external installation feature
5164 #if defined(OS_WIN)
5165 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
5166 // This should all work, even when normal extension installation is disabled.
5167 InitializeEmptyExtensionService();
5168 service()->set_extensions_enabled(false);
5170 // Now add providers. Extension system takes ownership of the objects.
5171 MockExtensionProvider* reg_provider =
5172 new MockExtensionProvider(service(), Manifest::EXTERNAL_REGISTRY);
5173 AddMockExternalProvider(reg_provider);
5174 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
5176 #endif
5178 TEST_F(ExtensionServiceTest, ExternalInstallPref) {
5179 InitializeEmptyExtensionService();
5181 // Now add providers. Extension system takes ownership of the objects.
5182 MockExtensionProvider* pref_provider =
5183 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
5185 AddMockExternalProvider(pref_provider);
5186 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
5189 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
5190 // This should all work, even when normal extension installation is disabled.
5191 InitializeEmptyExtensionService();
5192 service()->set_extensions_enabled(false);
5194 // TODO(skerner): The mock provider is not a good model of a provider
5195 // that works with update URLs, because it adds file and version info.
5196 // Extend the mock to work with update URLs. This test checks the
5197 // behavior that is common to all external extension visitors. The
5198 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5199 // what the visitor does results in an extension being downloaded and
5200 // installed.
5201 MockExtensionProvider* pref_provider =
5202 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF_DOWNLOAD);
5203 AddMockExternalProvider(pref_provider);
5204 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
5207 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
5208 // This should all work, even when normal extension installation is disabled.
5209 InitializeEmptyExtensionService();
5210 service()->set_extensions_enabled(false);
5212 // TODO(skerner): The mock provider is not a good model of a provider
5213 // that works with update URLs, because it adds file and version info.
5214 // Extend the mock to work with update URLs. This test checks the
5215 // behavior that is common to all external extension visitors. The
5216 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
5217 // what the visitor does results in an extension being downloaded and
5218 // installed.
5219 MockExtensionProvider* pref_provider =
5220 new MockExtensionProvider(service(), Manifest::EXTERNAL_POLICY_DOWNLOAD);
5221 AddMockExternalProvider(pref_provider);
5222 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
5225 // Tests that external extensions get uninstalled when the external extension
5226 // providers can't account for them.
5227 TEST_F(ExtensionServiceTest, ExternalUninstall) {
5228 // Start the extensions service with one external extension already installed.
5229 base::FilePath source_install_dir =
5230 data_dir().AppendASCII("good").AppendASCII("Extensions");
5231 base::FilePath pref_path = source_install_dir
5232 .DirName()
5233 .AppendASCII("PreferencesExternal");
5235 // This initializes the extensions service with no ExternalProviders.
5236 InitializeInstalledExtensionService(pref_path, source_install_dir);
5237 service()->set_extensions_enabled(false);
5239 service()->Init();
5241 ASSERT_EQ(0u, GetErrors().size());
5242 ASSERT_EQ(0u, loaded_.size());
5244 // Verify that it's not the disabled extensions flag causing it not to load.
5245 service()->set_extensions_enabled(true);
5246 service()->ReloadExtensionsForTest();
5247 base::RunLoop().RunUntilIdle();
5249 ASSERT_EQ(0u, GetErrors().size());
5250 ASSERT_EQ(0u, loaded_.size());
5253 // Test that running multiple update checks simultaneously does not
5254 // keep the update from succeeding.
5255 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
5256 InitializeEmptyExtensionService();
5258 MockExtensionProvider* provider =
5259 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
5260 AddMockExternalProvider(provider);
5262 // Verify that starting with no providers loads no extensions.
5263 service()->Init();
5264 ASSERT_EQ(0u, loaded_.size());
5266 // Start two checks for updates.
5267 provider->set_visit_count(0);
5268 service()->CheckForExternalUpdates();
5269 service()->CheckForExternalUpdates();
5270 base::RunLoop().RunUntilIdle();
5272 // Two calls should cause two checks for external extensions.
5273 EXPECT_EQ(2, provider->visit_count());
5274 EXPECT_EQ(0u, GetErrors().size());
5275 EXPECT_EQ(0u, loaded_.size());
5277 // Register a test extension externally using the mock registry provider.
5278 base::FilePath source_path = data_dir().AppendASCII("good.crx");
5279 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
5281 // Two checks for external updates should find the extension, and install it
5282 // once.
5283 content::WindowedNotificationObserver observer(
5284 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
5285 content::NotificationService::AllSources());
5286 provider->set_visit_count(0);
5287 service()->CheckForExternalUpdates();
5288 service()->CheckForExternalUpdates();
5289 observer.Wait();
5290 EXPECT_EQ(2, provider->visit_count());
5291 ASSERT_EQ(0u, GetErrors().size());
5292 ASSERT_EQ(1u, loaded_.size());
5293 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
5294 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
5295 ValidatePrefKeyCount(1);
5296 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
5297 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
5299 provider->RemoveExtension(good_crx);
5300 provider->set_visit_count(0);
5301 service()->CheckForExternalUpdates();
5302 service()->CheckForExternalUpdates();
5303 base::RunLoop().RunUntilIdle();
5305 // Two calls should cause two checks for external extensions.
5306 // Because the external source no longer includes good_crx,
5307 // good_crx will be uninstalled. So, expect that no extensions
5308 // are loaded.
5309 EXPECT_EQ(2, provider->visit_count());
5310 EXPECT_EQ(0u, GetErrors().size());
5311 EXPECT_EQ(0u, loaded_.size());
5314 TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
5315 InitializeEmptyExtensionService();
5317 // Test some valid extension records.
5318 // Set a base path to avoid erroring out on relative paths.
5319 // Paths starting with // are absolute on every platform we support.
5320 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
5321 ASSERT_TRUE(base_path.IsAbsolute());
5322 MockProviderVisitor visitor(base_path);
5323 std::string json_data =
5325 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5326 " \"external_crx\": \"RandomExtension.crx\","
5327 " \"external_version\": \"1.0\""
5328 " },"
5329 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5330 " \"external_crx\": \"RandomExtension2.crx\","
5331 " \"external_version\": \"2.0\""
5332 " },"
5333 " \"cccccccccccccccccccccccccccccccc\": {"
5334 " \"external_update_url\": \"http:\\\\foo.com/update\","
5335 " \"install_parameter\": \"id\""
5336 " }"
5337 "}";
5338 EXPECT_EQ(3, visitor.Visit(json_data));
5340 // Simulate an external_extensions.json file that contains seven invalid
5341 // records:
5342 // - One that is missing the 'external_crx' key.
5343 // - One that is missing the 'external_version' key.
5344 // - One that is specifying .. in the path.
5345 // - One that specifies both a file and update URL.
5346 // - One that specifies no file or update URL.
5347 // - One that has an update URL that is not well formed.
5348 // - One that contains a malformed version.
5349 // - One that has an invalid id.
5350 // - One that has a non-dictionary value.
5351 // - One that has an integer 'external_version' instead of a string.
5352 // The final extension is valid, and we check that it is read to make sure
5353 // failures don't stop valid records from being read.
5354 json_data =
5356 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5357 " \"external_version\": \"1.0\""
5358 " },"
5359 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5360 " \"external_crx\": \"RandomExtension.crx\""
5361 " },"
5362 " \"cccccccccccccccccccccccccccccccc\": {"
5363 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
5364 " \"external_version\": \"2.0\""
5365 " },"
5366 " \"dddddddddddddddddddddddddddddddd\": {"
5367 " \"external_crx\": \"RandomExtension2.crx\","
5368 " \"external_version\": \"2.0\","
5369 " \"external_update_url\": \"http:\\\\foo.com/update\""
5370 " },"
5371 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
5372 " },"
5373 " \"ffffffffffffffffffffffffffffffff\": {"
5374 " \"external_update_url\": \"This string is not a valid URL\""
5375 " },"
5376 " \"gggggggggggggggggggggggggggggggg\": {"
5377 " \"external_crx\": \"RandomExtension3.crx\","
5378 " \"external_version\": \"This is not a valid version!\""
5379 " },"
5380 " \"This is not a valid id!\": {},"
5381 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
5382 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
5383 " \"external_crx\": \"RandomExtension4.crx\","
5384 " \"external_version\": 1.0"
5385 " },"
5386 " \"pppppppppppppppppppppppppppppppp\": {"
5387 " \"external_crx\": \"RandomValidExtension.crx\","
5388 " \"external_version\": \"1.0\""
5389 " }"
5390 "}";
5391 EXPECT_EQ(1, visitor.Visit(json_data));
5393 // Check that if a base path is not provided, use of a relative
5394 // path fails.
5395 base::FilePath empty;
5396 MockProviderVisitor visitor_no_relative_paths(empty);
5398 // Use absolute paths. Expect success.
5399 json_data =
5401 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5402 " \"external_crx\": \"//RandomExtension1.crx\","
5403 " \"external_version\": \"3.0\""
5404 " },"
5405 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5406 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
5407 " \"external_version\": \"3.0\""
5408 " }"
5409 "}";
5410 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
5412 // Use a relative path. Expect that it will error out.
5413 json_data =
5415 " \"cccccccccccccccccccccccccccccccc\": {"
5416 " \"external_crx\": \"RandomExtension2.crx\","
5417 " \"external_version\": \"3.0\""
5418 " }"
5419 "}";
5420 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
5422 // Test supported_locales.
5423 json_data =
5425 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5426 " \"external_crx\": \"RandomExtension.crx\","
5427 " \"external_version\": \"1.0\","
5428 " \"supported_locales\": [ \"en\" ]"
5429 " },"
5430 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5431 " \"external_crx\": \"RandomExtension2.crx\","
5432 " \"external_version\": \"2.0\","
5433 " \"supported_locales\": [ \"en-GB\" ]"
5434 " },"
5435 " \"cccccccccccccccccccccccccccccccc\": {"
5436 " \"external_crx\": \"RandomExtension2.crx\","
5437 " \"external_version\": \"3.0\","
5438 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
5439 " }"
5440 "}";
5442 ScopedBrowserLocale guard("en-US");
5443 EXPECT_EQ(2, visitor.Visit(json_data));
5446 // Test keep_if_present.
5447 json_data =
5449 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5450 " \"external_crx\": \"RandomExtension.crx\","
5451 " \"external_version\": \"1.0\","
5452 " \"keep_if_present\": true"
5453 " }"
5454 "}";
5456 EXPECT_EQ(0, visitor.Visit(json_data));
5459 // Test is_bookmark_app.
5460 MockProviderVisitor from_bookmark_visitor(
5461 base_path, Extension::FROM_BOOKMARK);
5462 json_data =
5464 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5465 " \"external_crx\": \"RandomExtension.crx\","
5466 " \"external_version\": \"1.0\","
5467 " \"is_bookmark_app\": true"
5468 " }"
5469 "}";
5470 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
5472 // Test is_from_webstore.
5473 MockProviderVisitor from_webstore_visitor(
5474 base_path, Extension::FROM_WEBSTORE);
5475 json_data =
5477 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5478 " \"external_crx\": \"RandomExtension.crx\","
5479 " \"external_version\": \"1.0\","
5480 " \"is_from_webstore\": true"
5481 " }"
5482 "}";
5483 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
5485 // Test was_installed_by_eom.
5486 MockProviderVisitor was_installed_by_eom_visitor(
5487 base_path, Extension::WAS_INSTALLED_BY_OEM);
5488 json_data =
5490 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5491 " \"external_crx\": \"RandomExtension.crx\","
5492 " \"external_version\": \"1.0\","
5493 " \"was_installed_by_oem\": true"
5494 " }"
5495 "}";
5496 EXPECT_EQ(1, was_installed_by_eom_visitor.Visit(json_data));
5498 // Test min_profile_created_by_version.
5499 MockProviderVisitor min_profile_created_by_version_visitor(base_path);
5500 json_data =
5502 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5503 " \"external_crx\": \"RandomExtension.crx\","
5504 " \"external_version\": \"1.0\","
5505 " \"min_profile_created_by_version\": \"42.0.0.1\""
5506 " },"
5507 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5508 " \"external_crx\": \"RandomExtension2.crx\","
5509 " \"external_version\": \"1.0\","
5510 " \"min_profile_created_by_version\": \"43.0.0.1\""
5511 " },"
5512 " \"cccccccccccccccccccccccccccccccc\": {"
5513 " \"external_crx\": \"RandomExtension3.crx\","
5514 " \"external_version\": \"3.0\","
5515 " \"min_profile_created_by_version\": \"44.0.0.1\""
5516 " }"
5517 "}";
5518 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5519 prefs::kProfileCreatedByVersion, "40.0.0.1");
5520 EXPECT_EQ(0, min_profile_created_by_version_visitor.Visit(json_data));
5521 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5522 prefs::kProfileCreatedByVersion, "43.0.0.1");
5523 EXPECT_EQ(2, min_profile_created_by_version_visitor.Visit(json_data));
5524 min_profile_created_by_version_visitor.profile()->GetPrefs()->SetString(
5525 prefs::kProfileCreatedByVersion, "45.0.0.1");
5526 EXPECT_EQ(3, min_profile_created_by_version_visitor.Visit(json_data));
5529 // Test loading good extensions from the profile directory.
5530 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
5531 // Ensure we're testing in "en" and leave global state untouched.
5532 extension_l10n_util::ScopedLocaleForTest testLocale("en");
5534 // Initialize the test dir with a good Preferences/extensions.
5535 base::FilePath source_install_dir = data_dir().AppendASCII("l10n");
5536 base::FilePath pref_path =
5537 source_install_dir.Append(chrome::kPreferencesFilename);
5538 InitializeInstalledExtensionService(pref_path, source_install_dir);
5540 service()->Init();
5542 ASSERT_EQ(3u, loaded_.size());
5544 // This was equal to "sr" on load.
5545 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
5547 // These are untouched by re-localization.
5548 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
5549 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
5551 // This one starts with Serbian name, and gets re-localized into English.
5552 EXPECT_EQ("My name is simple.", loaded_[0]->name());
5554 // These are untouched by re-localization.
5555 EXPECT_EQ("My name is simple.", loaded_[1]->name());
5556 EXPECT_EQ("no l10n", loaded_[2]->name());
5559 class ExtensionsReadyRecorder : public content::NotificationObserver {
5560 public:
5561 ExtensionsReadyRecorder() : ready_(false) {
5562 registrar_.Add(this,
5563 extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED,
5564 content::NotificationService::AllSources());
5567 void set_ready(bool value) { ready_ = value; }
5568 bool ready() { return ready_; }
5570 private:
5571 void Observe(int type,
5572 const content::NotificationSource& source,
5573 const content::NotificationDetails& details) override {
5574 switch (type) {
5575 case extensions::NOTIFICATION_EXTENSIONS_READY_DEPRECATED:
5576 ready_ = true;
5577 break;
5578 default:
5579 NOTREACHED();
5583 content::NotificationRegistrar registrar_;
5584 bool ready_;
5587 // Test that we get enabled/disabled correctly for all the pref/command-line
5588 // combinations. We don't want to derive from the ExtensionServiceTest class
5589 // for this test, so we use ExtensionServiceTestSimple.
5591 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
5592 // enabled or not.
5593 class ExtensionServiceTestSimple : public testing::Test {
5594 content::TestBrowserThreadBundle thread_bundle_;
5597 TEST_F(ExtensionServiceTestSimple, Enabledness) {
5598 // Make sure the PluginService singleton is destroyed at the end of the test.
5599 base::ShadowingAtExitManager at_exit_manager;
5600 #if defined(ENABLE_PLUGINS)
5601 content::PluginService::GetInstance()->Init();
5602 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
5603 #endif
5605 ExtensionErrorReporter::Init(false); // no noisy errors
5606 ExtensionsReadyRecorder recorder;
5607 scoped_ptr<TestingProfile> profile(new TestingProfile());
5608 #if defined OS_CHROMEOS
5609 chromeos::ScopedTestDeviceSettingsService device_settings_service;
5610 chromeos::ScopedTestCrosSettings cros_settings;
5611 scoped_ptr<chromeos::ScopedTestUserManager> user_manager(
5612 new chromeos::ScopedTestUserManager);
5613 #endif
5614 scoped_ptr<base::CommandLine> command_line;
5615 base::FilePath install_dir = profile->GetPath()
5616 .AppendASCII(extensions::kInstallDirectoryName);
5618 // By default, we are enabled.
5619 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5620 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
5621 ExtensionSystem::Get(profile.get()))->
5622 CreateExtensionService(
5623 command_line.get(),
5624 install_dir,
5625 false);
5626 EXPECT_TRUE(service->extensions_enabled());
5627 service->Init();
5628 base::RunLoop().RunUntilIdle();
5629 EXPECT_TRUE(recorder.ready());
5630 #if defined OS_CHROMEOS
5631 user_manager.reset();
5632 #endif
5634 // If either the command line or pref is set, we are disabled.
5635 recorder.set_ready(false);
5636 profile.reset(new TestingProfile());
5637 command_line->AppendSwitch(switches::kDisableExtensions);
5638 service = static_cast<extensions::TestExtensionSystem*>(
5639 ExtensionSystem::Get(profile.get()))->
5640 CreateExtensionService(
5641 command_line.get(),
5642 install_dir,
5643 false);
5644 EXPECT_FALSE(service->extensions_enabled());
5645 service->Init();
5646 base::RunLoop().RunUntilIdle();
5647 EXPECT_TRUE(recorder.ready());
5649 recorder.set_ready(false);
5650 profile.reset(new TestingProfile());
5651 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5652 service = static_cast<extensions::TestExtensionSystem*>(
5653 ExtensionSystem::Get(profile.get()))->
5654 CreateExtensionService(
5655 command_line.get(),
5656 install_dir,
5657 false);
5658 EXPECT_FALSE(service->extensions_enabled());
5659 service->Init();
5660 base::RunLoop().RunUntilIdle();
5661 EXPECT_TRUE(recorder.ready());
5663 recorder.set_ready(false);
5664 profile.reset(new TestingProfile());
5665 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5666 command_line.reset(new base::CommandLine(base::CommandLine::NO_PROGRAM));
5667 service = static_cast<extensions::TestExtensionSystem*>(
5668 ExtensionSystem::Get(profile.get()))->
5669 CreateExtensionService(
5670 command_line.get(),
5671 install_dir,
5672 false);
5673 EXPECT_FALSE(service->extensions_enabled());
5674 service->Init();
5675 base::RunLoop().RunUntilIdle();
5676 EXPECT_TRUE(recorder.ready());
5678 // Explicitly delete all the resources used in this test.
5679 profile.reset();
5680 service = NULL;
5681 // Execute any pending deletion tasks.
5682 base::RunLoop().RunUntilIdle();
5685 // Test loading extensions that require limited and unlimited storage quotas.
5686 TEST_F(ExtensionServiceTest, StorageQuota) {
5687 InitializeEmptyExtensionService();
5689 base::FilePath extensions_path = data_dir().AppendASCII("storage_quota");
5691 base::FilePath limited_quota_ext =
5692 extensions_path.AppendASCII("limited_quota")
5693 .AppendASCII("1.0");
5695 // The old permission name for unlimited quota was "unlimited_storage", but
5696 // we changed it to "unlimitedStorage". This tests both versions.
5697 base::FilePath unlimited_quota_ext =
5698 extensions_path.AppendASCII("unlimited_quota")
5699 .AppendASCII("1.0");
5700 base::FilePath unlimited_quota_ext2 =
5701 extensions_path.AppendASCII("unlimited_quota")
5702 .AppendASCII("2.0");
5703 extensions::UnpackedInstaller::Create(service())->Load(limited_quota_ext);
5704 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext);
5705 extensions::UnpackedInstaller::Create(service())->Load(unlimited_quota_ext2);
5706 base::RunLoop().RunUntilIdle();
5708 ASSERT_EQ(3u, loaded_.size());
5709 EXPECT_TRUE(profile());
5710 EXPECT_FALSE(profile()->IsOffTheRecord());
5711 EXPECT_FALSE(
5712 profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5713 loaded_[0]->url()));
5714 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5715 loaded_[1]->url()));
5716 EXPECT_TRUE(profile()->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5717 loaded_[2]->url()));
5720 // Tests ComponentLoader::Add().
5721 TEST_F(ExtensionServiceTest, ComponentExtensions) {
5722 InitializeEmptyExtensionService();
5724 // Component extensions should work even when extensions are disabled.
5725 service()->set_extensions_enabled(false);
5727 base::FilePath path = data_dir()
5728 .AppendASCII("good")
5729 .AppendASCII("Extensions")
5730 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
5731 .AppendASCII("1.0.0.0");
5733 std::string manifest;
5734 ASSERT_TRUE(base::ReadFileToString(
5735 path.Append(extensions::kManifestFilename), &manifest));
5737 service()->component_loader()->Add(manifest, path);
5738 service()->Init();
5740 // Note that we do not pump messages -- the extension should be loaded
5741 // immediately.
5743 EXPECT_EQ(0u, GetErrors().size());
5744 ASSERT_EQ(1u, loaded_.size());
5745 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
5746 EXPECT_EQ(1u, registry()->enabled_extensions().size());
5748 // Component extensions get a prefs entry on first install.
5749 ValidatePrefKeyCount(1);
5751 // Reload all extensions, and make sure it comes back.
5752 std::string extension_id = (*registry()->enabled_extensions().begin())->id();
5753 loaded_.clear();
5754 service()->ReloadExtensionsForTest();
5755 ASSERT_EQ(1u, registry()->enabled_extensions().size());
5756 EXPECT_EQ(extension_id, (*registry()->enabled_extensions().begin())->id());
5759 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
5760 InitializeEmptyExtensionService();
5761 InitializeExtensionSyncService();
5763 bool flare_was_called = false;
5764 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5765 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5766 extension_sync_service()->SetSyncStartFlare(
5767 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5768 factory.GetWeakPtr(),
5769 &flare_was_called, // Safe due to WeakPtrFactory scope.
5770 &triggered_type)); // Safe due to WeakPtrFactory scope.
5772 // Install a component extension.
5773 std::string manifest;
5774 ASSERT_TRUE(base::ReadFileToString(
5775 good0_path().Append(extensions::kManifestFilename), &manifest));
5776 service()->component_loader()->Add(manifest, good0_path());
5777 ASSERT_FALSE(service()->is_ready());
5778 service()->Init();
5779 ASSERT_TRUE(service()->is_ready());
5781 // Extensions added before service is_ready() don't trigger sync startup.
5782 EXPECT_FALSE(flare_was_called);
5783 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5786 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
5787 InitializeGoodInstalledExtensionService();
5788 InitializeExtensionSyncService();
5790 bool flare_was_called = false;
5791 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5792 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5793 extension_sync_service()->SetSyncStartFlare(
5794 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5795 factory.GetWeakPtr(),
5796 &flare_was_called, // Safe due to WeakPtrFactory scope.
5797 &triggered_type)); // Safe due to WeakPtrFactory scope.
5799 ASSERT_FALSE(service()->is_ready());
5800 service()->Init();
5801 ASSERT_EQ(3u, loaded_.size());
5802 ASSERT_TRUE(service()->is_ready());
5804 // Extensions added before service is_ready() don't trigger sync startup.
5805 EXPECT_FALSE(flare_was_called);
5806 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5809 TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
5810 InitializeEmptyExtensionService();
5811 InitializeExtensionSyncService();
5812 service()->Init();
5813 ASSERT_TRUE(service()->is_ready());
5815 bool flare_was_called = false;
5816 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5817 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5818 extension_sync_service()->SetSyncStartFlare(
5819 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5820 factory.GetWeakPtr(),
5821 &flare_was_called, // Safe due to WeakPtrFactory scope.
5822 &triggered_type)); // Safe due to WeakPtrFactory scope.
5824 base::FilePath path = data_dir().AppendASCII("good.crx");
5825 InstallCRX(path, INSTALL_NEW);
5827 EXPECT_TRUE(flare_was_called);
5828 EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
5830 // Reset.
5831 flare_was_called = false;
5832 triggered_type = syncer::UNSPECIFIED;
5834 // Once sync starts, flare should no longer be invoked.
5835 extension_sync_service()->MergeDataAndStartSyncing(
5836 syncer::EXTENSIONS,
5837 syncer::SyncDataList(),
5838 scoped_ptr<syncer::SyncChangeProcessor>(
5839 new syncer::FakeSyncChangeProcessor),
5840 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5841 path = data_dir().AppendASCII("page_action.crx");
5842 InstallCRX(path, INSTALL_NEW);
5843 EXPECT_FALSE(flare_was_called);
5844 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5847 TEST_F(ExtensionServiceTest, DisableExtensionFromSync) {
5848 // Start the extensions service with one external extension already installed.
5849 base::FilePath source_install_dir =
5850 data_dir().AppendASCII("good").AppendASCII("Extensions");
5851 base::FilePath pref_path =
5852 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5854 InitializeInstalledExtensionService(pref_path, source_install_dir);
5855 InitializeExtensionSyncService();
5857 // The user has enabled sync.
5858 ProfileSyncService* sync_service =
5859 ProfileSyncServiceFactory::GetForProfile(profile());
5860 sync_service->SetSyncSetupCompleted();
5862 service()->Init();
5863 ASSERT_TRUE(service()->is_ready());
5865 ASSERT_EQ(3u, loaded_.size());
5867 // We start enabled.
5868 const Extension* extension = service()->GetExtensionById(good0, true);
5869 ASSERT_TRUE(extension);
5870 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5872 // Then sync data arrives telling us to disable |good0|.
5873 ExtensionSyncData disable_good_crx(*extension, false,
5874 Extension::DISABLE_USER_ACTION, false,
5875 false, ExtensionSyncData::BOOLEAN_UNSET);
5876 syncer::SyncDataList sync_data;
5877 sync_data.push_back(disable_good_crx.GetSyncData());
5878 extension_sync_service()->MergeDataAndStartSyncing(
5879 syncer::EXTENSIONS,
5880 sync_data,
5881 scoped_ptr<syncer::SyncChangeProcessor>(
5882 new syncer::FakeSyncChangeProcessor),
5883 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5884 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5887 TEST_F(ExtensionServiceTest, DontDisableExtensionWithPendingEnableFromSync) {
5888 // Start the extensions service with one external extension already installed.
5889 base::FilePath source_install_dir =
5890 data_dir().AppendASCII("good").AppendASCII("Extensions");
5891 base::FilePath pref_path =
5892 source_install_dir.DirName().Append(chrome::kPreferencesFilename);
5894 InitializeInstalledExtensionService(pref_path, source_install_dir);
5895 InitializeExtensionSyncService();
5897 // The user has enabled sync.
5898 ProfileSyncService* sync_service =
5899 ProfileSyncServiceFactory::GetForProfile(profile());
5900 sync_service->SetSyncSetupCompleted();
5902 service()->Init();
5903 ASSERT_TRUE(service()->is_ready());
5904 ASSERT_EQ(3u, loaded_.size());
5906 const Extension* extension = service()->GetExtensionById(good0, true);
5907 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5909 // Disable extension before first sync data arrives.
5910 service()->DisableExtension(good0, Extension::DISABLE_USER_ACTION);
5911 ASSERT_FALSE(service()->IsExtensionEnabled(good0));
5913 // Enable extension - this is now the most recent state.
5914 service()->EnableExtension(good0);
5915 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5917 // Now sync data comes in that says to disable good0. This should be
5918 // ignored.
5919 ExtensionSyncData disable_good_crx(*extension, false,
5920 Extension::DISABLE_USER_ACTION, false,
5921 false, ExtensionSyncData::BOOLEAN_UNSET);
5922 syncer::SyncDataList sync_data;
5923 sync_data.push_back(disable_good_crx.GetSyncData());
5924 extension_sync_service()->MergeDataAndStartSyncing(
5925 syncer::EXTENSIONS,
5926 sync_data,
5927 scoped_ptr<syncer::SyncChangeProcessor>(
5928 new syncer::FakeSyncChangeProcessor),
5929 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5931 // The extension was enabled locally before the sync data arrived, so it
5932 // should still be enabled now.
5933 ASSERT_TRUE(service()->IsExtensionEnabled(good0));
5936 TEST_F(ExtensionServiceTest, GetSyncData) {
5937 InitializeEmptyExtensionService();
5938 InitializeExtensionSyncService();
5939 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5940 const Extension* extension = service()->GetInstalledExtension(good_crx);
5941 ASSERT_TRUE(extension);
5943 extension_sync_service()->MergeDataAndStartSyncing(
5944 syncer::EXTENSIONS,
5945 syncer::SyncDataList(),
5946 scoped_ptr<syncer::SyncChangeProcessor>(
5947 new syncer::FakeSyncChangeProcessor),
5948 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5950 syncer::SyncDataList list =
5951 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5952 ASSERT_EQ(list.size(), 1U);
5953 scoped_ptr<ExtensionSyncData> data =
5954 ExtensionSyncData::CreateFromSyncData(list[0]);
5955 ASSERT_TRUE(data.get());
5956 EXPECT_EQ(extension->id(), data->id());
5957 EXPECT_FALSE(data->uninstalled());
5958 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
5959 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
5960 data->incognito_enabled());
5961 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
5962 EXPECT_TRUE(data->version().Equals(*extension->version()));
5963 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
5964 data->update_url());
5965 EXPECT_EQ(extension->name(), data->name());
5968 TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
5969 InitializeEmptyExtensionService();
5970 InitializeExtensionSyncService();
5971 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
5972 TerminateExtension(good_crx);
5973 const Extension* extension = service()->GetInstalledExtension(good_crx);
5974 ASSERT_TRUE(extension);
5976 syncer::FakeSyncChangeProcessor processor;
5977 extension_sync_service()->MergeDataAndStartSyncing(
5978 syncer::EXTENSIONS,
5979 syncer::SyncDataList(),
5980 scoped_ptr<syncer::SyncChangeProcessor>(
5981 new syncer::FakeSyncChangeProcessor),
5982 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5984 syncer::SyncDataList list =
5985 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
5986 ASSERT_EQ(list.size(), 1U);
5987 scoped_ptr<ExtensionSyncData> data =
5988 ExtensionSyncData::CreateFromSyncData(list[0]);
5989 ASSERT_TRUE(data.get());
5990 EXPECT_EQ(extension->id(), data->id());
5991 EXPECT_FALSE(data->uninstalled());
5992 EXPECT_EQ(service()->IsExtensionEnabled(good_crx), data->enabled());
5993 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx, profile()),
5994 data->incognito_enabled());
5995 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
5996 EXPECT_TRUE(data->version().Equals(*extension->version()));
5997 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
5998 data->update_url());
5999 EXPECT_EQ(extension->name(), data->name());
6002 TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
6003 InitializeEmptyExtensionService();
6004 InitializeExtensionSyncService();
6005 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6006 const Extension* extension = service()->GetInstalledExtension(good_crx);
6007 ASSERT_TRUE(extension);
6009 syncer::FakeSyncChangeProcessor processor;
6010 extension_sync_service()->MergeDataAndStartSyncing(
6011 syncer::APPS,
6012 syncer::SyncDataList(),
6013 scoped_ptr<syncer::SyncChangeProcessor>(
6014 new syncer::FakeSyncChangeProcessor),
6015 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6017 syncer::SyncDataList list =
6018 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6019 ASSERT_EQ(list.size(), 0U);
6022 TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
6023 InitializeEmptyExtensionService();
6024 InitializeExtensionSyncService();
6025 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6026 const Extension* extension = service()->GetInstalledExtension(good_crx);
6027 ASSERT_TRUE(extension);
6029 syncer::FakeSyncChangeProcessor processor;
6030 extension_sync_service()->MergeDataAndStartSyncing(
6031 syncer::EXTENSIONS,
6032 syncer::SyncDataList(),
6033 scoped_ptr<syncer::SyncChangeProcessor>(
6034 new syncer::FakeSyncChangeProcessor),
6035 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6038 syncer::SyncDataList list =
6039 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6040 ASSERT_EQ(list.size(), 1U);
6041 scoped_ptr<ExtensionSyncData> data =
6042 ExtensionSyncData::CreateFromSyncData(list[0]);
6043 ASSERT_TRUE(data.get());
6044 EXPECT_TRUE(data->enabled());
6045 EXPECT_FALSE(data->incognito_enabled());
6046 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6049 service()->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
6051 syncer::SyncDataList list =
6052 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6053 ASSERT_EQ(list.size(), 1U);
6054 scoped_ptr<ExtensionSyncData> data =
6055 ExtensionSyncData::CreateFromSyncData(list[0]);
6056 ASSERT_TRUE(data.get());
6057 EXPECT_FALSE(data->enabled());
6058 EXPECT_FALSE(data->incognito_enabled());
6059 EXPECT_EQ(ExtensionSyncData::BOOLEAN_UNSET, data->all_urls_enabled());
6062 extensions::util::SetIsIncognitoEnabled(good_crx, profile(), true);
6063 extensions::util::SetAllowedScriptingOnAllUrls(
6064 good_crx, profile(), false);
6066 syncer::SyncDataList list =
6067 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6068 ASSERT_EQ(list.size(), 1U);
6069 scoped_ptr<ExtensionSyncData> data =
6070 ExtensionSyncData::CreateFromSyncData(list[0]);
6071 ASSERT_TRUE(data.get());
6072 EXPECT_FALSE(data->enabled());
6073 EXPECT_TRUE(data->incognito_enabled());
6074 EXPECT_EQ(ExtensionSyncData::BOOLEAN_FALSE, data->all_urls_enabled());
6077 service()->EnableExtension(good_crx);
6078 extensions::util::SetAllowedScriptingOnAllUrls(
6079 good_crx, profile(), true);
6081 syncer::SyncDataList list =
6082 extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS);
6083 ASSERT_EQ(list.size(), 1U);
6084 scoped_ptr<ExtensionSyncData> data =
6085 ExtensionSyncData::CreateFromSyncData(list[0]);
6086 ASSERT_TRUE(data.get());
6087 EXPECT_TRUE(data->enabled());
6088 EXPECT_TRUE(data->incognito_enabled());
6089 EXPECT_EQ(ExtensionSyncData::BOOLEAN_TRUE, data->all_urls_enabled());
6093 TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
6094 InitializeEmptyExtensionService();
6095 InitializeExtensionSyncService();
6096 InstallCRXWithLocation(
6097 data_dir().AppendASCII("good.crx"), Manifest::EXTERNAL_PREF, INSTALL_NEW);
6098 const Extension* extension = service()->GetInstalledExtension(good_crx);
6099 ASSERT_TRUE(extension);
6101 syncer::FakeSyncChangeProcessor processor;
6102 extension_sync_service()->MergeDataAndStartSyncing(
6103 syncer::EXTENSIONS,
6104 syncer::SyncDataList(),
6105 scoped_ptr<syncer::SyncChangeProcessor>(
6106 new syncer::FakeSyncChangeProcessor),
6107 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6109 UninstallExtension(good_crx, false);
6110 EXPECT_TRUE(
6111 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
6113 sync_pb::EntitySpecifics specifics;
6114 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6115 sync_pb::ExtensionSpecifics* extension_specifics =
6116 app_specifics->mutable_extension();
6117 extension_specifics->set_id(good_crx);
6118 extension_specifics->set_version("1.0");
6119 extension_specifics->set_enabled(true);
6121 syncer::SyncData sync_data =
6122 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6123 syncer::SyncChange sync_change(FROM_HERE,
6124 syncer::SyncChange::ACTION_UPDATE,
6125 sync_data);
6126 syncer::SyncChangeList list(1);
6127 list[0] = sync_change;
6129 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6130 EXPECT_TRUE(
6131 ExtensionPrefs::Get(profile())->IsExternalExtensionUninstalled(good_crx));
6134 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
6135 InitializeEmptyExtensionService();
6136 InitializeExtensionSyncService();
6137 const Extension* app =
6138 PackAndInstallCRX(data_dir().AppendASCII("app"), INSTALL_NEW);
6139 ASSERT_TRUE(app);
6140 ASSERT_TRUE(app->is_app());
6142 syncer::FakeSyncChangeProcessor processor;
6143 extension_sync_service()->MergeDataAndStartSyncing(
6144 syncer::APPS,
6145 syncer::SyncDataList(),
6146 scoped_ptr<syncer::SyncChangeProcessor>(
6147 new syncer::FakeSyncChangeProcessor),
6148 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6150 syncer::StringOrdinal initial_ordinal =
6151 syncer::StringOrdinal::CreateInitialOrdinal();
6153 syncer::SyncDataList list =
6154 extension_sync_service()->GetAllSyncData(syncer::APPS);
6155 ASSERT_EQ(list.size(), 1U);
6157 scoped_ptr<AppSyncData> app_sync_data =
6158 AppSyncData::CreateFromSyncData(list[0]);
6159 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->app_launch_ordinal()));
6160 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6163 AppSorting* sorting = ExtensionPrefs::Get(profile())->app_sorting();
6164 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
6166 syncer::SyncDataList list =
6167 extension_sync_service()->GetAllSyncData(syncer::APPS);
6168 ASSERT_EQ(list.size(), 1U);
6170 scoped_ptr<AppSyncData> app_sync_data =
6171 AppSyncData::CreateFromSyncData(list[0]);
6172 ASSERT_TRUE(app_sync_data.get());
6173 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6174 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data->page_ordinal()));
6177 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
6179 syncer::SyncDataList list =
6180 extension_sync_service()->GetAllSyncData(syncer::APPS);
6181 ASSERT_EQ(list.size(), 1U);
6183 scoped_ptr<AppSyncData> app_sync_data =
6184 AppSyncData::CreateFromSyncData(list[0]);
6185 ASSERT_TRUE(app_sync_data.get());
6186 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->app_launch_ordinal()));
6187 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data->page_ordinal()));
6191 // TODO (rdevlin.cronin): The OnExtensionMoved() method has been removed from
6192 // ExtensionService, so this test probably needs a new home. Unfortunately, it
6193 // relies pretty heavily on things like InitializeExtension[Sync]Service() and
6194 // PackAndInstallCRX(). When we clean up a bit more, this should move out.
6195 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
6196 InitializeEmptyExtensionService();
6197 InitializeExtensionSyncService();
6198 const size_t kAppCount = 3;
6199 const Extension* apps[kAppCount];
6200 apps[0] = PackAndInstallCRX(data_dir().AppendASCII("app1"), INSTALL_NEW);
6201 apps[1] = PackAndInstallCRX(data_dir().AppendASCII("app2"), INSTALL_NEW);
6202 apps[2] = PackAndInstallCRX(data_dir().AppendASCII("app4"), INSTALL_NEW);
6203 for (size_t i = 0; i < kAppCount; ++i) {
6204 ASSERT_TRUE(apps[i]);
6205 ASSERT_TRUE(apps[i]->is_app());
6208 syncer::FakeSyncChangeProcessor processor;
6209 extension_sync_service()->MergeDataAndStartSyncing(
6210 syncer::APPS,
6211 syncer::SyncDataList(),
6212 scoped_ptr<syncer::SyncChangeProcessor>(
6213 new syncer::FakeSyncChangeProcessor),
6214 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6216 ExtensionPrefs::Get(service()->GetBrowserContext())
6217 ->app_sorting()
6218 ->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
6220 syncer::SyncDataList list =
6221 extension_sync_service()->GetAllSyncData(syncer::APPS);
6222 ASSERT_EQ(list.size(), 3U);
6224 scoped_ptr<AppSyncData> data[kAppCount];
6225 for (size_t i = 0; i < kAppCount; ++i) {
6226 data[i] = AppSyncData::CreateFromSyncData(list[i]);
6227 ASSERT_TRUE(data[i].get());
6230 // The sync data is not always in the same order our apps were installed in,
6231 // so we do that sorting here so we can make sure the values are changed as
6232 // expected.
6233 syncer::StringOrdinal app_launch_ordinals[kAppCount];
6234 for (size_t i = 0; i < kAppCount; ++i) {
6235 for (size_t j = 0; j < kAppCount; ++j) {
6236 if (apps[i]->id() == data[j]->id())
6237 app_launch_ordinals[i] = data[j]->app_launch_ordinal();
6241 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
6242 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
6246 TEST_F(ExtensionServiceTest, GetSyncDataList) {
6247 InitializeEmptyExtensionService();
6248 InitializeExtensionSyncService();
6249 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6250 InstallCRX(data_dir().AppendASCII("page_action.crx"), INSTALL_NEW);
6251 InstallCRX(data_dir().AppendASCII("theme.crx"), INSTALL_NEW);
6252 InstallCRX(data_dir().AppendASCII("theme2.crx"), INSTALL_NEW);
6254 syncer::FakeSyncChangeProcessor processor;
6255 extension_sync_service()->MergeDataAndStartSyncing(
6256 syncer::APPS,
6257 syncer::SyncDataList(),
6258 scoped_ptr<syncer::SyncChangeProcessor>(
6259 new syncer::FakeSyncChangeProcessor),
6260 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6261 extension_sync_service()->MergeDataAndStartSyncing(
6262 syncer::EXTENSIONS,
6263 syncer::SyncDataList(),
6264 scoped_ptr<syncer::SyncChangeProcessor>(
6265 new syncer::FakeSyncChangeProcessor),
6266 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6268 service()->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
6269 TerminateExtension(theme2_crx);
6271 EXPECT_EQ(0u, extension_sync_service()->GetAllSyncData(syncer::APPS).size());
6272 EXPECT_EQ(
6273 2u, extension_sync_service()->GetAllSyncData(syncer::EXTENSIONS).size());
6276 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
6277 InitializeEmptyExtensionService();
6278 InitializeExtensionSyncService();
6279 syncer::FakeSyncChangeProcessor processor;
6280 extension_sync_service()->MergeDataAndStartSyncing(
6281 syncer::EXTENSIONS,
6282 syncer::SyncDataList(),
6283 scoped_ptr<syncer::SyncChangeProcessor>(
6284 new syncer::FakeSyncChangeProcessor),
6285 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6287 sync_pb::EntitySpecifics specifics;
6288 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6289 ext_specifics->set_id(good_crx);
6290 ext_specifics->set_version("1.0");
6291 syncer::SyncData sync_data =
6292 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6293 syncer::SyncChange sync_change(FROM_HERE,
6294 syncer::SyncChange::ACTION_DELETE,
6295 sync_data);
6296 syncer::SyncChangeList list(1);
6297 list[0] = sync_change;
6299 // Should do nothing.
6300 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6301 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6303 // Install the extension.
6304 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6305 InstallCRX(extension_path, INSTALL_NEW);
6306 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6308 // Should uninstall the extension.
6309 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6310 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6312 // Should again do nothing.
6313 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6314 EXPECT_FALSE(service()->GetExtensionById(good_crx, true));
6317 TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
6318 InitializeEmptyExtensionService();
6319 InitializeExtensionSyncService();
6321 // Install the extension.
6322 base::FilePath extension_path = data_dir().AppendASCII("good.crx");
6323 InstallCRX(extension_path, INSTALL_NEW);
6324 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6326 sync_pb::EntitySpecifics specifics;
6327 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
6328 sync_pb::ExtensionSpecifics* extension_specifics =
6329 app_specifics->mutable_extension();
6330 extension_specifics->set_id(good_crx);
6331 extension_specifics->set_version(
6332 service()->GetInstalledExtension(good_crx)->version()->GetString());
6335 extension_specifics->set_enabled(true);
6336 syncer::SyncData sync_data =
6337 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6338 syncer::SyncChange sync_change(FROM_HERE,
6339 syncer::SyncChange::ACTION_DELETE,
6340 sync_data);
6341 syncer::SyncChangeList list(1);
6342 list[0] = sync_change;
6344 // Should do nothing
6345 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6346 EXPECT_TRUE(service()->GetExtensionById(good_crx, true));
6350 extension_specifics->set_enabled(false);
6351 syncer::SyncData sync_data =
6352 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6353 syncer::SyncChange sync_change(FROM_HERE,
6354 syncer::SyncChange::ACTION_UPDATE,
6355 sync_data);
6356 syncer::SyncChangeList list(1);
6357 list[0] = sync_change;
6359 // Should again do nothing.
6360 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6361 EXPECT_TRUE(service()->GetExtensionById(good_crx, false));
6365 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
6366 InitializeEmptyExtensionService();
6367 InitializeExtensionSyncService();
6368 syncer::FakeSyncChangeProcessor processor;
6369 extension_sync_service()->MergeDataAndStartSyncing(
6370 syncer::EXTENSIONS,
6371 syncer::SyncDataList(),
6372 scoped_ptr<syncer::SyncChangeProcessor>(
6373 new syncer::FakeSyncChangeProcessor),
6374 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6376 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6377 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6378 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6379 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6380 good_crx, profile()));
6381 const bool kDefaultAllowedScripting =
6382 extensions::util::DefaultAllowedScriptingOnAllUrls();
6383 EXPECT_EQ(kDefaultAllowedScripting,
6384 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6386 sync_pb::EntitySpecifics specifics;
6387 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6388 ext_specifics->set_id(good_crx);
6389 ext_specifics->set_version(
6390 service()->GetInstalledExtension(good_crx)->version()->GetString());
6391 ext_specifics->set_enabled(false);
6394 syncer::SyncData sync_data =
6395 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6396 syncer::SyncChange sync_change(FROM_HERE,
6397 syncer::SyncChange::ACTION_UPDATE,
6398 sync_data);
6399 syncer::SyncChangeList list(1);
6400 list[0] = sync_change;
6401 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6402 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6403 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6404 EXPECT_FALSE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6405 good_crx, profile()));
6406 EXPECT_EQ(kDefaultAllowedScripting,
6407 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6411 ext_specifics->set_enabled(true);
6412 ext_specifics->set_incognito_enabled(true);
6413 syncer::SyncData sync_data =
6414 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6415 syncer::SyncChange sync_change(FROM_HERE,
6416 syncer::SyncChange::ACTION_UPDATE,
6417 sync_data);
6418 syncer::SyncChangeList list(1);
6419 list[0] = sync_change;
6420 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6421 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6422 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6426 ext_specifics->set_enabled(false);
6427 ext_specifics->set_incognito_enabled(true);
6428 syncer::SyncData sync_data =
6429 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6430 syncer::SyncChange sync_change(FROM_HERE,
6431 syncer::SyncChange::ACTION_UPDATE,
6432 sync_data);
6433 syncer::SyncChangeList list(1);
6434 list[0] = sync_change;
6435 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6436 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6437 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6441 ext_specifics->set_enabled(true);
6442 ext_specifics->set_all_urls_enabled(!kDefaultAllowedScripting);
6443 syncer::SyncData sync_data =
6444 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6445 syncer::SyncChange sync_change(FROM_HERE,
6446 syncer::SyncChange::ACTION_UPDATE,
6447 sync_data);
6448 syncer::SyncChangeList list(1);
6449 list[0] = sync_change;
6450 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6451 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6452 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6453 good_crx, profile()));
6454 EXPECT_EQ(!kDefaultAllowedScripting,
6455 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6459 ext_specifics->set_all_urls_enabled(kDefaultAllowedScripting);
6460 syncer::SyncData sync_data =
6461 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6462 syncer::SyncChange sync_change(FROM_HERE,
6463 syncer::SyncChange::ACTION_UPDATE,
6464 sync_data);
6465 syncer::SyncChangeList list(1);
6466 list[0] = sync_change;
6467 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6468 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6469 EXPECT_TRUE(extensions::util::HasSetAllowedScriptingOnAllUrls(
6470 good_crx, profile()));
6471 EXPECT_EQ(kDefaultAllowedScripting,
6472 extensions::util::AllowedScriptingOnAllUrls(good_crx, profile()));
6475 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6478 TEST_F(ExtensionServiceTest, ProcessSyncDataNewExtension) {
6479 InitializeEmptyExtensionService();
6480 InitializeExtensionSyncService();
6481 syncer::FakeSyncChangeProcessor processor;
6482 extension_sync_service()->MergeDataAndStartSyncing(
6483 syncer::EXTENSIONS,
6484 syncer::SyncDataList(),
6485 scoped_ptr<syncer::SyncChangeProcessor>(
6486 new syncer::FakeSyncChangeProcessor),
6487 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6489 const base::FilePath path = data_dir().AppendASCII("good.crx");
6490 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6492 struct TestCase {
6493 const char* name; // For failure output only.
6494 bool sync_enabled; // The "enabled" flag coming in from Sync.
6495 // The disable reason(s) coming in from Sync, or -1 for "not set".
6496 int sync_disable_reasons;
6497 // The disable reason(s) that should be set on the installed extension.
6498 // This will usually be the same as |sync_disable_reasons|, but see the
6499 // "Legacy" case.
6500 int expect_disable_reasons;
6501 // Whether the extension's permissions should be auto-granted during
6502 // installation.
6503 bool expect_permissions_granted;
6504 } test_cases[] = {
6505 // Standard case: Extension comes in enabled; permissions should be granted
6506 // during installation.
6507 { "Standard", true, 0, 0, true },
6508 // If the extension comes in disabled, its permissions should still be
6509 // granted (the user already approved them on another machine).
6510 { "Disabled", false, Extension::DISABLE_USER_ACTION,
6511 Extension::DISABLE_USER_ACTION, true },
6512 // Legacy case (<M45): No disable reasons come in from Sync (see
6513 // crbug.com/484214). After installation, the reason should be set to
6514 // DISABLE_UNKNOWN_FROM_SYNC.
6515 { "Legacy", false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC, true },
6516 // If the extension came in disabled due to a permissions increase, then the
6517 // user has *not* approved the permissions, and they shouldn't be granted.
6518 // crbug.com/484214
6519 { "PermissionsIncrease", false, Extension::DISABLE_PERMISSIONS_INCREASE,
6520 Extension::DISABLE_PERMISSIONS_INCREASE, false },
6523 for (const TestCase& test_case : test_cases) {
6524 SCOPED_TRACE(test_case.name);
6526 sync_pb::EntitySpecifics specifics;
6527 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6528 ext_specifics->set_id(good_crx);
6529 ext_specifics->set_version(base::Version("1").GetString());
6530 ext_specifics->set_enabled(test_case.sync_enabled);
6531 if (test_case.sync_disable_reasons != -1)
6532 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6534 syncer::SyncData sync_data =
6535 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6536 syncer::SyncChange sync_change(FROM_HERE,
6537 syncer::SyncChange::ACTION_UPDATE,
6538 sync_data);
6539 syncer::SyncChangeList list(1, sync_change);
6540 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6542 ASSERT_TRUE(service()->pending_extension_manager()->IsIdPending(good_crx));
6543 UpdateExtension(good_crx, path, test_case.sync_enabled ? ENABLED
6544 : DISABLED);
6545 EXPECT_EQ(test_case.expect_disable_reasons,
6546 prefs->GetDisableReasons(good_crx));
6547 scoped_refptr<PermissionSet> permissions(
6548 prefs->GetGrantedPermissions(good_crx));
6549 EXPECT_EQ(test_case.expect_permissions_granted, !permissions->IsEmpty());
6550 ASSERT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6552 // Remove the extension again, so we can install it again for the next case.
6553 UninstallExtension(good_crx, false,
6554 test_case.sync_enabled ? Extension::ENABLED
6555 : Extension::DISABLED);
6559 TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
6560 InitializeExtensionServiceWithUpdater();
6561 InitializeExtensionSyncService();
6562 syncer::FakeSyncChangeProcessor processor;
6563 extension_sync_service()->MergeDataAndStartSyncing(
6564 syncer::EXTENSIONS,
6565 syncer::SyncDataList(),
6566 scoped_ptr<syncer::SyncChangeProcessor>(
6567 new syncer::FakeSyncChangeProcessor),
6568 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6570 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6571 TerminateExtension(good_crx);
6572 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6573 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6575 sync_pb::EntitySpecifics specifics;
6576 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6577 ext_specifics->set_id(good_crx);
6578 ext_specifics->set_version(
6579 service()->GetInstalledExtension(good_crx)->version()->GetString());
6580 ext_specifics->set_enabled(false);
6581 ext_specifics->set_incognito_enabled(true);
6582 syncer::SyncData sync_data =
6583 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6584 syncer::SyncChange sync_change(FROM_HERE,
6585 syncer::SyncChange::ACTION_UPDATE,
6586 sync_data);
6587 syncer::SyncChangeList list(1);
6588 list[0] = sync_change;
6590 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6591 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6592 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6594 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6597 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
6598 InitializeExtensionServiceWithUpdater();
6599 InitializeExtensionSyncService();
6600 syncer::FakeSyncChangeProcessor processor;
6601 extension_sync_service()->MergeDataAndStartSyncing(
6602 syncer::EXTENSIONS,
6603 syncer::SyncDataList(),
6604 scoped_ptr<syncer::SyncChangeProcessor>(
6605 new syncer::FakeSyncChangeProcessor),
6606 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6608 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6609 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6610 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6612 sync_pb::EntitySpecifics specifics;
6613 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6614 ext_specifics->set_id(good_crx);
6615 ext_specifics->set_enabled(true);
6618 ext_specifics->set_version(
6619 service()->GetInstalledExtension(good_crx)->version()->GetString());
6620 syncer::SyncData sync_data =
6621 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6622 syncer::SyncChange sync_change(FROM_HERE,
6623 syncer::SyncChange::ACTION_UPDATE,
6624 sync_data);
6625 syncer::SyncChangeList list(1);
6626 list[0] = sync_change;
6628 // Should do nothing if extension version == sync version.
6629 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6630 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6633 // Should do nothing if extension version > sync version (but see
6634 // the TODO in ProcessExtensionSyncData).
6636 ext_specifics->set_version("0.0.0.0");
6637 syncer::SyncData sync_data =
6638 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6639 syncer::SyncChange sync_change(FROM_HERE,
6640 syncer::SyncChange::ACTION_UPDATE,
6641 sync_data);
6642 syncer::SyncChangeList list(1);
6643 list[0] = sync_change;
6645 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6646 EXPECT_FALSE(service()->updater()->WillCheckSoon());
6649 // Should kick off an update if extension version < sync version.
6651 ext_specifics->set_version("9.9.9.9");
6652 syncer::SyncData sync_data =
6653 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6654 syncer::SyncChange sync_change(FROM_HERE,
6655 syncer::SyncChange::ACTION_UPDATE,
6656 sync_data);
6657 syncer::SyncChangeList list(1);
6658 list[0] = sync_change;
6660 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6661 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6664 EXPECT_FALSE(service()->pending_extension_manager()->IsIdPending(good_crx));
6667 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
6668 InitializeExtensionServiceWithUpdater();
6669 InitializeExtensionSyncService();
6670 syncer::FakeSyncChangeProcessor processor;
6671 extension_sync_service()->MergeDataAndStartSyncing(
6672 syncer::EXTENSIONS,
6673 syncer::SyncDataList(),
6674 scoped_ptr<syncer::SyncChangeProcessor>(
6675 new syncer::FakeSyncChangeProcessor),
6676 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6678 sync_pb::EntitySpecifics specifics;
6679 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6680 ext_specifics->set_id(good_crx);
6681 ext_specifics->set_enabled(false);
6682 ext_specifics->set_incognito_enabled(true);
6683 ext_specifics->set_update_url("http://www.google.com/");
6684 ext_specifics->set_version("1.2.3.4");
6685 syncer::SyncData sync_data =
6686 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6687 syncer::SyncChange sync_change(FROM_HERE,
6688 syncer::SyncChange::ACTION_UPDATE,
6689 sync_data);
6690 syncer::SyncChangeList list(1);
6691 list[0] = sync_change;
6693 EXPECT_TRUE(service()->IsExtensionEnabled(good_crx));
6694 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6695 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6696 EXPECT_TRUE(service()->updater()->WillCheckSoon());
6697 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
6698 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx, profile()));
6700 const extensions::PendingExtensionInfo* info;
6701 EXPECT_TRUE(
6702 (info = service()->pending_extension_manager()->GetById(good_crx)));
6703 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
6704 EXPECT_TRUE(info->is_from_sync());
6705 EXPECT_EQ(Manifest::INTERNAL, info->install_source());
6706 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
6709 TEST_F(ExtensionServiceTest, ProcessSyncDataEnableDisable) {
6710 InitializeEmptyExtensionService();
6711 InitializeExtensionSyncService();
6712 extension_sync_service()->MergeDataAndStartSyncing(
6713 syncer::EXTENSIONS,
6714 syncer::SyncDataList(),
6715 scoped_ptr<syncer::SyncChangeProcessor>(
6716 new syncer::FakeSyncChangeProcessor),
6717 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6719 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6721 struct TestCase {
6722 const char* name; // For failure output only.
6723 // Set of disable reasons before any Sync data comes in. If this is != 0,
6724 // the extension is disabled.
6725 int previous_disable_reasons;
6726 bool sync_enable; // The enabled flag coming in from Sync.
6727 // The disable reason(s) coming in from Sync, or -1 for "not set".
6728 int sync_disable_reasons;
6729 // The expected set of disable reasons after processing the Sync update. The
6730 // extension should be disabled iff this is != 0.
6731 int expect_disable_reasons;
6732 } test_cases[] = {
6733 { "NopEnable", 0, true, 0, 0 },
6734 { "NopDisable", Extension::DISABLE_USER_ACTION, false,
6735 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6736 { "Disable", 0, false, Extension::DISABLE_USER_ACTION,
6737 Extension::DISABLE_USER_ACTION },
6738 { "DisableLegacy", 0, false, -1, Extension::DISABLE_UNKNOWN_FROM_SYNC },
6739 { "AddDisableReason", Extension::DISABLE_REMOTE_INSTALL, false,
6740 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION,
6741 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION },
6742 { "AddDisableReasonLegacy", Extension::DISABLE_USER_ACTION, false, -1,
6743 Extension::DISABLE_USER_ACTION | Extension::DISABLE_UNKNOWN_FROM_SYNC},
6744 { "RemoveDisableReason",
6745 Extension::DISABLE_REMOTE_INSTALL | Extension::DISABLE_USER_ACTION, false,
6746 Extension::DISABLE_USER_ACTION, Extension::DISABLE_USER_ACTION },
6747 { "Enable", Extension::DISABLE_USER_ACTION, true, 0, 0 },
6748 { "EnableLegacy", Extension::DISABLE_USER_ACTION, true, -1, 0 },
6751 for (const TestCase& test_case : test_cases) {
6752 SCOPED_TRACE(test_case.name);
6754 std::string id;
6755 std::string version;
6756 // Don't keep |extension| around longer than necessary.
6758 const Extension* extension =
6759 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
6760 // The extension should now be installed and enabled.
6761 ASSERT_TRUE(extension);
6762 id = extension->id();
6763 version = extension->VersionString();
6765 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6767 // Disable it if the test case says so.
6768 if (test_case.previous_disable_reasons) {
6769 service()->DisableExtension(id, test_case.previous_disable_reasons);
6770 ASSERT_TRUE(registry()->disabled_extensions().Contains(id));
6773 // Now a sync update comes in.
6774 sync_pb::EntitySpecifics specifics;
6775 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6776 ext_specifics->set_id(id);
6777 ext_specifics->set_enabled(test_case.sync_enable);
6778 ext_specifics->set_version(version);
6779 if (test_case.sync_disable_reasons != -1)
6780 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6782 syncer::SyncData sync_data =
6783 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6784 syncer::SyncChange sync_change(FROM_HERE,
6785 syncer::SyncChange::ACTION_UPDATE,
6786 sync_data);
6787 syncer::SyncChangeList list(1, sync_change);
6788 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6790 // Check expectations.
6791 const bool expect_enabled = !test_case.expect_disable_reasons;
6792 EXPECT_EQ(expect_enabled, service()->IsExtensionEnabled(id));
6793 EXPECT_EQ(test_case.expect_disable_reasons, prefs->GetDisableReasons(id));
6795 // Remove the extension again, so we can install it again for the next case.
6796 UninstallExtension(id, false, expect_enabled ? Extension::ENABLED
6797 : Extension::DISABLED);
6801 TEST_F(ExtensionServiceTest, ProcessSyncDataPermissionApproval) {
6802 // This is the update URL specified in the test extension. Setting it here is
6803 // necessary to make it considered syncable.
6804 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6805 switches::kAppsGalleryUpdateURL,
6806 "http://localhost/autoupdate/updates.xml");
6808 InitializeEmptyExtensionService();
6809 InitializeExtensionSyncService();
6810 extension_sync_service()->MergeDataAndStartSyncing(
6811 syncer::EXTENSIONS,
6812 syncer::SyncDataList(),
6813 scoped_ptr<syncer::SyncChangeProcessor>(
6814 new syncer::FakeSyncChangeProcessor),
6815 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
6817 const base::FilePath base_path =
6818 data_dir().AppendASCII("permissions_increase");
6819 const base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
6820 const base::FilePath path_v1 = base_path.AppendASCII("v1");
6821 const base::FilePath path_v2 = base_path.AppendASCII("v2");
6823 base::ScopedTempDir crx_dir;
6824 ASSERT_TRUE(crx_dir.CreateUniqueTempDir());
6825 const base::FilePath crx_path_v1 = crx_dir.path().AppendASCII("temp1.crx");
6826 PackCRX(path_v1, pem_path, crx_path_v1);
6827 const base::FilePath crx_path_v2 = crx_dir.path().AppendASCII("temp2.crx");
6828 PackCRX(path_v2, pem_path, crx_path_v2);
6830 const std::string v1("1");
6831 const std::string v2("2");
6833 const ExtensionPrefs* prefs = ExtensionPrefs::Get(profile());
6835 struct TestCase {
6836 const char* name; // For failure output only.
6837 const std::string& sync_version; // The version coming in from Sync.
6838 // The disable reason(s) coming in from Sync, or -1 for "not set".
6839 int sync_disable_reasons;
6840 // Whether the extension's permissions should be auto-granted.
6841 bool expect_permissions_granted;
6842 } test_cases[] = {
6843 // Sync tells us to re-enable an older version. No permissions should be
6844 // granted, since we can't be sure if the user actually approved the right
6845 // set of permissions. Note that the extension will get disabled again the
6846 // next time ExtensionService::CheckPermissionsIncrease runs because of the
6847 // extra permissions.
6848 { "OldVersion", v1, 0, false },
6849 // Legacy case: Sync tells us to re-enable the extension, but doesn't
6850 // specify disable reasons. No permissions should be granted.
6851 { "Legacy", v2, -1, false },
6852 // Sync tells us to re-enable the extension and explicitly removes the
6853 // disable reasons. Now the extension should have its permissions granted.
6854 { "GrantPermissions", v2, 0, true },
6857 for (const TestCase& test_case : test_cases) {
6858 SCOPED_TRACE(test_case.name);
6860 std::string id;
6861 // Don't keep |extension| around longer than necessary (it'll be destroyed
6862 // during updating).
6864 const Extension* extension = InstallCRX(crx_path_v1, INSTALL_NEW);
6865 // The extension should now be installed and enabled.
6866 ASSERT_TRUE(extension);
6867 ASSERT_EQ(v1, extension->VersionString());
6868 id = extension->id();
6870 ASSERT_TRUE(registry()->enabled_extensions().Contains(id));
6872 scoped_refptr<PermissionSet> granted_permissions_v1(
6873 prefs->GetGrantedPermissions(id));
6875 // Update to a new version with increased permissions.
6876 UpdateExtension(id, crx_path_v2, DISABLED);
6878 // Now the extension should be disabled due to a permissions increase.
6880 const Extension* extension =
6881 registry()->disabled_extensions().GetByID(id);
6882 ASSERT_TRUE(extension);
6883 ASSERT_EQ(v2, extension->VersionString());
6885 ASSERT_TRUE(prefs->HasDisableReason(
6886 id, Extension::DISABLE_PERMISSIONS_INCREASE));
6888 // No new permissions should have been granted.
6889 scoped_refptr<PermissionSet> granted_permissions_v2(
6890 prefs->GetGrantedPermissions(id));
6891 ASSERT_EQ(*granted_permissions_v1, *granted_permissions_v2);
6893 // Now a sync update comes in.
6894 sync_pb::EntitySpecifics specifics;
6895 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
6896 ext_specifics->set_id(id);
6897 ext_specifics->set_enabled(true);
6898 ext_specifics->set_version(test_case.sync_version);
6899 if (test_case.sync_disable_reasons != -1)
6900 ext_specifics->set_disable_reasons(test_case.sync_disable_reasons);
6902 syncer::SyncData sync_data =
6903 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
6904 syncer::SyncChange sync_change(FROM_HERE,
6905 syncer::SyncChange::ACTION_UPDATE,
6906 sync_data);
6907 syncer::SyncChangeList list(1, sync_change);
6908 extension_sync_service()->ProcessSyncChanges(FROM_HERE, list);
6910 // Check expectations.
6911 EXPECT_TRUE(registry()->GetExtensionById(id, ExtensionRegistry::ENABLED));
6912 scoped_refptr<PermissionSet> granted_permissions(
6913 prefs->GetGrantedPermissions(id));
6914 if (test_case.expect_permissions_granted) {
6915 scoped_refptr<PermissionSet> active_permissions(
6916 prefs->GetActivePermissions(id));
6917 EXPECT_EQ(*granted_permissions, *active_permissions);
6918 } else {
6919 EXPECT_EQ(*granted_permissions, *granted_permissions_v1);
6921 EXPECT_EQ(Extension::DISABLE_NONE, prefs->GetDisableReasons(id));
6923 // Remove the extension again, so we can install it again for the next case.
6924 UninstallExtension(id, false);
6928 #if defined(ENABLE_SUPERVISED_USERS)
6929 class ScopedSupervisedUserServiceDelegate
6930 : public SupervisedUserService::Delegate {
6931 public:
6932 explicit ScopedSupervisedUserServiceDelegate(SupervisedUserService* service)
6933 : service_(service) {
6934 service_->SetDelegate(this);
6936 ~ScopedSupervisedUserServiceDelegate() override {
6937 service_->SetDelegate(nullptr);
6940 // This prevents the legacy supervised user init code from running.
6941 bool SetActive(bool active) override { return true; }
6943 private:
6944 SupervisedUserService* service_;
6947 class MockPermissionRequestCreator : public PermissionRequestCreator {
6948 public:
6949 MockPermissionRequestCreator() {}
6950 ~MockPermissionRequestCreator() override {}
6952 bool IsEnabled() const override { return true; }
6954 void CreateURLAccessRequest(const GURL& url_requested,
6955 const SuccessCallback& callback) override {
6956 FAIL();
6959 MOCK_METHOD2(CreateExtensionUpdateRequest,
6960 void(const std::string& id,
6961 const SupervisedUserService::SuccessCallback& callback));
6963 private:
6964 DISALLOW_COPY_AND_ASSIGN(MockPermissionRequestCreator);
6967 TEST_F(ExtensionServiceTest, SupervisedUser_InstallOnlyAllowedByCustodian) {
6968 ExtensionServiceInitParams params = CreateDefaultInitParams();
6969 params.profile_is_supervised = true;
6970 InitializeExtensionService(params);
6972 SupervisedUserService* supervised_user_service =
6973 SupervisedUserServiceFactory::GetForProfile(profile());
6974 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
6975 supervised_user_service->Init();
6977 base::FilePath path1 = data_dir().AppendASCII("good.crx");
6978 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
6979 const Extension* extensions[] = {
6980 InstallCRX(path1, INSTALL_FAILED),
6981 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
6984 // Only the extension with the "installed by custodian" flag should have been
6985 // installed and enabled.
6986 EXPECT_FALSE(extensions[0]);
6987 ASSERT_TRUE(extensions[1]);
6988 EXPECT_TRUE(registry()->enabled_extensions().Contains(extensions[1]->id()));
6991 TEST_F(ExtensionServiceTest, SupervisedUser_PreinstalledExtension) {
6992 ExtensionServiceInitParams params = CreateDefaultInitParams();
6993 // Do *not* set the profile to supervised here!
6994 InitializeExtensionService(params);
6996 SupervisedUserService* supervised_user_service =
6997 SupervisedUserServiceFactory::GetForProfile(profile());
6998 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
6999 supervised_user_service->Init();
7001 // Install an extension.
7002 base::FilePath path = data_dir().AppendASCII("good.crx");
7003 const Extension* extension = InstallCRX(path, INSTALL_NEW);
7004 std::string id = extension->id();
7006 // Now make the profile supervised.
7007 profile()->AsTestingProfile()->SetSupervisedUserId(
7008 supervised_users::kChildAccountSUID);
7010 // The extension should not be enabled anymore.
7011 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7014 TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithoutPermissionIncrease) {
7015 ExtensionServiceInitParams params = CreateDefaultInitParams();
7016 params.profile_is_supervised = true;
7017 InitializeExtensionService(params);
7019 SupervisedUserService* supervised_user_service =
7020 SupervisedUserServiceFactory::GetForProfile(profile());
7021 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7022 supervised_user_service->Init();
7024 base::FilePath base_path = data_dir().AppendASCII("autoupdate");
7025 base::FilePath pem_path = base_path.AppendASCII("key.pem");
7027 base::FilePath path = base_path.AppendASCII("v1");
7028 const Extension* extension =
7029 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
7030 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7031 // The extension must now be installed and enabled.
7032 ASSERT_TRUE(extension);
7033 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7035 // Save the id, as the extension object will be destroyed during updating.
7036 std::string id = extension->id();
7038 std::string old_version = extension->VersionString();
7040 // Update to a new version.
7041 path = base_path.AppendASCII("v2");
7042 PackCRXAndUpdateExtension(id, path, pem_path, ENABLED);
7044 // The extension should still be there and enabled.
7045 extension = registry()->enabled_extensions().GetByID(id);
7046 ASSERT_TRUE(extension);
7047 // The version should have changed.
7048 EXPECT_NE(extension->VersionString(), old_version);
7051 TEST_F(ExtensionServiceTest, SupervisedUser_UpdateWithPermissionIncrease) {
7052 ExtensionServiceInitParams params = CreateDefaultInitParams();
7053 params.profile_is_supervised = true;
7054 InitializeExtensionService(params);
7056 SupervisedUserService* supervised_user_service =
7057 SupervisedUserServiceFactory::GetForProfile(profile());
7058 ScopedSupervisedUserServiceDelegate delegate(supervised_user_service);
7059 supervised_user_service->Init();
7060 MockPermissionRequestCreator* creator = new MockPermissionRequestCreator;
7061 supervised_user_service->AddPermissionRequestCreator(
7062 make_scoped_ptr(creator));
7064 base::FilePath base_path = data_dir().AppendASCII("permissions_increase");
7065 base::FilePath pem_path = base_path.AppendASCII("permissions.pem");
7067 base::FilePath path = base_path.AppendASCII("v1");
7068 const Extension* extension =
7069 PackAndInstallCRX(path, pem_path, INSTALL_NEW,
7070 Extension::WAS_INSTALLED_BY_CUSTODIAN);
7071 // The extension must now be installed and enabled.
7072 ASSERT_TRUE(extension);
7073 ASSERT_TRUE(registry()->enabled_extensions().Contains(extension->id()));
7075 // Save the id, as the extension object will be destroyed during updating.
7076 std::string id = extension->id();
7078 std::string old_version = extension->VersionString();
7080 // Update to a new version with increased permissions.
7081 EXPECT_CALL(*creator,
7082 CreateExtensionUpdateRequest(id + ":2", testing::_));
7083 path = base_path.AppendASCII("v2");
7084 PackCRXAndUpdateExtension(id, path, pem_path, DISABLED);
7086 // The extension should still be there, but disabled.
7087 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
7088 extension = registry()->disabled_extensions().GetByID(id);
7089 ASSERT_TRUE(extension);
7090 // The version should have changed.
7091 EXPECT_NE(extension->VersionString(), old_version);
7094 TEST_F(ExtensionServiceTest,
7095 SupervisedUser_SyncUninstallByCustodianSkipsPolicy) {
7096 InitializeEmptyExtensionService();
7097 InitializeExtensionSyncService();
7098 extension_sync_service()->MergeDataAndStartSyncing(
7099 syncer::EXTENSIONS,
7100 syncer::SyncDataList(),
7101 scoped_ptr<syncer::SyncChangeProcessor>(
7102 new syncer::FakeSyncChangeProcessor),
7103 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
7105 // Install two extensions.
7106 base::FilePath path1 = data_dir().AppendASCII("good.crx");
7107 base::FilePath path2 = data_dir().AppendASCII("good2048.crx");
7108 const Extension* extensions[] = {
7109 InstallCRX(path1, INSTALL_NEW),
7110 InstallCRX(path2, INSTALL_NEW, Extension::WAS_INSTALLED_BY_CUSTODIAN)
7113 // Add a policy provider that will disallow any changes.
7114 extensions::TestManagementPolicyProvider provider(
7115 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
7116 GetManagementPolicy()->RegisterProvider(&provider);
7118 // Create a sync deletion for each extension.
7119 syncer::SyncChangeList change_list;
7120 for (size_t i = 0; i < arraysize(extensions); i++) {
7121 const std::string& id = extensions[i]->id();
7122 sync_pb::EntitySpecifics specifics;
7123 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
7124 ext_specifics->set_id(id);
7125 ext_specifics->set_version("1.0");
7126 ext_specifics->set_installed_by_custodian(
7127 extensions[i]->was_installed_by_custodian());
7128 syncer::SyncData sync_data =
7129 syncer::SyncData::CreateLocalData(id, "Name", specifics);
7130 change_list.push_back(syncer::SyncChange(FROM_HERE,
7131 syncer::SyncChange::ACTION_DELETE,
7132 sync_data));
7135 // Save the extension ids, as uninstalling destroys the Extension instance.
7136 std::string extension_ids[] = {
7137 extensions[0]->id(),
7138 extensions[1]->id()
7141 // Now apply the uninstallations.
7142 extension_sync_service()->ProcessSyncChanges(FROM_HERE, change_list);
7144 // Uninstalling the extension without installed_by_custodian should have been
7145 // blocked by policy, so it should still be there.
7146 EXPECT_TRUE(registry()->enabled_extensions().Contains(extension_ids[0]));
7148 // But installed_by_custodian should result in bypassing the policy check.
7149 EXPECT_FALSE(
7150 registry()->GenerateInstalledExtensionsSet()->Contains(extension_ids[1]));
7152 #endif // defined(ENABLE_SUPERVISED_USERS)
7154 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
7155 InitializeEmptyExtensionService();
7157 base::FilePath path = data_dir().AppendASCII("good.crx");
7158 InstallCRX(path, INSTALL_NEW);
7159 ValidatePrefKeyCount(1u);
7160 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7161 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7163 extensions::PendingExtensionManager* pending =
7164 service()->pending_extension_manager();
7165 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7167 // Skip install when the location is the same.
7168 EXPECT_FALSE(
7169 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
7170 std::string(),
7171 GURL(kGoodUpdateURL),
7172 Manifest::INTERNAL,
7173 Extension::NO_FLAGS,
7174 false));
7175 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7177 // Install when the location has higher priority.
7178 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
7179 kGoodId,
7180 std::string(),
7181 GURL(kGoodUpdateURL),
7182 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7183 Extension::NO_FLAGS,
7184 false));
7185 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7187 // Try the low priority again. Should be rejected.
7188 EXPECT_FALSE(service()->OnExternalExtensionUpdateUrlFound(
7189 kGoodId,
7190 std::string(),
7191 GURL(kGoodUpdateURL),
7192 Manifest::EXTERNAL_PREF_DOWNLOAD,
7193 Extension::NO_FLAGS,
7194 false));
7195 // The existing record should still be present in the pending extension
7196 // manager.
7197 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7199 pending->Remove(kGoodId);
7201 // Skip install when the location has the same priority as the installed
7202 // location.
7203 EXPECT_FALSE(
7204 service()->OnExternalExtensionUpdateUrlFound(kGoodId,
7205 std::string(),
7206 GURL(kGoodUpdateURL),
7207 Manifest::INTERNAL,
7208 Extension::NO_FLAGS,
7209 false));
7211 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7214 TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
7215 Version older_version("0.1.0.0");
7216 Version newer_version("2.0.0.0");
7218 // We don't want the extension to be installed. A path that doesn't
7219 // point to a valid CRX ensures this.
7220 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
7222 const int kCreationFlags = 0;
7223 const bool kDontMarkAcknowledged = false;
7224 const bool kDontInstallImmediately = false;
7226 InitializeEmptyExtensionService();
7228 // The test below uses install source constants to test that
7229 // priority is enforced. It assumes a specific ranking of install
7230 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
7231 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
7232 // The following assertions verify these assumptions:
7233 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
7234 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
7235 Manifest::EXTERNAL_PREF));
7236 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
7237 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
7238 Manifest::INTERNAL));
7239 ASSERT_EQ(Manifest::EXTERNAL_PREF,
7240 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
7241 Manifest::INTERNAL));
7243 extensions::PendingExtensionManager* pending =
7244 service()->pending_extension_manager();
7245 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7248 // Simulate an external source adding the extension as INTERNAL.
7249 content::WindowedNotificationObserver observer(
7250 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7251 content::NotificationService::AllSources());
7252 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7253 kGoodId,
7254 &older_version,
7255 kInvalidPathToCrx,
7256 Manifest::INTERNAL,
7257 kCreationFlags,
7258 kDontMarkAcknowledged,
7259 kDontInstallImmediately));
7260 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7261 observer.Wait();
7262 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7266 // Simulate an external source adding the extension as EXTERNAL_PREF.
7267 content::WindowedNotificationObserver observer(
7268 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7269 content::NotificationService::AllSources());
7270 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7271 kGoodId,
7272 &older_version,
7273 kInvalidPathToCrx,
7274 Manifest::EXTERNAL_PREF,
7275 kCreationFlags,
7276 kDontMarkAcknowledged,
7277 kDontInstallImmediately));
7278 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7279 observer.Wait();
7280 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7283 // Simulate an external source adding as EXTERNAL_PREF again.
7284 // This is rejected because the version and the location are the same as
7285 // the previous installation, which is still pending.
7286 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7287 kGoodId,
7288 &older_version,
7289 kInvalidPathToCrx,
7290 Manifest::EXTERNAL_PREF,
7291 kCreationFlags,
7292 kDontMarkAcknowledged,
7293 kDontInstallImmediately));
7294 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7296 // Try INTERNAL again. Should fail.
7297 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7298 kGoodId,
7299 &older_version,
7300 kInvalidPathToCrx,
7301 Manifest::INTERNAL,
7302 kCreationFlags,
7303 kDontMarkAcknowledged,
7304 kDontInstallImmediately));
7305 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7308 // Now the registry adds the extension.
7309 content::WindowedNotificationObserver observer(
7310 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7311 content::NotificationService::AllSources());
7312 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7313 kGoodId,
7314 &older_version,
7315 kInvalidPathToCrx,
7316 Manifest::EXTERNAL_REGISTRY,
7317 kCreationFlags,
7318 kDontMarkAcknowledged,
7319 kDontInstallImmediately));
7320 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7321 observer.Wait();
7322 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
7325 // Registry outranks both external pref and internal, so both fail.
7326 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7327 kGoodId,
7328 &older_version,
7329 kInvalidPathToCrx,
7330 Manifest::EXTERNAL_PREF,
7331 kCreationFlags,
7332 kDontMarkAcknowledged,
7333 kDontInstallImmediately));
7334 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7336 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7337 kGoodId,
7338 &older_version,
7339 kInvalidPathToCrx,
7340 Manifest::INTERNAL,
7341 kCreationFlags,
7342 kDontMarkAcknowledged,
7343 kDontInstallImmediately));
7344 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7346 pending->Remove(kGoodId);
7348 // Install the extension.
7349 base::FilePath path = data_dir().AppendASCII("good.crx");
7350 const Extension* ext = InstallCRX(path, INSTALL_NEW);
7351 ValidatePrefKeyCount(1u);
7352 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
7353 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
7355 // Now test the logic of OnExternalExtensionFileFound() when the extension
7356 // being added is already installed.
7358 // Tests assume |older_version| is less than the installed version, and
7359 // |newer_version| is greater. Verify this:
7360 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
7361 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
7363 // An external install for the same location should fail if the version is
7364 // older, or the same, and succeed if the version is newer.
7366 // Older than the installed version...
7367 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7368 kGoodId,
7369 &older_version,
7370 kInvalidPathToCrx,
7371 Manifest::INTERNAL,
7372 kCreationFlags,
7373 kDontMarkAcknowledged,
7374 kDontInstallImmediately));
7375 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7377 // Same version as the installed version...
7378 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7379 kGoodId,
7380 ext->version(),
7381 kInvalidPathToCrx,
7382 Manifest::INTERNAL,
7383 kCreationFlags,
7384 kDontMarkAcknowledged,
7385 kDontInstallImmediately));
7386 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7388 // Newer than the installed version...
7389 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7390 kGoodId,
7391 &newer_version,
7392 kInvalidPathToCrx,
7393 Manifest::INTERNAL,
7394 kCreationFlags,
7395 kDontMarkAcknowledged,
7396 kDontInstallImmediately));
7397 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7399 // An external install for a higher priority install source should succeed
7400 // if the version is greater. |older_version| is not...
7401 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7402 kGoodId,
7403 &older_version,
7404 kInvalidPathToCrx,
7405 Manifest::EXTERNAL_PREF,
7406 kCreationFlags,
7407 kDontMarkAcknowledged,
7408 kDontInstallImmediately));
7409 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7411 // |newer_version| is newer.
7412 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7413 kGoodId,
7414 &newer_version,
7415 kInvalidPathToCrx,
7416 Manifest::EXTERNAL_PREF,
7417 kCreationFlags,
7418 kDontMarkAcknowledged,
7419 kDontInstallImmediately));
7420 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7422 // An external install for an even higher priority install source should
7423 // succeed if the version is greater.
7424 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7425 kGoodId,
7426 &newer_version,
7427 kInvalidPathToCrx,
7428 Manifest::EXTERNAL_REGISTRY,
7429 kCreationFlags,
7430 kDontMarkAcknowledged,
7431 kDontInstallImmediately));
7432 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7434 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
7435 // adding from external pref will now fail.
7436 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7437 kGoodId,
7438 &newer_version,
7439 kInvalidPathToCrx,
7440 Manifest::EXTERNAL_PREF,
7441 kCreationFlags,
7442 kDontMarkAcknowledged,
7443 kDontInstallImmediately));
7444 EXPECT_TRUE(pending->IsIdPending(kGoodId));
7447 TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
7448 Version kVersion123("1.2.3");
7449 Version kVersion124("1.2.4");
7450 Version kVersion125("1.2.5");
7451 const base::FilePath kInvalidPathToCrx(FILE_PATH_LITERAL("invalid_path"));
7452 const int kCreationFlags = 0;
7453 const bool kDontMarkAcknowledged = false;
7454 const bool kDontInstallImmediately = false;
7456 InitializeEmptyExtensionService();
7458 extensions::PendingExtensionManager* pending =
7459 service()->pending_extension_manager();
7460 EXPECT_FALSE(pending->IsIdPending(kGoodId));
7462 // An external provider starts installing from a local crx.
7463 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7464 kGoodId,
7465 &kVersion123,
7466 kInvalidPathToCrx,
7467 Manifest::EXTERNAL_PREF,
7468 kCreationFlags,
7469 kDontMarkAcknowledged,
7470 kDontInstallImmediately));
7471 const extensions::PendingExtensionInfo* info;
7472 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7473 EXPECT_TRUE(info->version().IsValid());
7474 EXPECT_TRUE(info->version().Equals(kVersion123));
7476 // Adding a newer version overrides the currently pending version.
7477 EXPECT_TRUE(service()->OnExternalExtensionFileFound(
7478 kGoodId,
7479 &kVersion124,
7480 kInvalidPathToCrx,
7481 Manifest::EXTERNAL_PREF,
7482 kCreationFlags,
7483 kDontMarkAcknowledged,
7484 kDontInstallImmediately));
7485 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7486 EXPECT_TRUE(info->version().IsValid());
7487 EXPECT_TRUE(info->version().Equals(kVersion124));
7489 // Adding an older version fails.
7490 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7491 kGoodId,
7492 &kVersion123,
7493 kInvalidPathToCrx,
7494 Manifest::EXTERNAL_PREF,
7495 kCreationFlags,
7496 kDontMarkAcknowledged,
7497 kDontInstallImmediately));
7498 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7499 EXPECT_TRUE(info->version().IsValid());
7500 EXPECT_TRUE(info->version().Equals(kVersion124));
7502 // Adding an older version fails even when coming from a higher-priority
7503 // location.
7504 EXPECT_FALSE(service()->OnExternalExtensionFileFound(
7505 kGoodId,
7506 &kVersion123,
7507 kInvalidPathToCrx,
7508 Manifest::EXTERNAL_REGISTRY,
7509 kCreationFlags,
7510 kDontMarkAcknowledged,
7511 kDontInstallImmediately));
7512 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7513 EXPECT_TRUE(info->version().IsValid());
7514 EXPECT_TRUE(info->version().Equals(kVersion124));
7516 // Adding the latest version from the webstore overrides a specific version.
7517 GURL kUpdateUrl("http://example.com/update");
7518 EXPECT_TRUE(service()->OnExternalExtensionUpdateUrlFound(
7519 kGoodId,
7520 std::string(),
7521 kUpdateUrl,
7522 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7523 Extension::NO_FLAGS,
7524 false));
7525 EXPECT_TRUE((info = pending->GetById(kGoodId)));
7526 EXPECT_FALSE(info->version().IsValid());
7529 // This makes sure we can package and install CRX files that use whitelisted
7530 // permissions.
7531 TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
7532 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
7533 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
7534 extensions::switches::kWhitelistedExtensionID, test_id);
7536 InitializeEmptyExtensionService();
7537 base::FilePath path = data_dir().AppendASCII("permissions");
7538 base::FilePath pem_path = path
7539 .AppendASCII("whitelist.pem");
7540 path = path
7541 .AppendASCII("whitelist");
7543 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
7544 EXPECT_EQ(0u, GetErrors().size());
7545 ASSERT_EQ(1u, registry()->enabled_extensions().size());
7546 EXPECT_EQ(test_id, extension->id());
7549 // Test that when multiple sources try to install an extension,
7550 // we consistently choose the right one. To make tests easy to read,
7551 // methods that fake requests to install crx files in several ways
7552 // are provided.
7553 class ExtensionSourcePriorityTest : public ExtensionServiceTest {
7554 public:
7555 void SetUp() override {
7556 ExtensionServiceTest::SetUp();
7558 // All tests use a single extension. Put the id and path in member vars
7559 // that all methods can read.
7560 crx_id_ = kGoodId;
7561 crx_path_ = data_dir().AppendASCII("good.crx");
7564 // Fake an external source adding a URL to fetch an extension from.
7565 bool AddPendingExternalPrefUrl() {
7566 return service()->pending_extension_manager()->AddFromExternalUpdateUrl(
7567 crx_id_,
7568 std::string(),
7569 GURL(),
7570 Manifest::EXTERNAL_PREF_DOWNLOAD,
7571 Extension::NO_FLAGS,
7572 false);
7575 // Fake an external file from external_extensions.json.
7576 bool AddPendingExternalPrefFileInstall() {
7577 Version version("1.0.0.0");
7579 return service()->OnExternalExtensionFileFound(crx_id_,
7580 &version,
7581 crx_path_,
7582 Manifest::EXTERNAL_PREF,
7583 Extension::NO_FLAGS,
7584 false,
7585 false);
7588 // Fake a request from sync to install an extension.
7589 bool AddPendingSyncInstall() {
7590 return service()->pending_extension_manager()->AddFromSync(
7591 crx_id_,
7592 GURL(kGoodUpdateURL),
7593 &IsExtension,
7594 kGoodRemoteInstall,
7595 kGoodInstalledByCustodian);
7598 // Fake a policy install.
7599 bool AddPendingPolicyInstall() {
7600 // Get path to the CRX with id |kGoodId|.
7601 return service()->OnExternalExtensionUpdateUrlFound(
7602 crx_id_,
7603 std::string(),
7604 GURL(),
7605 Manifest::EXTERNAL_POLICY_DOWNLOAD,
7606 Extension::NO_FLAGS,
7607 false);
7610 // Get the install source of a pending extension.
7611 Manifest::Location GetPendingLocation() {
7612 const extensions::PendingExtensionInfo* info;
7613 EXPECT_TRUE(
7614 (info = service()->pending_extension_manager()->GetById(crx_id_)));
7615 return info->install_source();
7618 // Is an extension pending from a sync request?
7619 bool GetPendingIsFromSync() {
7620 const extensions::PendingExtensionInfo* info;
7621 EXPECT_TRUE(
7622 (info = service()->pending_extension_manager()->GetById(crx_id_)));
7623 return info->is_from_sync();
7626 // Is the CRX id these tests use pending?
7627 bool IsCrxPending() {
7628 return service()->pending_extension_manager()->IsIdPending(crx_id_);
7631 // Is an extension installed?
7632 bool IsCrxInstalled() {
7633 return (service()->GetExtensionById(crx_id_, true) != NULL);
7636 protected:
7637 // All tests use a single extension. Making the id and path member
7638 // vars avoids pasing the same argument to every method.
7639 std::string crx_id_;
7640 base::FilePath crx_path_;
7643 // Test that a pending request for installation of an external CRX from
7644 // an update URL overrides a pending request to install the same extension
7645 // from sync.
7646 TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
7647 InitializeEmptyExtensionService();
7649 ASSERT_FALSE(IsCrxInstalled());
7651 // Install pending extension from sync.
7652 content::WindowedNotificationObserver observer(
7653 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7654 content::NotificationService::AllSources());
7655 EXPECT_TRUE(AddPendingSyncInstall());
7656 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
7657 EXPECT_TRUE(GetPendingIsFromSync());
7658 ASSERT_FALSE(IsCrxInstalled());
7660 // Install pending as external prefs json would.
7661 AddPendingExternalPrefFileInstall();
7662 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
7663 ASSERT_FALSE(IsCrxInstalled());
7665 // Another request from sync should be ignored.
7666 EXPECT_FALSE(AddPendingSyncInstall());
7667 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
7668 ASSERT_FALSE(IsCrxInstalled());
7670 observer.Wait();
7671 VerifyCrxInstall(crx_path_, INSTALL_NEW);
7672 ASSERT_TRUE(IsCrxInstalled());
7675 // Test that an install of an external CRX from an update overrides
7676 // an install of the same extension from sync.
7677 TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
7678 InitializeEmptyExtensionService();
7679 ASSERT_FALSE(IsCrxInstalled());
7681 EXPECT_TRUE(AddPendingSyncInstall());
7682 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
7683 EXPECT_TRUE(GetPendingIsFromSync());
7684 ASSERT_FALSE(IsCrxInstalled());
7686 ASSERT_TRUE(AddPendingExternalPrefUrl());
7687 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
7688 EXPECT_FALSE(GetPendingIsFromSync());
7689 ASSERT_FALSE(IsCrxInstalled());
7691 EXPECT_FALSE(AddPendingSyncInstall());
7692 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
7693 EXPECT_FALSE(GetPendingIsFromSync());
7694 ASSERT_FALSE(IsCrxInstalled());
7697 // Test that an external install request stops sync from installing
7698 // the same extension.
7699 TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
7700 InitializeEmptyExtensionService();
7701 ASSERT_FALSE(IsCrxInstalled());
7703 // External prefs starts an install.
7704 AddPendingExternalPrefFileInstall();
7706 // Crx installer was made, but has not yet run.
7707 ASSERT_FALSE(IsCrxInstalled());
7709 // Before the CRX installer runs, Sync requests that the same extension
7710 // be installed. Should fail, because an external source is pending.
7711 content::WindowedNotificationObserver observer(
7712 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7713 content::NotificationService::AllSources());
7714 ASSERT_FALSE(AddPendingSyncInstall());
7716 // Wait for the external source to install.
7717 observer.Wait();
7718 VerifyCrxInstall(crx_path_, INSTALL_NEW);
7719 ASSERT_TRUE(IsCrxInstalled());
7721 // Now that the extension is installed, sync request should fail
7722 // because the extension is already installed.
7723 ASSERT_FALSE(AddPendingSyncInstall());
7726 // Test that installing an external extension displays a GlobalError.
7727 TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
7728 FeatureSwitch::ScopedOverride prompt(
7729 FeatureSwitch::prompt_for_external_extensions(), true);
7731 InitializeEmptyExtensionService();
7732 MockExtensionProvider* provider =
7733 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7734 AddMockExternalProvider(provider);
7736 service()->external_install_manager()->UpdateExternalExtensionAlert();
7737 // Should return false, meaning there aren't any extensions that the user
7738 // needs to know about.
7739 EXPECT_FALSE(
7740 service()->external_install_manager()->HasExternalInstallError());
7742 // This is a normal extension, installed normally.
7743 // This should NOT trigger an alert.
7744 service()->set_extensions_enabled(true);
7745 base::FilePath path = data_dir().AppendASCII("good.crx");
7746 InstallCRX(path, INSTALL_NEW);
7748 service()->CheckForExternalUpdates();
7749 base::RunLoop().RunUntilIdle();
7750 EXPECT_FALSE(
7751 service()->external_install_manager()->HasExternalInstallError());
7753 // A hosted app, installed externally.
7754 // This should NOT trigger an alert.
7755 provider->UpdateOrAddExtension(
7756 hosted_app, "1.0.0.0", data_dir().AppendASCII("hosted_app.crx"));
7758 content::WindowedNotificationObserver observer(
7759 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7760 content::NotificationService::AllSources());
7761 service()->CheckForExternalUpdates();
7762 observer.Wait();
7763 EXPECT_FALSE(
7764 service()->external_install_manager()->HasExternalInstallError());
7766 // Another normal extension, but installed externally.
7767 // This SHOULD trigger an alert.
7768 provider->UpdateOrAddExtension(
7769 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7771 content::WindowedNotificationObserver observer2(
7772 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7773 content::NotificationService::AllSources());
7774 service()->CheckForExternalUpdates();
7775 observer2.Wait();
7776 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7779 // Test that external extensions are initially disabled, and that enabling
7780 // them clears the prompt.
7781 TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
7782 FeatureSwitch::ScopedOverride prompt(
7783 FeatureSwitch::prompt_for_external_extensions(), true);
7785 InitializeEmptyExtensionService();
7786 MockExtensionProvider* provider =
7787 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7788 AddMockExternalProvider(provider);
7790 provider->UpdateOrAddExtension(
7791 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7793 content::WindowedNotificationObserver observer(
7794 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7795 content::NotificationService::AllSources());
7796 service()->CheckForExternalUpdates();
7797 observer.Wait();
7798 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7799 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
7801 const Extension* extension =
7802 registry()->disabled_extensions().GetByID(page_action);
7803 EXPECT_TRUE(extension);
7804 EXPECT_EQ(page_action, extension->id());
7806 service()->EnableExtension(page_action);
7807 EXPECT_FALSE(
7808 service()->external_install_manager()->HasExternalInstallError());
7809 EXPECT_TRUE(service()->IsExtensionEnabled(page_action));
7812 // Test that installing multiple external extensions works.
7813 // Flaky on windows; http://crbug.com/295757 .
7814 #if defined(OS_WIN)
7815 #define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
7816 #else
7817 #define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
7818 #endif
7819 TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
7820 FeatureSwitch::ScopedOverride prompt(
7821 FeatureSwitch::prompt_for_external_extensions(), true);
7823 InitializeEmptyExtensionService();
7824 MockExtensionProvider* provider =
7825 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7826 AddMockExternalProvider(provider);
7828 provider->UpdateOrAddExtension(
7829 page_action, "1.0.0.0", data_dir().AppendASCII("page_action.crx"));
7830 provider->UpdateOrAddExtension(
7831 good_crx, "1.0.0.0", data_dir().AppendASCII("good.crx"));
7832 provider->UpdateOrAddExtension(
7833 theme_crx, "2.0", data_dir().AppendASCII("theme.crx"));
7835 int count = 3;
7836 content::WindowedNotificationObserver observer(
7837 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7838 base::Bind(&WaitForCountNotificationsCallback, &count));
7839 service()->CheckForExternalUpdates();
7840 observer.Wait();
7841 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7842 EXPECT_FALSE(service()->IsExtensionEnabled(page_action));
7843 EXPECT_FALSE(service()->IsExtensionEnabled(good_crx));
7844 EXPECT_FALSE(service()->IsExtensionEnabled(theme_crx));
7846 service()->EnableExtension(page_action);
7847 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7848 EXPECT_FALSE(service()
7849 ->external_install_manager()
7850 ->HasExternalInstallBubbleForTesting());
7852 service()->EnableExtension(theme_crx);
7853 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7854 EXPECT_FALSE(service()
7855 ->external_install_manager()
7856 ->HasExternalInstallBubbleForTesting());
7858 service()->EnableExtension(good_crx);
7859 EXPECT_FALSE(
7860 service()->external_install_manager()->HasExternalInstallError());
7861 EXPECT_FALSE(service()
7862 ->external_install_manager()
7863 ->HasExternalInstallBubbleForTesting());
7866 // Test that there is a bubble for external extensions that update
7867 // from the webstore if the profile is not new.
7868 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
7869 FeatureSwitch::ScopedOverride prompt(
7870 FeatureSwitch::prompt_for_external_extensions(), true);
7872 // This sets up the ExtensionPrefs used by our ExtensionService to be
7873 // post-first run.
7874 ExtensionServiceInitParams params = CreateDefaultInitParams();
7875 params.is_first_run = false;
7876 InitializeExtensionService(params);
7878 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7879 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7880 data_dir().AppendASCII("update_from_webstore.pem"),
7881 crx_path);
7883 MockExtensionProvider* provider =
7884 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7885 AddMockExternalProvider(provider);
7886 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7888 content::WindowedNotificationObserver observer(
7889 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7890 content::NotificationService::AllSources());
7891 service()->CheckForExternalUpdates();
7892 observer.Wait();
7893 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7894 EXPECT_TRUE(service()
7895 ->external_install_manager()
7896 ->HasExternalInstallBubbleForTesting());
7897 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7900 // Test that there is no bubble for external extensions if the profile is new.
7901 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
7902 FeatureSwitch::ScopedOverride prompt(
7903 FeatureSwitch::prompt_for_external_extensions(), true);
7905 InitializeEmptyExtensionService();
7907 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7908 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7909 data_dir().AppendASCII("update_from_webstore.pem"),
7910 crx_path);
7912 MockExtensionProvider* provider =
7913 new MockExtensionProvider(service(), Manifest::EXTERNAL_PREF);
7914 AddMockExternalProvider(provider);
7915 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7917 content::WindowedNotificationObserver observer(
7918 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7919 content::NotificationService::AllSources());
7920 service()->CheckForExternalUpdates();
7921 observer.Wait();
7922 EXPECT_TRUE(service()->external_install_manager()->HasExternalInstallError());
7923 EXPECT_FALSE(service()
7924 ->external_install_manager()
7925 ->HasExternalInstallBubbleForTesting());
7926 EXPECT_FALSE(service()->IsExtensionEnabled(updates_from_webstore));
7929 // Test that clicking to remove the extension on an external install warning
7930 // uninstalls the extension.
7931 TEST_F(ExtensionServiceTest, ExternalInstallClickToRemove) {
7932 FeatureSwitch::ScopedOverride prompt(
7933 FeatureSwitch::prompt_for_external_extensions(), true);
7935 ExtensionServiceInitParams params = CreateDefaultInitParams();
7936 params.is_first_run = false;
7937 InitializeExtensionService(params);
7939 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7940 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7941 data_dir().AppendASCII("update_from_webstore.pem"),
7942 crx_path);
7944 MockExtensionProvider* provider =
7945 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
7946 AddMockExternalProvider(provider);
7947 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7949 content::WindowedNotificationObserver observer(
7950 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7951 content::NotificationService::AllSources());
7952 service_->CheckForExternalUpdates();
7953 observer.Wait();
7954 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
7956 // We check both enabled and disabled, since these are "eventually exclusive"
7957 // sets.
7958 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
7959 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
7961 // Click the negative response.
7962 service_->external_install_manager()->error_for_testing()->InstallUIAbort(
7963 true);
7964 // The Extension should be uninstalled.
7965 EXPECT_FALSE(registry()->GetExtensionById(updates_from_webstore,
7966 ExtensionRegistry::EVERYTHING));
7967 // The error should be removed.
7968 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
7971 // Test that clicking to keep the extension on an external install warning
7972 // re-enables the extension.
7973 TEST_F(ExtensionServiceTest, ExternalInstallClickToKeep) {
7974 FeatureSwitch::ScopedOverride prompt(
7975 FeatureSwitch::prompt_for_external_extensions(), true);
7977 ExtensionServiceInitParams params = CreateDefaultInitParams();
7978 params.is_first_run = false;
7979 InitializeExtensionService(params);
7981 base::FilePath crx_path = temp_dir().path().AppendASCII("webstore.crx");
7982 PackCRX(data_dir().AppendASCII("update_from_webstore"),
7983 data_dir().AppendASCII("update_from_webstore.pem"),
7984 crx_path);
7986 MockExtensionProvider* provider =
7987 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
7988 AddMockExternalProvider(provider);
7989 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
7991 content::WindowedNotificationObserver observer(
7992 extensions::NOTIFICATION_CRX_INSTALLER_DONE,
7993 content::NotificationService::AllSources());
7994 service_->CheckForExternalUpdates();
7995 observer.Wait();
7996 EXPECT_TRUE(service_->external_install_manager()->HasExternalInstallError());
7998 // We check both enabled and disabled, since these are "eventually exclusive"
7999 // sets.
8000 EXPECT_TRUE(registry()->disabled_extensions().GetByID(updates_from_webstore));
8001 EXPECT_FALSE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8003 // Accept the extension.
8004 service_->external_install_manager()->error_for_testing()->InstallUIProceed();
8006 // It should be enabled again.
8007 EXPECT_TRUE(registry()->enabled_extensions().GetByID(updates_from_webstore));
8008 EXPECT_FALSE(
8009 registry()->disabled_extensions().GetByID(updates_from_webstore));
8011 // The error should be removed.
8012 EXPECT_FALSE(service_->external_install_manager()->HasExternalInstallError());
8015 TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) {
8016 InitializeEmptyExtensionService();
8018 scoped_refptr<Extension> extension = extensions::ExtensionBuilder()
8019 .SetManifest(extensions::DictionaryBuilder()
8020 .Set("name", "extension")
8021 .Set("version", "1.0")
8022 .Set("manifest_version", 2).Build())
8023 .Build();
8024 ASSERT_TRUE(extension.get());
8025 const std::string& id = extension->id();
8027 std::set<std::string> id_set;
8028 id_set.insert(id);
8029 extensions::ExtensionNotificationObserver notifications(
8030 content::NotificationService::AllSources(), id_set);
8032 // Installation should be allowed but the extension should never have been
8033 // loaded and it should be blacklisted in prefs.
8034 service()->OnExtensionInstalled(
8035 extension.get(),
8036 syncer::StringOrdinal(),
8037 (extensions::kInstallFlagIsBlacklistedForMalware |
8038 extensions::kInstallFlagInstallImmediately));
8039 base::RunLoop().RunUntilIdle();
8041 // Extension was installed but not loaded.
8042 EXPECT_TRUE(notifications.CheckNotifications(
8043 extensions::NOTIFICATION_EXTENSION_WILL_BE_INSTALLED_DEPRECATED));
8044 EXPECT_TRUE(service()->GetInstalledExtension(id));
8046 EXPECT_FALSE(registry()->enabled_extensions().Contains(id));
8047 EXPECT_TRUE(registry()->blacklisted_extensions().Contains(id));
8049 EXPECT_TRUE(ExtensionPrefs::Get(profile())->IsExtensionBlacklisted(id));
8050 EXPECT_TRUE(
8051 ExtensionPrefs::Get(profile())->IsBlacklistedExtensionAcknowledged(id));
8054 // Tests a profile being destroyed correctly disables extensions.
8055 TEST_F(ExtensionServiceTest, DestroyingProfileClearsExtensions) {
8056 InitializeEmptyExtensionService();
8058 InstallCRX(data_dir().AppendASCII("good.crx"), INSTALL_NEW);
8059 EXPECT_NE(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8060 EXPECT_EQ(1u, registry()->enabled_extensions().size());
8061 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8062 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8063 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());
8065 service()->Observe(chrome::NOTIFICATION_PROFILE_DESTRUCTION_STARTED,
8066 content::Source<Profile>(profile()),
8067 content::NotificationService::NoDetails());
8068 EXPECT_EQ(UnloadedExtensionInfo::REASON_PROFILE_SHUTDOWN, unloaded_reason_);
8069 EXPECT_EQ(0u, registry()->enabled_extensions().size());
8070 EXPECT_EQ(0u, registry()->disabled_extensions().size());
8071 EXPECT_EQ(0u, registry()->terminated_extensions().size());
8072 EXPECT_EQ(0u, registry()->blacklisted_extensions().size());