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 "chrome/browser/extensions/extension_service_unittest.h"
11 #include "base/at_exit.h"
12 #include "base/basictypes.h"
13 #include "base/bind.h"
14 #include "base/command_line.h"
15 #include "base/file_util.h"
16 #include "base/files/file_enumerator.h"
17 #include "base/files/scoped_temp_dir.h"
18 #include "base/json/json_file_value_serializer.h"
19 #include "base/json/json_reader.h"
20 #include "base/json/json_string_value_serializer.h"
21 #include "base/memory/scoped_ptr.h"
22 #include "base/memory/weak_ptr.h"
23 #include "base/message_loop/message_loop.h"
24 #include "base/path_service.h"
25 #include "base/prefs/scoped_user_pref_update.h"
26 #include "base/stl_util.h"
27 #include "base/strings/string16.h"
28 #include "base/strings/string_number_conversions.h"
29 #include "base/strings/string_util.h"
30 #include "base/strings/utf_string_conversions.h"
31 #include "base/version.h"
32 #include "chrome/browser/browser_process.h"
33 #include "chrome/browser/chrome_notification_types.h"
34 #include "chrome/browser/extensions/app_sync_data.h"
35 #include "chrome/browser/extensions/blacklist.h"
36 #include "chrome/browser/extensions/chrome_app_sorting.h"
37 #include "chrome/browser/extensions/component_loader.h"
38 #include "chrome/browser/extensions/crx_installer.h"
39 #include "chrome/browser/extensions/default_apps.h"
40 #include "chrome/browser/extensions/extension_creator.h"
41 #include "chrome/browser/extensions/extension_error_reporter.h"
42 #include "chrome/browser/extensions/extension_error_ui.h"
43 #include "chrome/browser/extensions/extension_notification_observer.h"
44 #include "chrome/browser/extensions/extension_service.h"
45 #include "chrome/browser/extensions/extension_special_storage_policy.h"
46 #include "chrome/browser/extensions/extension_sync_data.h"
47 #include "chrome/browser/extensions/extension_util.h"
48 #include "chrome/browser/extensions/external_install_ui.h"
49 #include "chrome/browser/extensions/external_policy_loader.h"
50 #include "chrome/browser/extensions/external_pref_loader.h"
51 #include "chrome/browser/extensions/external_provider_impl.h"
52 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
53 #include "chrome/browser/extensions/install_observer.h"
54 #include "chrome/browser/extensions/install_tracker.h"
55 #include "chrome/browser/extensions/install_tracker_factory.h"
56 #include "chrome/browser/extensions/installed_loader.h"
57 #include "chrome/browser/extensions/pack_extension_job.h"
58 #include "chrome/browser/extensions/test_blacklist.h"
59 #include "chrome/browser/extensions/test_extension_system.h"
60 #include "chrome/browser/extensions/unpacked_installer.h"
61 #include "chrome/browser/extensions/updater/extension_updater.h"
62 #include "chrome/browser/prefs/browser_prefs.h"
63 #include "chrome/browser/prefs/pref_service_mock_factory.h"
64 #include "chrome/browser/prefs/pref_service_syncable.h"
65 #include "chrome/browser/sync/profile_sync_service.h"
66 #include "chrome/browser/sync/profile_sync_service_factory.h"
67 #include "chrome/common/chrome_constants.h"
68 #include "chrome/common/chrome_paths.h"
69 #include "chrome/common/chrome_switches.h"
70 #include "chrome/common/extensions/api/plugins/plugins_handler.h"
71 #include "chrome/common/extensions/extension_l10n_util.h"
72 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
73 #include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
74 #include "chrome/common/extensions/manifest_url_handler.h"
75 #include "chrome/common/pref_names.h"
76 #include "chrome/common/url_constants.h"
77 #include "chrome/test/base/scoped_browser_locale.h"
78 #include "chrome/test/base/testing_profile.h"
79 #include "components/user_prefs/pref_registry_syncable.h"
80 #include "content/public/browser/dom_storage_context.h"
81 #include "content/public/browser/gpu_data_manager.h"
82 #include "content/public/browser/indexed_db_context.h"
83 #include "content/public/browser/notification_registrar.h"
84 #include "content/public/browser/notification_service.h"
85 #include "content/public/browser/plugin_service.h"
86 #include "content/public/browser/render_process_host.h"
87 #include "content/public/browser/storage_partition.h"
88 #include "content/public/common/content_constants.h"
89 #include "content/public/test/test_utils.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/management_policy.h"
94 #include "extensions/browser/pending_extension_info.h"
95 #include "extensions/browser/pending_extension_manager.h"
96 #include "extensions/browser/pref_names.h"
97 #include "extensions/browser/test_management_policy.h"
98 #include "extensions/common/constants.h"
99 #include "extensions/common/extension.h"
100 #include "extensions/common/extension_builder.h"
101 #include "extensions/common/extension_resource.h"
102 #include "extensions/common/manifest_constants.h"
103 #include "extensions/common/manifest_handlers/background_info.h"
104 #include "extensions/common/permissions/permission_set.h"
105 #include "extensions/common/url_pattern.h"
106 #include "extensions/common/value_builder.h"
107 #include "gpu/config/gpu_info.h"
108 #include "grit/browser_resources.h"
109 #include "net/cookies/canonical_cookie.h"
110 #include "net/cookies/cookie_monster.h"
111 #include "net/cookies/cookie_options.h"
112 #include "net/url_request/url_request_context.h"
113 #include "net/url_request/url_request_context_getter.h"
114 #include "sync/api/string_ordinal.h"
115 #include "sync/api/sync_data.h"
116 #include "sync/api/sync_error_factory.h"
117 #include "sync/api/sync_error_factory_mock.h"
118 #include "sync/api/syncable_service.h"
119 #include "sync/protocol/app_specifics.pb.h"
120 #include "sync/protocol/extension_specifics.pb.h"
121 #include "sync/protocol/sync.pb.h"
122 #include "testing/gtest/include/gtest/gtest.h"
123 #include "testing/platform_test.h"
124 #include "url/gurl.h"
125 #include "webkit/browser/database/database_tracker.h"
126 #include "webkit/browser/quota/quota_manager.h"
127 #include "webkit/common/database/database_identifier.h"
129 #if defined(OS_CHROMEOS)
130 #include "chrome/browser/chromeos/extensions/install_limiter.h"
131 #include "chrome/browser/chromeos/login/user_manager.h"
132 #include "chrome/browser/chromeos/settings/cros_settings.h"
133 #include "chrome/browser/chromeos/settings/device_settings_service.h"
136 // The blacklist tests rely on safe browsing.
137 #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
138 #define ENABLE_BLACKLIST_TESTS
141 using base::DictionaryValue
;
142 using base::ListValue
;
144 using content::BrowserContext
;
145 using content::BrowserThread
;
146 using content::DOMStorageContext
;
147 using content::IndexedDBContext
;
148 using content::PluginService
;
149 using extensions::APIPermission
;
150 using extensions::APIPermissionSet
;
151 using extensions::AppSorting
;
152 using extensions::Blacklist
;
153 using extensions::CrxInstaller
;
154 using extensions::Extension
;
155 using extensions::ExtensionCreator
;
156 using extensions::ExtensionPrefs
;
157 using extensions::ExtensionRegistry
;
158 using extensions::ExtensionResource
;
159 using extensions::ExtensionSystem
;
160 using extensions::FakeSafeBrowsingDatabaseManager
;
161 using extensions::FeatureSwitch
;
162 using extensions::Manifest
;
163 using extensions::PermissionSet
;
164 using extensions::TestExtensionSystem
;
165 using extensions::URLPatternSet
;
167 namespace keys
= extensions::manifest_keys
;
171 // Extension ids used during testing.
172 const char good0
[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
173 const char good1
[] = "hpiknbiabeeppbpihjehijgoemciehgk";
174 const char good2
[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
175 const char all_zero
[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
176 const char good2048
[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
177 const char good_crx
[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
178 const char hosted_app
[] = "kbmnembihfiondgfjekmnmcbddelicoi";
179 const char page_action
[] = "obcimlgaoabeegjmmpldobjndiealpln";
180 const char theme_crx
[] = "iamefpfkojoapidjnbafmgkgncegbkad";
181 const char theme2_crx
[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
182 const char permissions_crx
[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
183 const char unpacked
[] = "cbcdidchbppangcjoddlpdjlenngjldk";
184 const char updates_from_webstore
[] = "akjooamlhcgeopfifcmlggaebeocgokj";
186 struct ExtensionsOrder
{
187 bool operator()(const scoped_refptr
<const Extension
>& a
,
188 const scoped_refptr
<const Extension
>& b
) {
189 return a
->name() < b
->name();
193 static std::vector
<base::string16
> GetErrors() {
194 const std::vector
<base::string16
>* errors
=
195 ExtensionErrorReporter::GetInstance()->GetErrors();
196 std::vector
<base::string16
> ret_val
;
198 for (std::vector
<base::string16
>::const_iterator iter
= errors
->begin();
199 iter
!= errors
->end(); ++iter
) {
200 std::string utf8_error
= base::UTF16ToUTF8(*iter
);
201 if (utf8_error
.find(".svn") == std::string::npos
) {
202 ret_val
.push_back(*iter
);
206 // The tests rely on the errors being in a certain order, which can vary
207 // depending on how filesystem iteration works.
208 std::stable_sort(ret_val
.begin(), ret_val
.end());
213 static void AddPattern(URLPatternSet
* extent
, const std::string
& pattern
) {
214 int schemes
= URLPattern::SCHEME_ALL
;
215 extent
->AddPattern(URLPattern(schemes
, pattern
));
218 base::FilePath
GetTemporaryFile() {
219 base::FilePath temp_file
;
220 CHECK(base::CreateTemporaryFile(&temp_file
));
224 bool WaitForCountNotificationsCallback(int *count
) {
225 return --(*count
) == 0;
230 class MockExtensionProvider
: public extensions::ExternalProviderInterface
{
232 MockExtensionProvider(
233 VisitorInterface
* visitor
,
234 Manifest::Location location
)
235 : location_(location
), visitor_(visitor
), visit_count_(0) {
238 virtual ~MockExtensionProvider() {}
240 void UpdateOrAddExtension(const std::string
& id
,
241 const std::string
& version
,
242 const base::FilePath
& path
) {
243 extension_map_
[id
] = std::make_pair(version
, path
);
246 void RemoveExtension(const std::string
& id
) {
247 extension_map_
.erase(id
);
250 // ExternalProvider implementation:
251 virtual void VisitRegisteredExtension() OVERRIDE
{
253 for (DataMap::const_iterator i
= extension_map_
.begin();
254 i
!= extension_map_
.end(); ++i
) {
255 Version
version(i
->second
.first
);
257 visitor_
->OnExternalExtensionFileFound(
258 i
->first
, &version
, i
->second
.second
, location_
,
259 Extension::NO_FLAGS
, false);
261 visitor_
->OnExternalProviderReady(this);
264 virtual bool HasExtension(const std::string
& id
) const OVERRIDE
{
265 return extension_map_
.find(id
) != extension_map_
.end();
268 virtual bool GetExtensionDetails(
269 const std::string
& id
,
270 Manifest::Location
* location
,
271 scoped_ptr
<Version
>* version
) const OVERRIDE
{
272 DataMap::const_iterator it
= extension_map_
.find(id
);
273 if (it
== extension_map_
.end())
277 version
->reset(new Version(it
->second
.first
));
280 *location
= location_
;
285 virtual bool IsReady() const OVERRIDE
{
289 virtual void ServiceShutdown() OVERRIDE
{
292 int visit_count() const { return visit_count_
; }
293 void set_visit_count(int visit_count
) {
294 visit_count_
= visit_count
;
298 typedef std::map
< std::string
, std::pair
<std::string
, base::FilePath
> >
300 DataMap extension_map_
;
301 Manifest::Location location_
;
302 VisitorInterface
* visitor_
;
304 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
305 // Mutable because it must be incremented on each call to
306 // VisitRegisteredExtension(), which must be a const method to inherit
307 // from the class being mocked.
308 mutable int visit_count_
;
310 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider
);
313 class MockProviderVisitor
314 : public extensions::ExternalProviderInterface::VisitorInterface
{
316 // The provider will return |fake_base_path| from
317 // GetBaseCrxFilePath(). User can test the behavior with
318 // and without an empty path using this parameter.
319 explicit MockProviderVisitor(base::FilePath fake_base_path
)
321 fake_base_path_(fake_base_path
),
322 expected_creation_flags_(Extension::NO_FLAGS
) {
323 profile_
.reset(new TestingProfile
);
326 MockProviderVisitor(base::FilePath fake_base_path
,
327 int expected_creation_flags
)
329 fake_base_path_(fake_base_path
),
330 expected_creation_flags_(expected_creation_flags
) {
333 int Visit(const std::string
& json_data
) {
334 // Give the test json file to the provider for parsing.
335 provider_
.reset(new extensions::ExternalProviderImpl(
337 new extensions::ExternalTestingLoader(json_data
, fake_base_path_
),
339 Manifest::EXTERNAL_PREF
,
340 Manifest::EXTERNAL_PREF_DOWNLOAD
,
341 Extension::NO_FLAGS
));
343 // We also parse the file into a dictionary to compare what we get back
344 // from the provider.
345 JSONStringValueSerializer
serializer(json_data
);
346 base::Value
* json_value
= serializer
.Deserialize(NULL
, NULL
);
348 if (!json_value
|| !json_value
->IsType(base::Value::TYPE_DICTIONARY
)) {
349 NOTREACHED() << "Unable to deserialize json data";
352 base::DictionaryValue
* external_extensions
=
353 static_cast<base::DictionaryValue
*>(json_value
);
354 prefs_
.reset(external_extensions
);
357 // Reset our counter.
359 // Ask the provider to look up all extensions and return them.
360 provider_
->VisitRegisteredExtension();
365 virtual bool OnExternalExtensionFileFound(const std::string
& id
,
366 const Version
* version
,
367 const base::FilePath
& path
,
368 Manifest::Location unused
,
370 bool mark_acknowledged
) OVERRIDE
{
371 EXPECT_EQ(expected_creation_flags_
, creation_flags
);
374 base::DictionaryValue
* pref
;
375 // This tests is to make sure that the provider only notifies us of the
376 // values we gave it. So if the id we doesn't exist in our internal
377 // dictionary then something is wrong.
378 EXPECT_TRUE(prefs_
->GetDictionary(id
, &pref
))
379 << "Got back ID (" << id
.c_str() << ") we weren't expecting";
381 EXPECT_TRUE(path
.IsAbsolute());
382 if (!fake_base_path_
.empty())
383 EXPECT_TRUE(fake_base_path_
.IsParent(path
));
386 EXPECT_TRUE(provider_
->HasExtension(id
));
388 // Ask provider if the extension we got back is registered.
389 Manifest::Location location
= Manifest::INVALID_LOCATION
;
390 scoped_ptr
<Version
> v1
;
391 base::FilePath crx_path
;
393 EXPECT_TRUE(provider_
->GetExtensionDetails(id
, NULL
, &v1
));
394 EXPECT_STREQ(version
->GetString().c_str(), v1
->GetString().c_str());
396 scoped_ptr
<Version
> v2
;
397 EXPECT_TRUE(provider_
->GetExtensionDetails(id
, &location
, &v2
));
398 EXPECT_STREQ(version
->GetString().c_str(), v1
->GetString().c_str());
399 EXPECT_STREQ(version
->GetString().c_str(), v2
->GetString().c_str());
400 EXPECT_EQ(Manifest::EXTERNAL_PREF
, location
);
402 // Remove it so we won't count it ever again.
403 prefs_
->Remove(id
, NULL
);
408 virtual bool OnExternalExtensionUpdateUrlFound(
409 const std::string
& id
, const GURL
& update_url
,
410 Manifest::Location location
,
412 bool mark_acknowledged
) OVERRIDE
{
414 base::DictionaryValue
* pref
;
415 // This tests is to make sure that the provider only notifies us of the
416 // values we gave it. So if the id we doesn't exist in our internal
417 // dictionary then something is wrong.
418 EXPECT_TRUE(prefs_
->GetDictionary(id
, &pref
))
419 << L
"Got back ID (" << id
.c_str() << ") we weren't expecting";
420 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD
, location
);
423 EXPECT_TRUE(provider_
->HasExtension(id
));
425 // External extensions with update URLs do not have versions.
426 scoped_ptr
<Version
> v1
;
427 Manifest::Location location1
= Manifest::INVALID_LOCATION
;
428 EXPECT_TRUE(provider_
->GetExtensionDetails(id
, &location1
, &v1
));
429 EXPECT_FALSE(v1
.get());
430 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD
, location1
);
432 // Remove it so we won't count it again.
433 prefs_
->Remove(id
, NULL
);
438 virtual void OnExternalProviderReady(
439 const extensions::ExternalProviderInterface
* provider
) OVERRIDE
{
440 EXPECT_EQ(provider
, provider_
.get());
441 EXPECT_TRUE(provider
->IsReady());
446 base::FilePath fake_base_path_
;
447 int expected_creation_flags_
;
448 scoped_ptr
<extensions::ExternalProviderImpl
> provider_
;
449 scoped_ptr
<base::DictionaryValue
> prefs_
;
450 scoped_ptr
<TestingProfile
> profile_
;
452 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor
);
455 ExtensionServiceTestBase::ExtensionServiceInitParams::
456 ExtensionServiceInitParams()
457 : autoupdate_enabled(false), is_first_run(true), profile_is_managed(false) {
460 // Our message loop may be used in tests which require it to be an IO loop.
461 ExtensionServiceTestBase::ExtensionServiceTestBase()
462 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP
),
464 management_policy_(NULL
),
465 expected_extensions_count_(0),
467 base::FilePath test_data_dir
;
468 if (!PathService::Get(chrome::DIR_TEST_DATA
, &test_data_dir
)) {
472 data_dir_
= test_data_dir
.AppendASCII("extensions");
475 ExtensionServiceTestBase::~ExtensionServiceTestBase() {
479 void ExtensionServiceTestBase::InitializeExtensionService(
480 const ExtensionServiceTestBase::ExtensionServiceInitParams
& params
) {
481 profile_
= CreateTestingProfile(params
);
482 service_
= InitializeExtensionServiceForProfile(params
, profile_
.get());
484 ExtensionSystem::Get(profile_
.get())->management_policy();
485 extensions_install_dir_
= params
.extensions_install_dir
;
486 expected_extensions_count_
= 0;
487 registry_
= extensions::ExtensionRegistry::Get(profile_
.get());
491 scoped_ptr
<TestingProfile
> ExtensionServiceTestBase::CreateTestingProfile(
492 const ExtensionServiceInitParams
& params
) {
493 TestingProfile::Builder profile_builder
;
494 // Create a PrefService that only contains user defined preference values.
495 PrefServiceMockFactory factory
;
496 // If pref_file is empty, TestingProfile automatically creates
497 // TestingPrefServiceSyncable instance.
498 if (!params
.pref_file
.empty()) {
499 factory
.SetUserPrefsFile(params
.pref_file
,
500 base::MessageLoopProxy::current().get());
501 scoped_refptr
<user_prefs::PrefRegistrySyncable
> registry(
502 new user_prefs::PrefRegistrySyncable
);
503 scoped_ptr
<PrefServiceSyncable
> prefs(
504 factory
.CreateSyncable(registry
.get()));
505 chrome::RegisterUserProfilePrefs(registry
.get());
506 profile_builder
.SetPrefService(prefs
.Pass());
509 if (params
.profile_is_managed
)
510 profile_builder
.SetManagedUserId("asdf");
512 profile_builder
.SetPath(params
.profile_path
);
513 return profile_builder
.Build();
518 ExtensionServiceTestBase::InitializeExtensionServiceForProfile(
519 const ExtensionServiceInitParams
& params
,
521 TestExtensionSystem
* system
= static_cast<TestExtensionSystem
*>(
522 ExtensionSystem::Get(profile
));
523 if (!params
.is_first_run
) {
524 ExtensionPrefs
* prefs
= system
->CreateExtensionPrefs(
525 CommandLine::ForCurrentProcess(),
526 params
.extensions_install_dir
);
527 prefs
->SetAlertSystemFirstRun();
530 ExtensionService
* service
= system
->CreateExtensionService(
531 CommandLine::ForCurrentProcess(),
532 params
.extensions_install_dir
,
533 params
.autoupdate_enabled
);
535 service
->SetFileTaskRunnerForTesting(
536 base::MessageLoopProxy::current().get());
537 service
->set_extensions_enabled(true);
538 service
->set_show_extensions_prompts(false);
539 service
->set_install_updates_when_idle_for_test(false);
541 // When we start up, we want to make sure there is no external provider,
542 // since the ExtensionService on Windows will use the Registry as a default
543 // provider and if there is something already registered there then it will
544 // interfere with the tests. Those tests that need an external provider
545 // will register one specifically.
546 service
->ClearProvidersForTesting();
548 #if defined(OS_CHROMEOS)
549 extensions::InstallLimiter::Get(profile
)->DisableForTest();
554 void ExtensionServiceTestBase::InitializeInstalledExtensionService(
555 const base::FilePath
& prefs_file
,
556 const base::FilePath
& source_install_dir
) {
557 EXPECT_TRUE(temp_dir_
.CreateUniqueTempDir());
558 base::FilePath path
= temp_dir_
.path();
559 path
= path
.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
560 EXPECT_TRUE(base::DeleteFile(path
, true));
561 base::File::Error error
= base::File::FILE_OK
;
562 EXPECT_TRUE(base::CreateDirectoryAndGetError(path
, &error
)) << error
;
563 base::FilePath temp_prefs
= path
.Append(chrome::kPreferencesFilename
);
564 EXPECT_TRUE(base::CopyFile(prefs_file
, temp_prefs
));
566 base::FilePath extensions_install_dir
=
567 path
.Append(FILE_PATH_LITERAL("Extensions"));
568 EXPECT_TRUE(base::DeleteFile(extensions_install_dir
, true));
570 base::CopyDirectory(source_install_dir
, extensions_install_dir
, true));
572 ExtensionServiceInitParams params
;
573 params
.profile_path
= path
;
574 params
.pref_file
= temp_prefs
;
575 params
.extensions_install_dir
= extensions_install_dir
;
576 InitializeExtensionService(params
);
579 void ExtensionServiceTestBase::InitializeGoodInstalledExtensionService() {
580 base::FilePath source_install_dir
= data_dir_
582 .AppendASCII("Extensions");
583 base::FilePath pref_path
=
584 source_install_dir
.DirName().Append(chrome::kPreferencesFilename
);
585 InitializeInstalledExtensionService(pref_path
, source_install_dir
);
588 void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
589 InitializeExtensionService(CreateDefaultInitParams());
592 void ExtensionServiceTestBase::InitializeProcessManager() {
593 static_cast<extensions::TestExtensionSystem
*>(
594 ExtensionSystem::Get(profile_
.get()))->
595 CreateProcessManager();
598 void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
599 ExtensionServiceInitParams params
= CreateDefaultInitParams();
600 params
.autoupdate_enabled
= true;
601 InitializeExtensionService(params
);
602 service_
->updater()->Start();
605 void ExtensionServiceTestBase::InitializeExtensionSyncService() {
606 extension_sync_service_
.reset(new ExtensionSyncService(
607 profile_
.get(), service_
->extension_prefs(), service_
));
611 void ExtensionServiceTestBase::SetUpTestCase() {
612 ExtensionErrorReporter::Init(false); // no noisy errors
615 void ExtensionServiceTestBase::SetUp() {
616 ExtensionErrorReporter::GetInstance()->ClearErrors();
619 void ExtensionServiceTestBase::TearDown() {
622 ExtensionServiceTestBase::ExtensionServiceInitParams
623 ExtensionServiceTestBase::CreateDefaultInitParams() {
624 return CreateDefaultInitParamsInTempDir(&temp_dir_
);
628 ExtensionServiceTestBase::ExtensionServiceInitParams
629 ExtensionServiceTestBase::CreateDefaultInitParamsInTempDir(
630 base::ScopedTempDir
* temp_dir
) {
631 ExtensionServiceInitParams params
;
632 EXPECT_TRUE(temp_dir
->CreateUniqueTempDir());
633 base::FilePath path
= temp_dir
->path();
634 path
= path
.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
635 EXPECT_TRUE(base::DeleteFile(path
, true));
636 base::File::Error error
= base::File::FILE_OK
;
637 EXPECT_TRUE(base::CreateDirectoryAndGetError(path
, &error
)) << error
;
638 base::FilePath prefs_filename
=
639 path
.Append(FILE_PATH_LITERAL("TestPreferences"));
640 base::FilePath extensions_install_dir
=
641 path
.Append(FILE_PATH_LITERAL("Extensions"));
642 EXPECT_TRUE(base::DeleteFile(extensions_install_dir
, true));
643 EXPECT_TRUE(base::CreateDirectoryAndGetError(extensions_install_dir
,
646 params
.profile_path
= path
;
647 params
.pref_file
= prefs_filename
;
648 params
.extensions_install_dir
= extensions_install_dir
;
652 class ExtensionServiceTest
653 : public ExtensionServiceTestBase
, public content::NotificationObserver
{
655 ExtensionServiceTest()
658 override_external_install_prompt_(
659 FeatureSwitch::prompt_for_external_extensions(), false) {
660 registrar_
.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED
,
661 content::NotificationService::AllSources());
662 registrar_
.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED
,
663 content::NotificationService::AllSources());
664 registrar_
.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED
,
665 content::NotificationService::AllSources());
668 virtual void Observe(int type
,
669 const content::NotificationSource
& source
,
670 const content::NotificationDetails
& details
) OVERRIDE
{
672 case chrome::NOTIFICATION_EXTENSION_LOADED
: {
673 const Extension
* extension
=
674 content::Details
<const Extension
>(details
).ptr();
675 loaded_
.push_back(make_scoped_refptr(extension
));
676 // The tests rely on the errors being in a certain order, which can vary
677 // depending on how filesystem iteration works.
678 std::stable_sort(loaded_
.begin(), loaded_
.end(), ExtensionsOrder());
682 case chrome::NOTIFICATION_EXTENSION_UNLOADED
: {
684 content::Details
<extensions::UnloadedExtensionInfo
>(
686 unloaded_id_
= e
->id();
687 extensions::ExtensionList::iterator i
=
688 std::find(loaded_
.begin(), loaded_
.end(), e
);
689 // TODO(erikkay) fix so this can be an assert. Right now the tests
690 // are manually calling clear() on loaded_, so this isn't doable.
691 if (i
== loaded_
.end())
696 case chrome::NOTIFICATION_EXTENSION_INSTALLED
: {
697 const extensions::InstalledExtensionInfo
* installed_info
=
698 content::Details
<const extensions::InstalledExtensionInfo
>(details
)
700 installed_
= installed_info
->extension
;
701 was_update_
= installed_info
->is_update
;
702 old_name_
= installed_info
->old_name
;
711 void AddMockExternalProvider(
712 extensions::ExternalProviderInterface
* provider
) {
713 service_
->AddProviderForTesting(provider
);
716 void MockSyncStartFlare(bool* was_called
,
717 syncer::ModelType
* model_type_passed_in
,
718 syncer::ModelType model_type
) {
720 *model_type_passed_in
= model_type
;
724 // Paths to some of the fake extensions.
725 base::FilePath
good0_path() {
726 return data_dir_
.AppendASCII("good").AppendASCII("Extensions")
727 .AppendASCII(good0
).AppendASCII("1.0.0.0");
730 base::FilePath
good1_path() {
731 return data_dir_
.AppendASCII("good").AppendASCII("Extensions")
732 .AppendASCII(good1
).AppendASCII("2");
735 base::FilePath
good2_path() {
736 return data_dir_
.AppendASCII("good").AppendASCII("Extensions")
737 .AppendASCII(good2
).AppendASCII("1.0");
740 void TestExternalProvider(MockExtensionProvider
* provider
,
741 Manifest::Location location
);
743 void PackCRX(const base::FilePath
& dir_path
,
744 const base::FilePath
& pem_path
,
745 const base::FilePath
& crx_path
) {
746 // Use the existing pem key, if provided.
747 base::FilePath pem_output_path
;
748 if (pem_path
.value().empty()) {
749 pem_output_path
= crx_path
.DirName().AppendASCII("temp.pem");
751 ASSERT_TRUE(base::PathExists(pem_path
));
754 ASSERT_TRUE(base::DeleteFile(crx_path
, false));
756 scoped_ptr
<ExtensionCreator
> creator(new ExtensionCreator());
757 ASSERT_TRUE(creator
->Run(dir_path
,
761 ExtensionCreator::kOverwriteCRX
));
763 ASSERT_TRUE(base::PathExists(crx_path
));
770 INSTALL_WITHOUT_LOAD
,
773 const Extension
* PackAndInstallCRX(const base::FilePath
& dir_path
,
774 const base::FilePath
& pem_path
,
775 InstallState install_state
,
776 int creation_flags
) {
777 base::FilePath crx_path
;
778 base::ScopedTempDir temp_dir
;
779 EXPECT_TRUE(temp_dir
.CreateUniqueTempDir());
780 crx_path
= temp_dir
.path().AppendASCII("temp.crx");
782 PackCRX(dir_path
, pem_path
, crx_path
);
783 return InstallCRX(crx_path
, install_state
, creation_flags
);
786 const Extension
* PackAndInstallCRX(const base::FilePath
& dir_path
,
787 const base::FilePath
& pem_path
,
788 InstallState install_state
) {
789 return PackAndInstallCRX(dir_path
, pem_path
, install_state
,
790 Extension::NO_FLAGS
);
793 const Extension
* PackAndInstallCRX(const base::FilePath
& dir_path
,
794 InstallState install_state
) {
795 return PackAndInstallCRX(dir_path
, base::FilePath(), install_state
,
796 Extension::NO_FLAGS
);
799 // Attempts to install an extension. Use INSTALL_FAILED if the installation
800 // is expected to fail.
801 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
802 // non-empty, expects that the existing extension's title was
803 // |expected_old_name|.
804 const Extension
* InstallCRX(const base::FilePath
& path
,
805 InstallState install_state
,
807 const std::string
& expected_old_name
) {
808 InstallCRXInternal(path
, creation_flags
);
809 return VerifyCrxInstall(path
, install_state
, expected_old_name
);
812 // Attempts to install an extension. Use INSTALL_FAILED if the installation
813 // is expected to fail.
814 const Extension
* InstallCRX(const base::FilePath
& path
,
815 InstallState install_state
,
816 int creation_flags
) {
817 return InstallCRX(path
, install_state
, creation_flags
, std::string());
820 // Attempts to install an extension. Use INSTALL_FAILED if the installation
821 // is expected to fail.
822 const Extension
* InstallCRX(const base::FilePath
& path
,
823 InstallState install_state
) {
824 return InstallCRX(path
, install_state
, Extension::NO_FLAGS
);
827 const Extension
* InstallCRXFromWebStore(const base::FilePath
& path
,
828 InstallState install_state
) {
829 InstallCRXInternal(path
, Extension::FROM_WEBSTORE
);
830 return VerifyCrxInstall(path
, install_state
);
833 const Extension
* InstallCRXWithLocation(const base::FilePath
& crx_path
,
834 Manifest::Location install_location
,
835 InstallState install_state
) {
836 EXPECT_TRUE(base::PathExists(crx_path
))
837 << "Path does not exist: "<< crx_path
.value().c_str();
838 // no client (silent install)
839 scoped_refptr
<CrxInstaller
> installer(CrxInstaller::CreateSilent(service_
));
840 installer
->set_install_source(install_location
);
842 content::WindowedNotificationObserver
observer(
843 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
844 content::NotificationService::AllSources());
845 installer
->InstallCrx(crx_path
);
848 return VerifyCrxInstall(crx_path
, install_state
);
851 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
852 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
853 // Returns an Extension pointer if the install succeeded, NULL otherwise.
854 const Extension
* VerifyCrxInstall(const base::FilePath
& path
,
855 InstallState install_state
) {
856 return VerifyCrxInstall(path
, install_state
, std::string());
859 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
860 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
861 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
862 // non-empty, expects that the existing extension's title was
863 // |expected_old_name|.
864 // Returns an Extension pointer if the install succeeded, NULL otherwise.
865 const Extension
* VerifyCrxInstall(const base::FilePath
& path
,
866 InstallState install_state
,
867 const std::string
& expected_old_name
) {
868 std::vector
<base::string16
> errors
= GetErrors();
869 const Extension
* extension
= NULL
;
870 if (install_state
!= INSTALL_FAILED
) {
871 if (install_state
== INSTALL_NEW
)
872 ++expected_extensions_count_
;
874 EXPECT_TRUE(installed_
) << path
.value();
875 // If and only if INSTALL_UPDATED, it should have the is_update flag.
876 EXPECT_EQ(install_state
== INSTALL_UPDATED
, was_update_
)
878 // If INSTALL_UPDATED, old_name_ should match the given string.
879 if (install_state
== INSTALL_UPDATED
&& !expected_old_name
.empty())
880 EXPECT_EQ(expected_old_name
, old_name_
);
881 EXPECT_EQ(0u, errors
.size()) << path
.value();
883 if (install_state
== INSTALL_WITHOUT_LOAD
) {
884 EXPECT_EQ(0u, loaded_
.size()) << path
.value();
886 EXPECT_EQ(1u, loaded_
.size()) << path
.value();
887 size_t actual_extension_count
= registry_
->enabled_extensions().size() +
888 registry_
->disabled_extensions().size();
889 EXPECT_EQ(expected_extensions_count_
, actual_extension_count
) <<
891 extension
= loaded_
[0].get();
892 EXPECT_TRUE(service_
->GetExtensionById(extension
->id(), false))
896 for (std::vector
<base::string16
>::iterator err
= errors
.begin();
897 err
!= errors
.end(); ++err
) {
901 EXPECT_FALSE(installed_
) << path
.value();
902 EXPECT_EQ(0u, loaded_
.size()) << path
.value();
903 EXPECT_EQ(1u, errors
.size()) << path
.value();
910 ExtensionErrorReporter::GetInstance()->ClearErrors();
922 void BlackListWebGL() {
923 static const std::string json_blacklist
=
925 " \"name\": \"gpu blacklist\",\n"
926 " \"version\": \"1.0\",\n"
930 " \"features\": [\"webgl\"]\n"
934 gpu::GPUInfo gpu_info
;
935 content::GpuDataManager::GetInstance()->InitializeForTesting(
936 json_blacklist
, gpu_info
);
939 // Helper method to set up a WindowedNotificationObserver to wait for a
940 // specific CrxInstaller to finish if we don't know the value of the
942 static bool IsCrxInstallerDone(extensions::CrxInstaller
** installer
,
943 const content::NotificationSource
& source
,
944 const content::NotificationDetails
& details
) {
945 return content::Source
<extensions::CrxInstaller
>(source
).ptr() ==
949 void UpdateExtension(const std::string
& id
,
950 const base::FilePath
& in_path
,
951 UpdateState expected_state
) {
952 ASSERT_TRUE(base::PathExists(in_path
));
954 // We need to copy this to a temporary location because Update() will delete
956 base::FilePath path
= temp_dir_
.path();
957 path
= path
.Append(in_path
.BaseName());
958 ASSERT_TRUE(base::CopyFile(in_path
, path
));
960 int previous_enabled_extension_count
=
961 registry_
->enabled_extensions().size();
962 int previous_installed_extension_count
=
963 previous_enabled_extension_count
+
964 registry_
->disabled_extensions().size();
966 extensions::CrxInstaller
* installer
= NULL
;
967 content::WindowedNotificationObserver
observer(
968 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
969 base::Bind(&IsCrxInstallerDone
, &installer
));
970 service_
->UpdateExtension(id
, path
, true, GURL(), &installer
);
975 base::RunLoop().RunUntilIdle();
977 std::vector
<base::string16
> errors
= GetErrors();
978 int error_count
= errors
.size();
979 int enabled_extension_count
= registry_
->enabled_extensions().size();
980 int installed_extension_count
=
981 enabled_extension_count
+ registry_
->disabled_extensions().size();
983 int expected_error_count
= (expected_state
== FAILED
) ? 1 : 0;
984 EXPECT_EQ(expected_error_count
, error_count
) << path
.value();
986 if (expected_state
<= FAILED
) {
987 EXPECT_EQ(previous_enabled_extension_count
,
988 enabled_extension_count
);
989 EXPECT_EQ(previous_installed_extension_count
,
990 installed_extension_count
);
992 int expected_installed_extension_count
=
993 (expected_state
>= INSTALLED
) ? 1 : 0;
994 int expected_enabled_extension_count
=
995 (expected_state
>= ENABLED
) ? 1 : 0;
996 EXPECT_EQ(expected_installed_extension_count
,
997 installed_extension_count
);
998 EXPECT_EQ(expected_enabled_extension_count
,
999 enabled_extension_count
);
1002 // Update() should the temporary input file.
1003 EXPECT_FALSE(base::PathExists(path
));
1006 void TerminateExtension(const std::string
& id
) {
1007 const Extension
* extension
= service_
->GetInstalledExtension(id
);
1012 service_
->TrackTerminatedExtensionForTest(extension
);
1015 size_t GetPrefKeyCount() {
1016 const base::DictionaryValue
* dict
=
1017 profile_
->GetPrefs()->GetDictionary("extensions.settings");
1022 return dict
->size();
1025 void UninstallExtension(const std::string
& id
, bool use_helper
) {
1026 // Verify that the extension is installed.
1027 base::FilePath extension_path
= extensions_install_dir_
.AppendASCII(id
);
1028 EXPECT_TRUE(base::PathExists(extension_path
));
1029 size_t pref_key_count
= GetPrefKeyCount();
1030 EXPECT_GT(pref_key_count
, 0u);
1031 ValidateIntegerPref(id
, "state", Extension::ENABLED
);
1035 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(service_
, id
));
1037 EXPECT_TRUE(service_
->UninstallExtension(id
, false, NULL
));
1039 --expected_extensions_count_
;
1041 // We should get an unload notification.
1042 EXPECT_FALSE(unloaded_id_
.empty());
1043 EXPECT_EQ(id
, unloaded_id_
);
1045 // Verify uninstalled state.
1046 size_t new_pref_key_count
= GetPrefKeyCount();
1047 if (new_pref_key_count
== pref_key_count
) {
1048 ValidateIntegerPref(id
, "location",
1049 Extension::EXTERNAL_EXTENSION_UNINSTALLED
);
1051 EXPECT_EQ(new_pref_key_count
, pref_key_count
- 1);
1054 // The extension should not be in the service anymore.
1055 EXPECT_FALSE(service_
->GetInstalledExtension(id
));
1056 base::RunLoop().RunUntilIdle();
1058 // The directory should be gone.
1059 EXPECT_FALSE(base::PathExists(extension_path
));
1062 void ValidatePrefKeyCount(size_t count
) {
1063 EXPECT_EQ(count
, GetPrefKeyCount());
1066 testing::AssertionResult
ValidateBooleanPref(
1067 const std::string
& extension_id
,
1068 const std::string
& pref_path
,
1069 bool expected_val
) {
1070 std::string msg
= "while checking: ";
1071 msg
+= extension_id
;
1075 msg
+= expected_val
? "true" : "false";
1077 PrefService
* prefs
= profile_
->GetPrefs();
1078 const base::DictionaryValue
* dict
=
1079 prefs
->GetDictionary("extensions.settings");
1081 return testing::AssertionFailure()
1082 << "extension.settings does not exist " << msg
;
1085 const base::DictionaryValue
* pref
= NULL
;
1086 if (!dict
->GetDictionary(extension_id
, &pref
)) {
1087 return testing::AssertionFailure()
1088 << "extension pref does not exist " << msg
;
1092 if (!pref
->GetBoolean(pref_path
, &val
)) {
1093 return testing::AssertionFailure()
1094 << pref_path
<< " pref not found " << msg
;
1097 return expected_val
== val
1098 ? testing::AssertionSuccess()
1099 : testing::AssertionFailure() << "base::Value is incorrect " << msg
;
1102 bool IsPrefExist(const std::string
& extension_id
,
1103 const std::string
& pref_path
) {
1104 const base::DictionaryValue
* dict
=
1105 profile_
->GetPrefs()->GetDictionary("extensions.settings");
1106 if (dict
== NULL
) return false;
1107 const base::DictionaryValue
* pref
= NULL
;
1108 if (!dict
->GetDictionary(extension_id
, &pref
)) {
1115 if (!pref
->GetBoolean(pref_path
, &val
)) {
1121 void ValidateIntegerPref(const std::string
& extension_id
,
1122 const std::string
& pref_path
,
1124 std::string msg
= " while checking: ";
1125 msg
+= extension_id
;
1129 msg
+= base::IntToString(expected_val
);
1131 PrefService
* prefs
= profile_
->GetPrefs();
1132 const base::DictionaryValue
* dict
=
1133 prefs
->GetDictionary("extensions.settings");
1134 ASSERT_TRUE(dict
!= NULL
) << msg
;
1135 const base::DictionaryValue
* pref
= NULL
;
1136 ASSERT_TRUE(dict
->GetDictionary(extension_id
, &pref
)) << msg
;
1137 EXPECT_TRUE(pref
!= NULL
) << msg
;
1139 ASSERT_TRUE(pref
->GetInteger(pref_path
, &val
)) << msg
;
1140 EXPECT_EQ(expected_val
, val
) << msg
;
1143 void ValidateStringPref(const std::string
& extension_id
,
1144 const std::string
& pref_path
,
1145 const std::string
& expected_val
) {
1146 std::string msg
= " while checking: ";
1147 msg
+= extension_id
;
1148 msg
+= ".manifest.";
1151 msg
+= expected_val
;
1153 const base::DictionaryValue
* dict
=
1154 profile_
->GetPrefs()->GetDictionary("extensions.settings");
1155 ASSERT_TRUE(dict
!= NULL
) << msg
;
1156 const base::DictionaryValue
* pref
= NULL
;
1157 std::string manifest_path
= extension_id
+ ".manifest";
1158 ASSERT_TRUE(dict
->GetDictionary(manifest_path
, &pref
)) << msg
;
1159 EXPECT_TRUE(pref
!= NULL
) << msg
;
1161 ASSERT_TRUE(pref
->GetString(pref_path
, &val
)) << msg
;
1162 EXPECT_EQ(expected_val
, val
) << msg
;
1165 void SetPref(const std::string
& extension_id
,
1166 const std::string
& pref_path
,
1168 const std::string
& msg
) {
1169 DictionaryPrefUpdate
update(profile_
->GetPrefs(), "extensions.settings");
1170 base::DictionaryValue
* dict
= update
.Get();
1171 ASSERT_TRUE(dict
!= NULL
) << msg
;
1172 base::DictionaryValue
* pref
= NULL
;
1173 ASSERT_TRUE(dict
->GetDictionary(extension_id
, &pref
)) << msg
;
1174 EXPECT_TRUE(pref
!= NULL
) << msg
;
1175 pref
->Set(pref_path
, value
);
1178 void SetPrefInteg(const std::string
& extension_id
,
1179 const std::string
& pref_path
,
1181 std::string msg
= " while setting: ";
1182 msg
+= extension_id
;
1186 msg
+= base::IntToString(value
);
1188 SetPref(extension_id
, pref_path
, new base::FundamentalValue(value
), msg
);
1191 void SetPrefBool(const std::string
& extension_id
,
1192 const std::string
& pref_path
,
1194 std::string msg
= " while setting: ";
1195 msg
+= extension_id
+ " " + pref_path
;
1197 msg
+= (value
? "true" : "false");
1199 SetPref(extension_id
, pref_path
, new base::FundamentalValue(value
), msg
);
1202 void ClearPref(const std::string
& extension_id
,
1203 const std::string
& pref_path
) {
1204 std::string msg
= " while clearing: ";
1205 msg
+= extension_id
+ " " + pref_path
;
1207 DictionaryPrefUpdate
update(profile_
->GetPrefs(), "extensions.settings");
1208 base::DictionaryValue
* dict
= update
.Get();
1209 ASSERT_TRUE(dict
!= NULL
) << msg
;
1210 base::DictionaryValue
* pref
= NULL
;
1211 ASSERT_TRUE(dict
->GetDictionary(extension_id
, &pref
)) << msg
;
1212 EXPECT_TRUE(pref
!= NULL
) << msg
;
1213 pref
->Remove(pref_path
, NULL
);
1216 void SetPrefStringSet(const std::string
& extension_id
,
1217 const std::string
& pref_path
,
1218 const std::set
<std::string
>& value
) {
1219 std::string msg
= " while setting: ";
1220 msg
+= extension_id
+ " " + pref_path
;
1222 base::ListValue
* list_value
= new base::ListValue();
1223 for (std::set
<std::string
>::const_iterator iter
= value
.begin();
1224 iter
!= value
.end(); ++iter
)
1225 list_value
->Append(new base::StringValue(*iter
));
1227 SetPref(extension_id
, pref_path
, list_value
, msg
);
1230 void InitPluginService() {
1231 #if defined(ENABLE_PLUGINS)
1232 PluginService::GetInstance()->Init();
1237 extensions::ExtensionList loaded_
;
1238 std::string unloaded_id_
;
1239 const Extension
* installed_
;
1241 std::string old_name_
;
1242 FeatureSwitch::ScopedOverride override_external_install_prompt_
;
1245 // Create a CrxInstaller and install the CRX file.
1246 // Instead of calling this method yourself, use InstallCRX(), which does extra
1248 void InstallCRXInternal(const base::FilePath
& crx_path
) {
1249 InstallCRXInternal(crx_path
, Extension::NO_FLAGS
);
1252 void InstallCRXInternal(const base::FilePath
& crx_path
, int creation_flags
) {
1253 ASSERT_TRUE(base::PathExists(crx_path
))
1254 << "Path does not exist: "<< crx_path
.value().c_str();
1255 scoped_refptr
<CrxInstaller
> installer(CrxInstaller::CreateSilent(service_
));
1256 installer
->set_creation_flags(creation_flags
);
1257 if (!(creation_flags
& Extension::WAS_INSTALLED_BY_DEFAULT
))
1258 installer
->set_allow_silent_install(true);
1260 content::WindowedNotificationObserver
observer(
1261 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
1262 content::Source
<extensions::CrxInstaller
>(installer
));
1264 installer
->InstallCrx(crx_path
);
1269 content::NotificationRegistrar registrar_
;
1272 // Receives notifications from a PackExtensionJob, indicating either that
1273 // packing succeeded or that there was some error.
1274 class PackExtensionTestClient
: public extensions::PackExtensionJob::Client
{
1276 PackExtensionTestClient(const base::FilePath
& expected_crx_path
,
1277 const base::FilePath
& expected_private_key_path
);
1278 virtual void OnPackSuccess(const base::FilePath
& crx_path
,
1279 const base::FilePath
& private_key_path
) OVERRIDE
;
1280 virtual void OnPackFailure(const std::string
& error_message
,
1281 ExtensionCreator::ErrorType type
) OVERRIDE
;
1284 const base::FilePath expected_crx_path_
;
1285 const base::FilePath expected_private_key_path_
;
1286 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient
);
1289 PackExtensionTestClient::PackExtensionTestClient(
1290 const base::FilePath
& expected_crx_path
,
1291 const base::FilePath
& expected_private_key_path
)
1292 : expected_crx_path_(expected_crx_path
),
1293 expected_private_key_path_(expected_private_key_path
) {}
1295 // If packing succeeded, we make sure that the package names match our
1297 void PackExtensionTestClient::OnPackSuccess(
1298 const base::FilePath
& crx_path
,
1299 const base::FilePath
& private_key_path
) {
1300 // We got the notification and processed it; we don't expect any further tasks
1301 // to be posted to the current thread, so we should stop blocking and continue
1302 // on with the rest of the test.
1303 // This call to |Quit()| matches the call to |Run()| in the
1304 // |PackPunctuatedExtension| test.
1305 base::MessageLoop::current()->Quit();
1306 EXPECT_EQ(expected_crx_path_
.value(), crx_path
.value());
1307 EXPECT_EQ(expected_private_key_path_
.value(), private_key_path
.value());
1308 ASSERT_TRUE(base::PathExists(private_key_path
));
1311 // The tests are designed so that we never expect to see a packing error.
1312 void PackExtensionTestClient::OnPackFailure(const std::string
& error_message
,
1313 ExtensionCreator::ErrorType type
) {
1314 if (type
== ExtensionCreator::kCRXExists
)
1315 FAIL() << "Packing should not fail.";
1317 FAIL() << "Existing CRX should have been overwritten.";
1320 // Test loading good extensions from the profile directory.
1321 TEST_F(ExtensionServiceTest
, LoadAllExtensionsFromDirectorySuccess
) {
1322 InitPluginService();
1323 InitializeGoodInstalledExtensionService();
1326 uint32 expected_num_extensions
= 3u;
1327 ASSERT_EQ(expected_num_extensions
, loaded_
.size());
1329 EXPECT_EQ(std::string(good0
), loaded_
[0]->id());
1330 EXPECT_EQ(std::string("My extension 1"),
1331 loaded_
[0]->name());
1332 EXPECT_EQ(std::string("The first extension that I made."),
1333 loaded_
[0]->description());
1334 EXPECT_EQ(Manifest::INTERNAL
, loaded_
[0]->location());
1335 EXPECT_TRUE(service_
->GetExtensionById(loaded_
[0]->id(), false));
1336 EXPECT_EQ(expected_num_extensions
, registry_
->enabled_extensions().size());
1338 ValidatePrefKeyCount(3);
1339 ValidateIntegerPref(good0
, "state", Extension::ENABLED
);
1340 ValidateIntegerPref(good0
, "location", Manifest::INTERNAL
);
1341 ValidateIntegerPref(good1
, "state", Extension::ENABLED
);
1342 ValidateIntegerPref(good1
, "location", Manifest::INTERNAL
);
1343 ValidateIntegerPref(good2
, "state", Extension::ENABLED
);
1344 ValidateIntegerPref(good2
, "location", Manifest::INTERNAL
);
1346 URLPatternSet expected_patterns
;
1347 AddPattern(&expected_patterns
, "file:///*");
1348 AddPattern(&expected_patterns
, "http://*.google.com/*");
1349 AddPattern(&expected_patterns
, "https://*.google.com/*");
1350 const Extension
* extension
= loaded_
[0].get();
1351 const extensions::UserScriptList
& scripts
=
1352 extensions::ContentScriptsInfo::GetContentScripts(extension
);
1353 ASSERT_EQ(2u, scripts
.size());
1354 EXPECT_EQ(expected_patterns
, scripts
[0].url_patterns());
1355 EXPECT_EQ(2u, scripts
[0].js_scripts().size());
1356 ExtensionResource
resource00(extension
->id(),
1357 scripts
[0].js_scripts()[0].extension_root(),
1358 scripts
[0].js_scripts()[0].relative_path());
1359 base::FilePath expected_path
=
1360 base::MakeAbsoluteFilePath(extension
->path().AppendASCII("script1.js"));
1361 EXPECT_TRUE(resource00
.ComparePathWithDefault(expected_path
));
1362 ExtensionResource
resource01(extension
->id(),
1363 scripts
[0].js_scripts()[1].extension_root(),
1364 scripts
[0].js_scripts()[1].relative_path());
1366 base::MakeAbsoluteFilePath(extension
->path().AppendASCII("script2.js"));
1367 EXPECT_TRUE(resource01
.ComparePathWithDefault(expected_path
));
1368 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension
));
1369 EXPECT_EQ(1u, scripts
[1].url_patterns().patterns().size());
1370 EXPECT_EQ("http://*.news.com/*",
1371 scripts
[1].url_patterns().begin()->GetAsString());
1372 ExtensionResource
resource10(extension
->id(),
1373 scripts
[1].js_scripts()[0].extension_root(),
1374 scripts
[1].js_scripts()[0].relative_path());
1376 extension
->path().AppendASCII("js_files").AppendASCII("script3.js");
1377 expected_path
= base::MakeAbsoluteFilePath(expected_path
);
1378 EXPECT_TRUE(resource10
.ComparePathWithDefault(expected_path
));
1380 expected_patterns
.ClearPatterns();
1381 AddPattern(&expected_patterns
, "http://*.google.com/*");
1382 AddPattern(&expected_patterns
, "https://*.google.com/*");
1383 EXPECT_EQ(expected_patterns
,
1384 extension
->GetActivePermissions()->explicit_hosts());
1386 EXPECT_EQ(std::string(good1
), loaded_
[1]->id());
1387 EXPECT_EQ(std::string("My extension 2"), loaded_
[1]->name());
1388 EXPECT_EQ(std::string(), loaded_
[1]->description());
1389 EXPECT_EQ(loaded_
[1]->GetResourceURL("background.html"),
1390 extensions::BackgroundInfo::GetBackgroundURL(loaded_
[1].get()));
1392 extensions::ContentScriptsInfo::GetContentScripts(loaded_
[1].get())
1395 // We don't parse the plugins section on Chrome OS.
1396 #if defined(OS_CHROMEOS)
1397 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_
[1].get()));
1399 ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_
[1].get()));
1400 const std::vector
<extensions::PluginInfo
>* plugins
=
1401 extensions::PluginInfo::GetPlugins(loaded_
[1].get());
1402 ASSERT_TRUE(plugins
);
1403 ASSERT_EQ(2u, plugins
->size());
1404 EXPECT_EQ(loaded_
[1]->path().AppendASCII("content_plugin.dll").value(),
1405 plugins
->at(0).path
.value());
1406 EXPECT_TRUE(plugins
->at(0).is_public
);
1407 EXPECT_EQ(loaded_
[1]->path().AppendASCII("extension_plugin.dll").value(),
1408 plugins
->at(1).path
.value());
1409 EXPECT_FALSE(plugins
->at(1).is_public
);
1412 EXPECT_EQ(Manifest::INTERNAL
, loaded_
[1]->location());
1414 int index
= expected_num_extensions
- 1;
1415 EXPECT_EQ(std::string(good2
), loaded_
[index
]->id());
1416 EXPECT_EQ(std::string("My extension 3"), loaded_
[index
]->name());
1417 EXPECT_EQ(std::string(), loaded_
[index
]->description());
1419 extensions::ContentScriptsInfo::GetContentScripts(
1420 loaded_
[index
].get()).size());
1421 EXPECT_EQ(Manifest::INTERNAL
, loaded_
[index
]->location());
1424 // Test loading bad extensions from the profile directory.
1425 TEST_F(ExtensionServiceTest
, LoadAllExtensionsFromDirectoryFail
) {
1426 // Initialize the test dir with a bad Preferences/extensions.
1427 base::FilePath source_install_dir
= data_dir_
1429 .AppendASCII("Extensions");
1430 base::FilePath pref_path
=
1431 source_install_dir
.DirName().Append(chrome::kPreferencesFilename
);
1433 InitializeInstalledExtensionService(pref_path
, source_install_dir
);
1437 ASSERT_EQ(4u, GetErrors().size());
1438 ASSERT_EQ(0u, loaded_
.size());
1440 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[0]),
1441 std::string("Could not load extension from '*'. ") +
1442 extensions::manifest_errors::kManifestUnreadable
)) <<
1443 base::UTF16ToUTF8(GetErrors()[0]);
1445 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[1]),
1446 std::string("Could not load extension from '*'. ") +
1447 extensions::manifest_errors::kManifestUnreadable
)) <<
1448 base::UTF16ToUTF8(GetErrors()[1]);
1450 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[2]),
1451 std::string("Could not load extension from '*'. ") +
1452 extensions::manifest_errors::kMissingFile
)) <<
1453 base::UTF16ToUTF8(GetErrors()[2]);
1455 EXPECT_TRUE(MatchPattern(base::UTF16ToUTF8(GetErrors()[3]),
1456 std::string("Could not load extension from '*'. ") +
1457 extensions::manifest_errors::kManifestUnreadable
)) <<
1458 base::UTF16ToUTF8(GetErrors()[3]);
1461 // Test that partially deleted extensions are cleaned up during startup
1462 // Test loading bad extensions from the profile directory.
1463 TEST_F(ExtensionServiceTest
, CleanupOnStartup
) {
1464 InitPluginService();
1465 InitializeGoodInstalledExtensionService();
1467 // Simulate that one of them got partially deleted by clearing its pref.
1469 DictionaryPrefUpdate
update(profile_
->GetPrefs(), "extensions.settings");
1470 base::DictionaryValue
* dict
= update
.Get();
1471 ASSERT_TRUE(dict
!= NULL
);
1472 dict
->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL
);
1476 // A delayed task to call GarbageCollectExtensions is posted by
1477 // ExtensionService::Init. As the test won't wait for the delayed task to
1478 // be called, call it manually instead.
1479 service_
->GarbageCollectExtensions();
1480 // Wait for GarbageCollectExtensions task to complete.
1481 base::RunLoop().RunUntilIdle();
1483 base::FileEnumerator
dirs(extensions_install_dir_
, false,
1484 base::FileEnumerator::DIRECTORIES
);
1486 while (!dirs
.Next().empty())
1489 // We should have only gotten two extensions now.
1490 EXPECT_EQ(2u, count
);
1492 // And extension1 dir should now be toast.
1493 base::FilePath extension_dir
= extensions_install_dir_
1494 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1495 ASSERT_FALSE(base::PathExists(extension_dir
));
1498 // Test that GarbageCollectExtensions deletes the right versions of an
1500 TEST_F(ExtensionServiceTest
, GarbageCollectWithPendingUpdates
) {
1501 InitPluginService();
1503 base::FilePath source_install_dir
= data_dir_
1504 .AppendASCII("pending_updates")
1505 .AppendASCII("Extensions");
1506 base::FilePath pref_path
=
1507 source_install_dir
.DirName().Append(chrome::kPreferencesFilename
);
1509 InitializeInstalledExtensionService(pref_path
, source_install_dir
);
1511 // This is the directory that is going to be deleted, so make sure it actually
1512 // is there before the garbage collection.
1513 ASSERT_TRUE(base::PathExists(extensions_install_dir_
.AppendASCII(
1514 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1516 service_
->GarbageCollectExtensions();
1517 // Wait for GarbageCollectExtensions task to complete.
1518 base::RunLoop().RunUntilIdle();
1520 // Verify that the pending update for the first extension didn't get
1522 EXPECT_TRUE(base::PathExists(extensions_install_dir_
.AppendASCII(
1523 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1524 EXPECT_TRUE(base::PathExists(extensions_install_dir_
.AppendASCII(
1525 "bjafgdebaacbbbecmhlhpofkepfkgcpa/2.0")));
1526 EXPECT_TRUE(base::PathExists(extensions_install_dir_
.AppendASCII(
1527 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1528 EXPECT_FALSE(base::PathExists(extensions_install_dir_
.AppendASCII(
1529 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1532 // Test that pending updates are properly handled on startup.
1533 TEST_F(ExtensionServiceTest
, UpdateOnStartup
) {
1534 InitPluginService();
1536 base::FilePath source_install_dir
= data_dir_
1537 .AppendASCII("pending_updates")
1538 .AppendASCII("Extensions");
1539 base::FilePath pref_path
=
1540 source_install_dir
.DirName().Append(chrome::kPreferencesFilename
);
1542 InitializeInstalledExtensionService(pref_path
, source_install_dir
);
1544 // This is the directory that is going to be deleted, so make sure it actually
1545 // is there before the garbage collection.
1546 ASSERT_TRUE(base::PathExists(extensions_install_dir_
.AppendASCII(
1547 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1550 // A delayed task to call GarbageCollectExtensions is posted by
1551 // ExtensionService::Init. As the test won't wait for the delayed task to
1552 // be called, call it manually instead.
1553 service_
->GarbageCollectExtensions();
1554 // Wait for GarbageCollectExtensions task to complete.
1555 base::RunLoop().RunUntilIdle();
1557 // Verify that the pending update for the first extension got installed.
1558 EXPECT_FALSE(base::PathExists(extensions_install_dir_
.AppendASCII(
1559 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1560 EXPECT_TRUE(base::PathExists(extensions_install_dir_
.AppendASCII(
1561 "bjafgdebaacbbbecmhlhpofkepfkgcpa/2.0")));
1562 EXPECT_TRUE(base::PathExists(extensions_install_dir_
.AppendASCII(
1563 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1564 EXPECT_FALSE(base::PathExists(extensions_install_dir_
.AppendASCII(
1565 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1567 // Make sure update information got deleted.
1568 ExtensionPrefs
* prefs
= service_
->extension_prefs();
1570 prefs
->GetDelayedInstallInfo("bjafgdebaacbbbecmhlhpofkepfkgcpa"));
1573 // Test various cases for delayed install because of missing imports.
1574 TEST_F(ExtensionServiceTest
, PendingImports
) {
1575 InitPluginService();
1577 base::FilePath source_install_dir
= data_dir_
1578 .AppendASCII("pending_updates_with_imports")
1579 .AppendASCII("Extensions");
1580 base::FilePath pref_path
=
1581 source_install_dir
.DirName().Append(chrome::kPreferencesFilename
);
1583 InitializeInstalledExtensionService(pref_path
, source_install_dir
);
1585 // Verify there are no pending extensions initially.
1586 EXPECT_FALSE(service_
->pending_extension_manager()->HasPendingExtensions());
1589 // Wait for GarbageCollectExtensions task to complete.
1590 base::RunLoop().RunUntilIdle();
1592 // These extensions are used by the extensions we test below, they must be
1594 EXPECT_TRUE(base::PathExists(extensions_install_dir_
.AppendASCII(
1595 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1596 EXPECT_TRUE(base::PathExists(extensions_install_dir_
.AppendASCII(
1597 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1599 // Each of these extensions should have been rejected because of dependencies
1600 // that cannot be satisfied.
1601 ExtensionPrefs
* prefs
= service_
->extension_prefs();
1603 prefs
->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1605 prefs
->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1607 prefs
->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1609 prefs
->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1611 prefs
->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
1613 prefs
->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
1615 // Make sure the import started for the extension with a dependency.
1617 prefs
->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1618 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS
,
1619 prefs
->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1621 EXPECT_FALSE(base::PathExists(extensions_install_dir_
.AppendASCII(
1622 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
1624 EXPECT_TRUE(service_
->pending_extension_manager()->HasPendingExtensions());
1625 std::string
pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
1626 EXPECT_TRUE(service_
->pending_extension_manager()->IsIdPending(pending_id
));
1627 // Remove it because we are not testing the pending extension manager's
1628 // ability to download and install extensions.
1629 EXPECT_TRUE(service_
->pending_extension_manager()->Remove(pending_id
));
1632 // Test installing extensions. This test tries to install few extensions using
1633 // crx files. If you need to change those crx files, feel free to repackage
1634 // them, throw away the key used and change the id's above.
1635 TEST_F(ExtensionServiceTest
, InstallExtension
) {
1636 InitializeEmptyExtensionService();
1638 // Extensions not enabled.
1639 set_extensions_enabled(false);
1640 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
1641 InstallCRX(path
, INSTALL_FAILED
);
1642 set_extensions_enabled(true);
1644 ValidatePrefKeyCount(0);
1646 // A simple extension that should install without error.
1647 path
= data_dir_
.AppendASCII("good.crx");
1648 InstallCRX(path
, INSTALL_NEW
);
1649 // TODO(erikkay): verify the contents of the installed extension.
1652 ValidatePrefKeyCount(++pref_count
);
1653 ValidateIntegerPref(good_crx
, "state", Extension::ENABLED
);
1654 ValidateIntegerPref(good_crx
, "location", Manifest::INTERNAL
);
1656 // An extension with page actions.
1657 path
= data_dir_
.AppendASCII("page_action.crx");
1658 InstallCRX(path
, INSTALL_NEW
);
1659 ValidatePrefKeyCount(++pref_count
);
1660 ValidateIntegerPref(page_action
, "state", Extension::ENABLED
);
1661 ValidateIntegerPref(page_action
, "location", Manifest::INTERNAL
);
1664 path
= data_dir_
.AppendASCII("bad_signature.crx");
1665 InstallCRX(path
, INSTALL_FAILED
);
1666 ValidatePrefKeyCount(pref_count
);
1668 // 0-length extension file.
1669 path
= data_dir_
.AppendASCII("not_an_extension.crx");
1670 InstallCRX(path
, INSTALL_FAILED
);
1671 ValidatePrefKeyCount(pref_count
);
1673 // Bad magic number.
1674 path
= data_dir_
.AppendASCII("bad_magic.crx");
1675 InstallCRX(path
, INSTALL_FAILED
);
1676 ValidatePrefKeyCount(pref_count
);
1678 // Packed extensions may have folders or files that have underscores.
1679 // This will only cause a warning, rather than a fatal error.
1680 path
= data_dir_
.AppendASCII("bad_underscore.crx");
1681 InstallCRX(path
, INSTALL_NEW
);
1682 ValidatePrefKeyCount(++pref_count
);
1684 // A test for an extension with a 2048-bit public key.
1685 path
= data_dir_
.AppendASCII("good2048.crx");
1686 InstallCRX(path
, INSTALL_NEW
);
1687 ValidatePrefKeyCount(++pref_count
);
1688 ValidateIntegerPref(good2048
, "state", Extension::ENABLED
);
1689 ValidateIntegerPref(good2048
, "location", Manifest::INTERNAL
);
1691 // TODO(erikkay): add more tests for many of the failure cases.
1692 // TODO(erikkay): add tests for upgrade cases.
1695 struct MockInstallObserver
: public extensions::InstallObserver
{
1696 MockInstallObserver() {
1699 virtual ~MockInstallObserver() {
1702 virtual void OnBeginExtensionInstall(
1703 const ExtensionInstallParams
& params
) OVERRIDE
{
1706 virtual void OnDownloadProgress(const std::string
& extension_id
,
1707 int percent_downloaded
) OVERRIDE
{
1710 virtual void OnExtensionInstalled(const Extension
* extension
) OVERRIDE
{
1711 last_extension_installed
= extension
->id();
1714 virtual void OnInstallFailure(const std::string
& extension_id
) OVERRIDE
{
1717 virtual void OnExtensionLoaded(const Extension
* extension
) OVERRIDE
{
1720 virtual void OnExtensionUnloaded(const Extension
* extension
) OVERRIDE
{
1723 virtual void OnExtensionUninstalled(const Extension
* extension
) OVERRIDE
{
1724 last_extension_uninstalled
= extension
->id();
1727 virtual void OnAppsReordered() OVERRIDE
{
1730 virtual void OnAppInstalledToAppList(
1731 const std::string
& extension_id
) OVERRIDE
{
1734 virtual void OnShutdown() OVERRIDE
{
1737 std::string last_extension_installed
;
1738 std::string last_extension_uninstalled
;
1741 // Test that correct notifications are sent to InstallTracker observers on
1742 // extension install and uninstall.
1743 TEST_F(ExtensionServiceTest
, InstallObserverNotified
) {
1744 InitializeEmptyExtensionService();
1746 extensions::InstallTracker
* tracker(
1747 extensions::InstallTrackerFactory::GetForProfile(profile_
.get()));
1748 MockInstallObserver observer
;
1749 tracker
->AddObserver(&observer
);
1751 // A simple extension that should install without error.
1752 ASSERT_TRUE(observer
.last_extension_installed
.empty());
1753 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
1754 InstallCRX(path
, INSTALL_NEW
);
1755 ASSERT_EQ(good_crx
, observer
.last_extension_installed
);
1757 // Uninstall the extension.
1758 ASSERT_TRUE(observer
.last_extension_uninstalled
.empty());
1759 UninstallExtension(good_crx
, false);
1760 ASSERT_EQ(good_crx
, observer
.last_extension_uninstalled
);
1762 tracker
->RemoveObserver(&observer
);
1765 // Tests that flags passed to OnExternalExtensionFileFound() make it to the
1766 // extension object.
1767 TEST_F(ExtensionServiceTest
, InstallingExternalExtensionWithFlags
) {
1768 const char kPrefFromBookmark
[] = "from_bookmark";
1770 InitializeEmptyExtensionService();
1772 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
1773 set_extensions_enabled(true);
1775 // Register and install an external extension.
1776 Version
version("1.0.0.0");
1777 content::WindowedNotificationObserver
observer(
1778 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
1779 content::NotificationService::AllSources());
1780 if (service_
->OnExternalExtensionFileFound(
1784 Manifest::EXTERNAL_PREF
,
1785 Extension::FROM_BOOKMARK
,
1786 false /* mark_acknowledged */)) {
1790 const Extension
* extension
= service_
->GetExtensionById(good_crx
, false);
1791 ASSERT_TRUE(extension
);
1792 ASSERT_TRUE(extension
->from_bookmark());
1793 ASSERT_TRUE(ValidateBooleanPref(good_crx
, kPrefFromBookmark
, true));
1795 // Upgrade to version 2.0, the flag should be preserved.
1796 path
= data_dir_
.AppendASCII("good2.crx");
1797 UpdateExtension(good_crx
, path
, ENABLED
);
1798 ASSERT_TRUE(ValidateBooleanPref(good_crx
, kPrefFromBookmark
, true));
1799 extension
= service_
->GetExtensionById(good_crx
, false);
1800 ASSERT_TRUE(extension
);
1801 ASSERT_TRUE(extension
->from_bookmark());
1804 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
1805 TEST_F(ExtensionServiceTest
, UninstallingExternalExtensions
) {
1806 InitializeEmptyExtensionService();
1808 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
1809 set_extensions_enabled(true);
1811 // Install an external extension.
1812 Version
version("1.0.0.0");
1813 content::WindowedNotificationObserver
observer(
1814 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
1815 content::NotificationService::AllSources());
1816 if (service_
->OnExternalExtensionFileFound(good_crx
, &version
,
1817 path
, Manifest::EXTERNAL_PREF
,
1818 Extension::NO_FLAGS
, false)) {
1822 ASSERT_TRUE(service_
->GetExtensionById(good_crx
, false));
1824 // Uninstall it and check that its killbit gets set.
1825 UninstallExtension(good_crx
, false);
1826 ValidateIntegerPref(good_crx
, "location",
1827 Extension::EXTERNAL_EXTENSION_UNINSTALLED
);
1829 // Try to re-install it externally. This should fail because of the killbit.
1830 service_
->OnExternalExtensionFileFound(good_crx
, &version
,
1831 path
, Manifest::EXTERNAL_PREF
,
1832 Extension::NO_FLAGS
, false);
1833 base::RunLoop().RunUntilIdle();
1834 ASSERT_TRUE(NULL
== service_
->GetExtensionById(good_crx
, false));
1835 ValidateIntegerPref(good_crx
, "location",
1836 Extension::EXTERNAL_EXTENSION_UNINSTALLED
);
1838 version
= Version("1.0.0.1");
1839 // Repeat the same thing with a newer version of the extension.
1840 path
= data_dir_
.AppendASCII("good2.crx");
1841 service_
->OnExternalExtensionFileFound(good_crx
, &version
,
1842 path
, Manifest::EXTERNAL_PREF
,
1843 Extension::NO_FLAGS
, false);
1844 base::RunLoop().RunUntilIdle();
1845 ASSERT_TRUE(NULL
== service_
->GetExtensionById(good_crx
, false));
1846 ValidateIntegerPref(good_crx
, "location",
1847 Extension::EXTERNAL_EXTENSION_UNINSTALLED
);
1849 // Try adding the same extension from an external update URL.
1850 ASSERT_FALSE(service_
->pending_extension_manager()->AddFromExternalUpdateUrl(
1852 GURL("http:://fake.update/url"),
1853 Manifest::EXTERNAL_PREF_DOWNLOAD
,
1854 Extension::NO_FLAGS
,
1857 ASSERT_FALSE(service_
->pending_extension_manager()->IsIdPending(good_crx
));
1860 // Test that uninstalling an external extension does not crash when
1861 // the extension could not be loaded.
1862 // This extension shown in preferences file requires an experimental permission.
1863 // It could not be loaded without such permission.
1864 TEST_F(ExtensionServiceTest
, UninstallingNotLoadedExtension
) {
1865 base::FilePath source_install_dir
= data_dir_
1866 .AppendASCII("good")
1867 .AppendASCII("Extensions");
1868 // The preference contains an external extension
1869 // that requires 'experimental' permission.
1870 base::FilePath pref_path
= source_install_dir
1872 .AppendASCII("PreferencesExperimental");
1874 // Aforementioned extension will not be loaded if
1875 // there is no '--enable-experimental-extension-apis' command line flag.
1876 InitializeInstalledExtensionService(pref_path
, source_install_dir
);
1880 // Check and try to uninstall it.
1881 // If we don't check whether the extension is loaded before we uninstall it
1882 // in CheckExternalUninstall, a crash will happen here because we will get or
1883 // dereference a NULL pointer (extension) inside UninstallExtension.
1884 MockExtensionProvider
provider(NULL
, Manifest::EXTERNAL_REGISTRY
);
1885 service_
->OnExternalProviderReady(&provider
);
1888 // Test that external extensions with incorrect IDs are not installed.
1889 TEST_F(ExtensionServiceTest
, FailOnWrongId
) {
1890 InitializeEmptyExtensionService();
1891 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
1892 set_extensions_enabled(true);
1894 Version
version("1.0.0.0");
1896 const std::string wrong_id
= all_zero
;
1897 const std::string correct_id
= good_crx
;
1898 ASSERT_NE(correct_id
, wrong_id
);
1900 // Install an external extension with an ID from the external
1901 // source that is not equal to the ID in the extension manifest.
1902 content::WindowedNotificationObserver
observer(
1903 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
1904 content::NotificationService::AllSources());
1905 service_
->OnExternalExtensionFileFound(
1906 wrong_id
, &version
, path
, Manifest::EXTERNAL_PREF
,
1907 Extension::NO_FLAGS
, false);
1910 ASSERT_FALSE(service_
->GetExtensionById(good_crx
, false));
1912 // Try again with the right ID. Expect success.
1913 content::WindowedNotificationObserver
observer2(
1914 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
1915 content::NotificationService::AllSources());
1916 if (service_
->OnExternalExtensionFileFound(
1917 correct_id
, &version
, path
, Manifest::EXTERNAL_PREF
,
1918 Extension::NO_FLAGS
, false)) {
1921 ASSERT_TRUE(service_
->GetExtensionById(good_crx
, false));
1924 // Test that external extensions with incorrect versions are not installed.
1925 TEST_F(ExtensionServiceTest
, FailOnWrongVersion
) {
1926 InitializeEmptyExtensionService();
1927 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
1928 set_extensions_enabled(true);
1930 // Install an external extension with a version from the external
1931 // source that is not equal to the version in the extension manifest.
1932 Version
wrong_version("1.2.3.4");
1933 content::WindowedNotificationObserver
observer(
1934 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
1935 content::NotificationService::AllSources());
1936 service_
->OnExternalExtensionFileFound(
1937 good_crx
, &wrong_version
, path
, Manifest::EXTERNAL_PREF
,
1938 Extension::NO_FLAGS
, false);
1941 ASSERT_FALSE(service_
->GetExtensionById(good_crx
, false));
1943 // Try again with the right version. Expect success.
1944 service_
->pending_extension_manager()->Remove(good_crx
);
1945 Version
correct_version("1.0.0.0");
1946 content::WindowedNotificationObserver
observer2(
1947 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
1948 content::NotificationService::AllSources());
1949 if (service_
->OnExternalExtensionFileFound(
1950 good_crx
, &correct_version
, path
, Manifest::EXTERNAL_PREF
,
1951 Extension::NO_FLAGS
, false)) {
1954 ASSERT_TRUE(service_
->GetExtensionById(good_crx
, false));
1957 // Install a user script (they get converted automatically to an extension)
1958 TEST_F(ExtensionServiceTest
, InstallUserScript
) {
1959 // The details of script conversion are tested elsewhere, this just tests
1960 // integration with ExtensionService.
1961 InitializeEmptyExtensionService();
1963 base::FilePath path
= data_dir_
1964 .AppendASCII("user_script_basic.user.js");
1966 ASSERT_TRUE(base::PathExists(path
));
1967 scoped_refptr
<CrxInstaller
> installer(CrxInstaller::CreateSilent(service_
));
1968 installer
->set_allow_silent_install(true);
1969 installer
->InstallUserScript(
1971 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1973 base::RunLoop().RunUntilIdle();
1974 std::vector
<base::string16
> errors
= GetErrors();
1975 EXPECT_TRUE(installed_
) << "Nothing was installed.";
1976 EXPECT_FALSE(was_update_
) << path
.value();
1977 ASSERT_EQ(1u, loaded_
.size()) << "Nothing was loaded.";
1978 EXPECT_EQ(0u, errors
.size()) << "There were errors: "
1979 << JoinString(errors
, ',');
1980 EXPECT_TRUE(service_
->GetExtensionById(loaded_
[0]->id(), false)) <<
1984 was_update_
= false;
1986 ExtensionErrorReporter::GetInstance()->ClearErrors();
1989 // Extensions don't install during shutdown.
1990 TEST_F(ExtensionServiceTest
, InstallExtensionDuringShutdown
) {
1991 InitializeEmptyExtensionService();
1993 // Simulate shutdown.
1994 service_
->set_browser_terminating_for_test(true);
1996 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
1997 scoped_refptr
<CrxInstaller
> installer(CrxInstaller::CreateSilent(service_
));
1998 installer
->set_allow_silent_install(true);
1999 installer
->InstallCrx(path
);
2000 base::RunLoop().RunUntilIdle();
2002 EXPECT_FALSE(installed_
) << "Extension installed during shutdown.";
2003 ASSERT_EQ(0u, loaded_
.size()) << "Extension loaded during shutdown.";
2006 // This tests that the granted permissions preferences are correctly set when
2007 // installing an extension.
2008 TEST_F(ExtensionServiceTest
, GrantedPermissions
) {
2009 InitializeEmptyExtensionService();
2010 base::FilePath path
= data_dir_
2011 .AppendASCII("permissions");
2013 base::FilePath pem_path
= path
.AppendASCII("unknown.pem");
2014 path
= path
.AppendASCII("unknown");
2016 ASSERT_TRUE(base::PathExists(pem_path
));
2017 ASSERT_TRUE(base::PathExists(path
));
2019 ExtensionPrefs
* prefs
= service_
->extension_prefs();
2021 APIPermissionSet expected_api_perms
;
2022 URLPatternSet expected_host_perms
;
2024 // Make sure there aren't any granted permissions before the
2025 // extension is installed.
2026 scoped_refptr
<PermissionSet
> known_perms(
2027 prefs
->GetGrantedPermissions(permissions_crx
));
2028 EXPECT_FALSE(known_perms
.get());
2030 const Extension
* extension
= PackAndInstallCRX(path
, pem_path
, INSTALL_NEW
);
2032 EXPECT_EQ(0u, GetErrors().size());
2033 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
2034 EXPECT_EQ(permissions_crx
, extension
->id());
2036 // Verify that the valid API permissions have been recognized.
2037 expected_api_perms
.insert(APIPermission::kTab
);
2039 AddPattern(&expected_host_perms
, "http://*.google.com/*");
2040 AddPattern(&expected_host_perms
, "https://*.google.com/*");
2041 AddPattern(&expected_host_perms
, "http://*.google.com.hk/*");
2042 AddPattern(&expected_host_perms
, "http://www.example.com/*");
2044 known_perms
= prefs
->GetGrantedPermissions(extension
->id());
2045 EXPECT_TRUE(known_perms
.get());
2046 EXPECT_FALSE(known_perms
->IsEmpty());
2047 EXPECT_EQ(expected_api_perms
, known_perms
->apis());
2048 EXPECT_FALSE(known_perms
->HasEffectiveFullAccess());
2049 EXPECT_EQ(expected_host_perms
, known_perms
->effective_hosts());
2053 #if !defined(OS_CHROMEOS)
2054 // This tests that the granted permissions preferences are correctly set for
2056 TEST_F(ExtensionServiceTest
, DefaultAppsGrantedPermissions
) {
2057 InitializeEmptyExtensionService();
2058 base::FilePath path
= data_dir_
2059 .AppendASCII("permissions");
2061 base::FilePath pem_path
= path
.AppendASCII("unknown.pem");
2062 path
= path
.AppendASCII("unknown");
2064 ASSERT_TRUE(base::PathExists(pem_path
));
2065 ASSERT_TRUE(base::PathExists(path
));
2067 ExtensionPrefs
* prefs
= service_
->extension_prefs();
2069 APIPermissionSet expected_api_perms
;
2070 URLPatternSet expected_host_perms
;
2072 // Make sure there aren't any granted permissions before the
2073 // extension is installed.
2074 scoped_refptr
<PermissionSet
> known_perms(
2075 prefs
->GetGrantedPermissions(permissions_crx
));
2076 EXPECT_FALSE(known_perms
.get());
2078 const Extension
* extension
= PackAndInstallCRX(
2079 path
, pem_path
, INSTALL_NEW
, Extension::WAS_INSTALLED_BY_DEFAULT
);
2081 EXPECT_EQ(0u, GetErrors().size());
2082 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
2083 EXPECT_EQ(permissions_crx
, extension
->id());
2085 // Verify that the valid API permissions have been recognized.
2086 expected_api_perms
.insert(APIPermission::kTab
);
2088 known_perms
= prefs
->GetGrantedPermissions(extension
->id());
2089 EXPECT_TRUE(known_perms
.get());
2090 EXPECT_FALSE(known_perms
->IsEmpty());
2091 EXPECT_EQ(expected_api_perms
, known_perms
->apis());
2092 EXPECT_FALSE(known_perms
->HasEffectiveFullAccess());
2096 #if !defined(OS_CHROMEOS)
2097 // Tests that the granted permissions full_access bit gets set correctly when
2098 // an extension contains an NPAPI plugin. Don't run this test on Chrome OS
2099 // since they don't support plugins.
2100 TEST_F(ExtensionServiceTest
, GrantedFullAccessPermissions
) {
2101 InitPluginService();
2103 InitializeEmptyExtensionService();
2105 ASSERT_TRUE(base::PathExists(good1_path()));
2106 const Extension
* extension
= PackAndInstallCRX(good1_path(), INSTALL_NEW
);
2107 EXPECT_EQ(0u, GetErrors().size());
2108 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
2109 ExtensionPrefs
* prefs
= service_
->extension_prefs();
2111 scoped_refptr
<PermissionSet
> permissions(
2112 prefs
->GetGrantedPermissions(extension
->id()));
2113 EXPECT_FALSE(permissions
->IsEmpty());
2114 EXPECT_TRUE(permissions
->HasEffectiveFullAccess());
2115 EXPECT_FALSE(permissions
->apis().empty());
2116 EXPECT_TRUE(permissions
->HasAPIPermission(APIPermission::kPlugin
));
2118 // Full access implies full host access too...
2119 EXPECT_TRUE(permissions
->HasEffectiveAccessToAllHosts());
2123 // Tests that the extension is disabled when permissions are missing from
2124 // the extension's granted permissions preferences. (This simulates updating
2125 // the browser to a version which recognizes more permissions).
2126 TEST_F(ExtensionServiceTest
, GrantedAPIAndHostPermissions
) {
2127 InitializeEmptyExtensionService();
2129 base::FilePath path
= data_dir_
2130 .AppendASCII("permissions")
2131 .AppendASCII("unknown");
2133 ASSERT_TRUE(base::PathExists(path
));
2135 const Extension
* extension
= PackAndInstallCRX(path
, INSTALL_NEW
);
2137 EXPECT_EQ(0u, GetErrors().size());
2138 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
2139 std::string extension_id
= extension
->id();
2141 ExtensionPrefs
* prefs
= service_
->extension_prefs();
2143 APIPermissionSet expected_api_permissions
;
2144 URLPatternSet expected_host_permissions
;
2146 expected_api_permissions
.insert(APIPermission::kTab
);
2147 AddPattern(&expected_host_permissions
, "http://*.google.com/*");
2148 AddPattern(&expected_host_permissions
, "https://*.google.com/*");
2149 AddPattern(&expected_host_permissions
, "http://*.google.com.hk/*");
2150 AddPattern(&expected_host_permissions
, "http://www.example.com/*");
2152 std::set
<std::string
> host_permissions
;
2154 // Test that the extension is disabled when an API permission is missing from
2155 // the extension's granted api permissions preference. (This simulates
2156 // updating the browser to a version which recognizes a new API permission).
2157 SetPref(extension_id
, "granted_permissions.api",
2158 new base::ListValue(), "granted_permissions.api");
2159 service_
->ReloadExtensionsForTest();
2161 EXPECT_EQ(1u, registry_
->disabled_extensions().size());
2162 extension
= registry_
->disabled_extensions().begin()->get();
2164 ASSERT_TRUE(prefs
->IsExtensionDisabled(extension_id
));
2165 ASSERT_FALSE(service_
->IsExtensionEnabled(extension_id
));
2166 ASSERT_TRUE(prefs
->DidExtensionEscalatePermissions(extension_id
));
2168 // Now grant and re-enable the extension, making sure the prefs are updated.
2169 service_
->GrantPermissionsAndEnableExtension(extension
);
2171 ASSERT_FALSE(prefs
->IsExtensionDisabled(extension_id
));
2172 ASSERT_TRUE(service_
->IsExtensionEnabled(extension_id
));
2173 ASSERT_FALSE(prefs
->DidExtensionEscalatePermissions(extension_id
));
2175 scoped_refptr
<PermissionSet
> current_perms(
2176 prefs
->GetGrantedPermissions(extension_id
));
2177 ASSERT_TRUE(current_perms
.get());
2178 ASSERT_FALSE(current_perms
->IsEmpty());
2179 ASSERT_FALSE(current_perms
->HasEffectiveFullAccess());
2180 ASSERT_EQ(expected_api_permissions
, current_perms
->apis());
2181 ASSERT_EQ(expected_host_permissions
, current_perms
->effective_hosts());
2183 // Tests that the extension is disabled when a host permission is missing from
2184 // the extension's granted host permissions preference. (This simulates
2185 // updating the browser to a version which recognizes additional host
2187 host_permissions
.clear();
2188 current_perms
= NULL
;
2190 host_permissions
.insert("http://*.google.com/*");
2191 host_permissions
.insert("https://*.google.com/*");
2192 host_permissions
.insert("http://*.google.com.hk/*");
2194 base::ListValue
* api_permissions
= new base::ListValue();
2195 api_permissions
->Append(
2196 new base::StringValue("tabs"));
2197 SetPref(extension_id
, "granted_permissions.api",
2198 api_permissions
, "granted_permissions.api");
2200 extension_id
, "granted_permissions.scriptable_host", host_permissions
);
2202 service_
->ReloadExtensionsForTest();
2204 EXPECT_EQ(1u, registry_
->disabled_extensions().size());
2205 extension
= registry_
->disabled_extensions().begin()->get();
2207 ASSERT_TRUE(prefs
->IsExtensionDisabled(extension_id
));
2208 ASSERT_FALSE(service_
->IsExtensionEnabled(extension_id
));
2209 ASSERT_TRUE(prefs
->DidExtensionEscalatePermissions(extension_id
));
2211 // Now grant and re-enable the extension, making sure the prefs are updated.
2212 service_
->GrantPermissionsAndEnableExtension(extension
);
2214 ASSERT_TRUE(service_
->IsExtensionEnabled(extension_id
));
2215 ASSERT_FALSE(prefs
->DidExtensionEscalatePermissions(extension_id
));
2217 current_perms
= prefs
->GetGrantedPermissions(extension_id
);
2218 ASSERT_TRUE(current_perms
.get());
2219 ASSERT_FALSE(current_perms
->IsEmpty());
2220 ASSERT_FALSE(current_perms
->HasEffectiveFullAccess());
2221 ASSERT_EQ(expected_api_permissions
, current_perms
->apis());
2222 ASSERT_EQ(expected_host_permissions
, current_perms
->effective_hosts());
2225 // Test Packaging and installing an extension.
2226 TEST_F(ExtensionServiceTest
, PackExtension
) {
2227 InitializeEmptyExtensionService();
2228 base::FilePath input_directory
= data_dir_
2229 .AppendASCII("good")
2230 .AppendASCII("Extensions")
2231 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2232 .AppendASCII("1.0.0.0");
2234 base::ScopedTempDir temp_dir
;
2235 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
2236 base::FilePath output_directory
= temp_dir
.path();
2238 base::FilePath
crx_path(output_directory
.AppendASCII("ex1.crx"));
2239 base::FilePath
privkey_path(output_directory
.AppendASCII("privkey.pem"));
2241 scoped_ptr
<ExtensionCreator
> creator(new ExtensionCreator());
2242 ASSERT_TRUE(creator
->Run(input_directory
, crx_path
, base::FilePath(),
2243 privkey_path
, ExtensionCreator::kNoRunFlags
));
2244 ASSERT_TRUE(base::PathExists(crx_path
));
2245 ASSERT_TRUE(base::PathExists(privkey_path
));
2247 // Repeat the run with the pem file gone, and no special flags
2248 // Should refuse to overwrite the existing crx.
2249 base::DeleteFile(privkey_path
, false);
2250 ASSERT_FALSE(creator
->Run(input_directory
, crx_path
, base::FilePath(),
2251 privkey_path
, ExtensionCreator::kNoRunFlags
));
2253 // OK, now try it with a flag to overwrite existing crx. Should work.
2254 ASSERT_TRUE(creator
->Run(input_directory
, crx_path
, base::FilePath(),
2255 privkey_path
, ExtensionCreator::kOverwriteCRX
));
2257 // Repeat the run allowing existing crx, but the existing pem is still
2258 // an error. Should fail.
2259 ASSERT_FALSE(creator
->Run(input_directory
, crx_path
, base::FilePath(),
2260 privkey_path
, ExtensionCreator::kOverwriteCRX
));
2262 ASSERT_TRUE(base::PathExists(privkey_path
));
2263 InstallCRX(crx_path
, INSTALL_NEW
);
2265 // Try packing with invalid paths.
2266 creator
.reset(new ExtensionCreator());
2268 creator
->Run(base::FilePath(), base::FilePath(), base::FilePath(),
2269 base::FilePath(), ExtensionCreator::kOverwriteCRX
));
2271 // Try packing an empty directory. Should fail because an empty directory is
2272 // not a valid extension.
2273 base::ScopedTempDir temp_dir2
;
2274 ASSERT_TRUE(temp_dir2
.CreateUniqueTempDir());
2275 creator
.reset(new ExtensionCreator());
2276 ASSERT_FALSE(creator
->Run(temp_dir2
.path(), crx_path
, privkey_path
,
2277 base::FilePath(), ExtensionCreator::kOverwriteCRX
));
2279 // Try packing with an invalid manifest.
2280 std::string invalid_manifest_content
= "I am not a manifest.";
2281 ASSERT_TRUE(file_util::WriteFile(
2282 temp_dir2
.path().Append(extensions::kManifestFilename
),
2283 invalid_manifest_content
.c_str(), invalid_manifest_content
.size()));
2284 creator
.reset(new ExtensionCreator());
2285 ASSERT_FALSE(creator
->Run(temp_dir2
.path(), crx_path
, privkey_path
,
2286 base::FilePath(), ExtensionCreator::kOverwriteCRX
));
2288 // Try packing with a private key that is a valid key, but invalid for the
2290 base::FilePath bad_private_key_dir
= data_dir_
.AppendASCII("bad_private_key");
2291 crx_path
= output_directory
.AppendASCII("bad_private_key.crx");
2292 privkey_path
= data_dir_
.AppendASCII("bad_private_key.pem");
2293 ASSERT_FALSE(creator
->Run(bad_private_key_dir
, crx_path
, base::FilePath(),
2294 privkey_path
, ExtensionCreator::kOverwriteCRX
));
2297 // Test Packaging and installing an extension whose name contains punctuation.
2298 TEST_F(ExtensionServiceTest
, PackPunctuatedExtension
) {
2299 InitializeEmptyExtensionService();
2300 base::FilePath input_directory
= data_dir_
2301 .AppendASCII("good")
2302 .AppendASCII("Extensions")
2304 .AppendASCII("1.0.0.0");
2306 base::ScopedTempDir temp_dir
;
2307 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
2309 // Extension names containing punctuation, and the expected names for the
2310 // packed extensions.
2311 const base::FilePath punctuated_names
[] = {
2312 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2313 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2314 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
2315 NormalizePathSeparators(),
2317 const base::FilePath expected_crx_names
[] = {
2318 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2320 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2321 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
2323 const base::FilePath expected_private_key_names
[] = {
2324 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2326 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2327 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
2330 for (size_t i
= 0; i
< arraysize(punctuated_names
); ++i
) {
2331 SCOPED_TRACE(punctuated_names
[i
].value().c_str());
2332 base::FilePath output_dir
= temp_dir
.path().Append(punctuated_names
[i
]);
2334 // Copy the extension into the output directory, as PackExtensionJob doesn't
2335 // let us choose where to output the packed extension.
2336 ASSERT_TRUE(base::CopyDirectory(input_directory
, output_dir
, true));
2338 base::FilePath expected_crx_path
=
2339 temp_dir
.path().Append(expected_crx_names
[i
]);
2340 base::FilePath expected_private_key_path
=
2341 temp_dir
.path().Append(expected_private_key_names
[i
]);
2342 PackExtensionTestClient
pack_client(expected_crx_path
,
2343 expected_private_key_path
);
2344 scoped_refptr
<extensions::PackExtensionJob
> packer(
2345 new extensions::PackExtensionJob(&pack_client
, output_dir
,
2347 ExtensionCreator::kOverwriteCRX
));
2350 // The packer will post a notification task to the current thread's message
2351 // loop when it is finished. We manually run the loop here so that we
2352 // block and catch the notification; otherwise, the process would exit.
2353 // This call to |Run()| is matched by a call to |Quit()| in the
2354 // |PackExtensionTestClient|'s notification handling code.
2355 base::MessageLoop::current()->Run();
2357 if (HasFatalFailure())
2360 InstallCRX(expected_crx_path
, INSTALL_NEW
);
2364 TEST_F(ExtensionServiceTest
, PackExtensionContainingKeyFails
) {
2365 InitializeEmptyExtensionService();
2367 base::ScopedTempDir extension_temp_dir
;
2368 ASSERT_TRUE(extension_temp_dir
.CreateUniqueTempDir());
2369 base::FilePath input_directory
= extension_temp_dir
.path().AppendASCII("ext");
2370 ASSERT_TRUE(base::CopyDirectory(
2372 .AppendASCII("good")
2373 .AppendASCII("Extensions")
2374 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2375 .AppendASCII("1.0.0.0"),
2377 /*recursive=*/true));
2379 base::ScopedTempDir output_temp_dir
;
2380 ASSERT_TRUE(output_temp_dir
.CreateUniqueTempDir());
2381 base::FilePath output_directory
= output_temp_dir
.path();
2383 base::FilePath
crx_path(output_directory
.AppendASCII("ex1.crx"));
2384 base::FilePath
privkey_path(output_directory
.AppendASCII("privkey.pem"));
2386 // Pack the extension once to get a private key.
2387 scoped_ptr
<ExtensionCreator
> creator(new ExtensionCreator());
2388 ASSERT_TRUE(creator
->Run(input_directory
, crx_path
, base::FilePath(),
2389 privkey_path
, ExtensionCreator::kNoRunFlags
))
2390 << creator
->error_message();
2391 ASSERT_TRUE(base::PathExists(crx_path
));
2392 ASSERT_TRUE(base::PathExists(privkey_path
));
2394 base::DeleteFile(crx_path
, false);
2395 // Move the pem file into the extension.
2396 base::Move(privkey_path
,
2397 input_directory
.AppendASCII("privkey.pem"));
2399 // This pack should fail because of the contained private key.
2400 EXPECT_FALSE(creator
->Run(input_directory
, crx_path
, base::FilePath(),
2401 privkey_path
, ExtensionCreator::kNoRunFlags
));
2402 EXPECT_THAT(creator
->error_message(),
2403 testing::ContainsRegex(
2404 "extension includes the key file.*privkey.pem"));
2407 // Test Packaging and installing an extension using an openssl generated key.
2408 // The openssl is generated with the following:
2409 // > openssl genrsa -out privkey.pem 1024
2410 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
2411 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
2412 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
2413 TEST_F(ExtensionServiceTest
, PackExtensionOpenSSLKey
) {
2414 InitializeEmptyExtensionService();
2415 base::FilePath input_directory
= data_dir_
2416 .AppendASCII("good")
2417 .AppendASCII("Extensions")
2418 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2419 .AppendASCII("1.0.0.0");
2420 base::FilePath
privkey_path(data_dir_
.AppendASCII(
2421 "openssl_privkey_asn1.pem"));
2422 ASSERT_TRUE(base::PathExists(privkey_path
));
2424 base::ScopedTempDir temp_dir
;
2425 ASSERT_TRUE(temp_dir
.CreateUniqueTempDir());
2426 base::FilePath output_directory
= temp_dir
.path();
2428 base::FilePath
crx_path(output_directory
.AppendASCII("ex1.crx"));
2430 scoped_ptr
<ExtensionCreator
> creator(new ExtensionCreator());
2431 ASSERT_TRUE(creator
->Run(input_directory
, crx_path
, privkey_path
,
2432 base::FilePath(), ExtensionCreator::kOverwriteCRX
));
2434 InstallCRX(crx_path
, INSTALL_NEW
);
2437 TEST_F(ExtensionServiceTest
, InstallTheme
) {
2438 InitializeEmptyExtensionService();
2442 base::FilePath path
= data_dir_
.AppendASCII("theme.crx");
2443 InstallCRX(path
, INSTALL_NEW
);
2445 ValidatePrefKeyCount(++pref_count
);
2446 ValidateIntegerPref(theme_crx
, "state", Extension::ENABLED
);
2447 ValidateIntegerPref(theme_crx
, "location", Manifest::INTERNAL
);
2449 // A theme when extensions are disabled. Themes can be installed, even when
2450 // extensions are disabled.
2451 set_extensions_enabled(false);
2452 path
= data_dir_
.AppendASCII("theme2.crx");
2453 InstallCRX(path
, INSTALL_NEW
);
2454 ValidatePrefKeyCount(++pref_count
);
2455 ValidateIntegerPref(theme2_crx
, "state", Extension::ENABLED
);
2456 ValidateIntegerPref(theme2_crx
, "location", Manifest::INTERNAL
);
2458 // A theme with extension elements. Themes cannot have extension elements,
2459 // so any such elements (like content scripts) should be ignored.
2460 set_extensions_enabled(true);
2462 path
= data_dir_
.AppendASCII("theme_with_extension.crx");
2463 const Extension
* extension
= InstallCRX(path
, INSTALL_NEW
);
2464 ValidatePrefKeyCount(++pref_count
);
2465 ASSERT_TRUE(extension
);
2466 EXPECT_TRUE(extension
->is_theme());
2469 extensions::ContentScriptsInfo::GetContentScripts(extension
).size());
2472 // A theme with image resources missing (misspelt path).
2473 path
= data_dir_
.AppendASCII("theme_missing_image.crx");
2474 InstallCRX(path
, INSTALL_FAILED
);
2475 ValidatePrefKeyCount(pref_count
);
2478 TEST_F(ExtensionServiceTest
, LoadLocalizedTheme
) {
2480 InitializeEmptyExtensionService();
2483 base::FilePath extension_path
= data_dir_
2484 .AppendASCII("theme_i18n");
2486 extensions::UnpackedInstaller::Create(service_
)->Load(extension_path
);
2487 base::RunLoop().RunUntilIdle();
2488 EXPECT_EQ(0u, GetErrors().size());
2489 ASSERT_EQ(1u, loaded_
.size());
2490 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
2491 const Extension
* theme
= registry_
->enabled_extensions().begin()->get();
2492 EXPECT_EQ("name", theme
->name());
2493 EXPECT_EQ("description", theme
->description());
2495 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a
2496 // temporary directory, but it automatically installs to the extension's
2497 // directory, and we don't want to copy the whole extension for a unittest.
2498 base::FilePath theme_file
= extension_path
.Append(chrome::kThemePackFilename
);
2499 ASSERT_TRUE(base::PathExists(theme_file
));
2500 ASSERT_TRUE(base::DeleteFile(theme_file
, false)); // Not recursive.
2503 // Tests that we can change the ID of an unpacked extension by adding a key
2505 TEST_F(ExtensionServiceTest
, UnpackedExtensionCanChangeID
) {
2506 InitializeEmptyExtensionService();
2508 base::ScopedTempDir temp
;
2509 ASSERT_TRUE(temp
.CreateUniqueTempDir());
2511 base::FilePath extension_path
= temp
.path();
2512 base::FilePath manifest_path
=
2513 extension_path
.Append(extensions::kManifestFilename
);
2514 base::FilePath manifest_no_key
= data_dir_
.
2515 AppendASCII("unpacked").
2516 AppendASCII("manifest_no_key.json");
2518 base::FilePath manifest_with_key
= data_dir_
.
2519 AppendASCII("unpacked").
2520 AppendASCII("manifest_with_key.json");
2522 ASSERT_TRUE(base::PathExists(manifest_no_key
));
2523 ASSERT_TRUE(base::PathExists(manifest_with_key
));
2525 // Load the unpacked extension with no key.
2526 base::CopyFile(manifest_no_key
, manifest_path
);
2527 extensions::UnpackedInstaller::Create(service_
)->Load(extension_path
);
2529 base::RunLoop().RunUntilIdle();
2530 EXPECT_EQ(0u, GetErrors().size());
2531 ASSERT_EQ(1u, loaded_
.size());
2532 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
2534 // Add the key to the manifest.
2535 base::CopyFile(manifest_with_key
, manifest_path
);
2538 // Reload the extensions.
2539 service_
->ReloadExtensionsForTest();
2540 const Extension
* extension
= service_
->GetExtensionById(unpacked
, false);
2541 EXPECT_EQ(unpacked
, extension
->id());
2542 ASSERT_EQ(1u, loaded_
.size());
2544 // TODO(jstritar): Right now this just makes sure we don't crash and burn, but
2545 // we should also test that preferences are preserved.
2548 #if defined(OS_POSIX)
2549 TEST_F(ExtensionServiceTest
, UnpackedExtensionMayContainSymlinkedFiles
) {
2550 base::FilePath source_data_dir
= data_dir_
.
2551 AppendASCII("unpacked").
2552 AppendASCII("symlinks_allowed");
2554 // Paths to test data files.
2555 base::FilePath source_manifest
= source_data_dir
.AppendASCII("manifest.json");
2556 ASSERT_TRUE(base::PathExists(source_manifest
));
2557 base::FilePath source_icon
= source_data_dir
.AppendASCII("icon.png");
2558 ASSERT_TRUE(base::PathExists(source_icon
));
2560 // Set up the temporary extension directory.
2561 base::ScopedTempDir temp
;
2562 ASSERT_TRUE(temp
.CreateUniqueTempDir());
2563 base::FilePath extension_path
= temp
.path();
2564 base::FilePath manifest
= extension_path
.Append(
2565 extensions::kManifestFilename
);
2566 base::FilePath icon_symlink
= extension_path
.AppendASCII("icon.png");
2567 base::CopyFile(source_manifest
, manifest
);
2568 base::CreateSymbolicLink(source_icon
, icon_symlink
);
2571 InitializeEmptyExtensionService();
2572 extensions::UnpackedInstaller::Create(service_
)->Load(extension_path
);
2573 base::RunLoop().RunUntilIdle();
2575 EXPECT_TRUE(GetErrors().empty());
2576 ASSERT_EQ(1u, loaded_
.size());
2577 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
2581 TEST_F(ExtensionServiceTest
, UnpackedExtensionMayNotHaveUnderscore
) {
2582 InitializeEmptyExtensionService();
2583 base::FilePath extension_path
= data_dir_
2584 .AppendASCII("underscore_name");
2585 extensions::UnpackedInstaller::Create(service_
)->Load(extension_path
);
2586 base::RunLoop().RunUntilIdle();
2587 EXPECT_EQ(1u, GetErrors().size());
2588 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
2591 TEST_F(ExtensionServiceTest
, InstallLocalizedTheme
) {
2592 InitializeEmptyExtensionService();
2595 base::FilePath theme_path
= data_dir_
2596 .AppendASCII("theme_i18n");
2598 const Extension
* theme
= PackAndInstallCRX(theme_path
, INSTALL_NEW
);
2600 EXPECT_EQ(0u, GetErrors().size());
2601 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
2602 EXPECT_EQ("name", theme
->name());
2603 EXPECT_EQ("description", theme
->description());
2606 TEST_F(ExtensionServiceTest
, InstallApps
) {
2607 InitializeEmptyExtensionService();
2610 const Extension
* app
= PackAndInstallCRX(data_dir_
.AppendASCII("app1"),
2613 ValidatePrefKeyCount(++pref_count
);
2614 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
2615 ValidateIntegerPref(app
->id(), "state", Extension::ENABLED
);
2616 ValidateIntegerPref(app
->id(), "location", Manifest::INTERNAL
);
2618 // Another app with non-overlapping extent. Should succeed.
2619 PackAndInstallCRX(data_dir_
.AppendASCII("app2"), INSTALL_NEW
);
2620 ValidatePrefKeyCount(++pref_count
);
2622 // A third app whose extent overlaps the first. Should fail.
2623 PackAndInstallCRX(data_dir_
.AppendASCII("app3"), INSTALL_FAILED
);
2624 ValidatePrefKeyCount(pref_count
);
2627 // Tests that file access is OFF by default.
2628 TEST_F(ExtensionServiceTest
, DefaultFileAccess
) {
2629 InitializeEmptyExtensionService();
2630 const Extension
* extension
=
2631 PackAndInstallCRX(data_dir_
2632 .AppendASCII("permissions")
2633 .AppendASCII("files"),
2635 EXPECT_EQ(0u, GetErrors().size());
2636 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
2637 EXPECT_FALSE(service_
->extension_prefs()->AllowFileAccess(extension
->id()));
2640 TEST_F(ExtensionServiceTest
, UpdateApps
) {
2641 InitializeEmptyExtensionService();
2642 base::FilePath extensions_path
= data_dir_
.AppendASCII("app_update");
2644 // First install v1 of a hosted app.
2645 const Extension
* extension
=
2646 InstallCRX(extensions_path
.AppendASCII("v1.crx"), INSTALL_NEW
);
2647 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
2648 std::string id
= extension
->id();
2649 ASSERT_EQ(std::string("1"), extension
->version()->GetString());
2651 // Now try updating to v2.
2653 extensions_path
.AppendASCII("v2.crx"),
2655 ASSERT_EQ(std::string("2"),
2656 service_
->GetExtensionById(id
, false)->version()->GetString());
2659 // Verifies that the NTP page and launch ordinals are kept when updating apps.
2660 TEST_F(ExtensionServiceTest
, UpdateAppsRetainOrdinals
) {
2661 InitializeEmptyExtensionService();
2662 AppSorting
* sorting
= service_
->extension_prefs()->app_sorting();
2663 base::FilePath extensions_path
= data_dir_
.AppendASCII("app_update");
2665 // First install v1 of a hosted app.
2666 const Extension
* extension
=
2667 InstallCRX(extensions_path
.AppendASCII("v1.crx"), INSTALL_NEW
);
2668 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
2669 std::string id
= extension
->id();
2670 ASSERT_EQ(std::string("1"), extension
->version()->GetString());
2672 // Modify the ordinals so we can distinguish them from the defaults.
2673 syncer::StringOrdinal new_page_ordinal
=
2674 sorting
->GetPageOrdinal(id
).CreateAfter();
2675 syncer::StringOrdinal new_launch_ordinal
=
2676 sorting
->GetAppLaunchOrdinal(id
).CreateBefore();
2678 sorting
->SetPageOrdinal(id
, new_page_ordinal
);
2679 sorting
->SetAppLaunchOrdinal(id
, new_launch_ordinal
);
2681 // Now try updating to v2.
2682 UpdateExtension(id
, extensions_path
.AppendASCII("v2.crx"), ENABLED
);
2683 ASSERT_EQ(std::string("2"),
2684 service_
->GetExtensionById(id
, false)->version()->GetString());
2686 // Verify that the ordinals match.
2687 ASSERT_TRUE(new_page_ordinal
.Equals(sorting
->GetPageOrdinal(id
)));
2688 ASSERT_TRUE(new_launch_ordinal
.Equals(sorting
->GetAppLaunchOrdinal(id
)));
2691 // Ensures that the CWS has properly initialized ordinals.
2692 TEST_F(ExtensionServiceTest
, EnsureCWSOrdinalsInitialized
) {
2693 InitializeEmptyExtensionService();
2694 service_
->component_loader()->Add(
2695 IDR_WEBSTORE_MANIFEST
, base::FilePath(FILE_PATH_LITERAL("web_store")));
2698 AppSorting
* sorting
= service_
->extension_prefs()->app_sorting();
2700 sorting
->GetPageOrdinal(extension_misc::kWebStoreAppId
).IsValid());
2702 sorting
->GetAppLaunchOrdinal(extension_misc::kWebStoreAppId
).IsValid());
2705 TEST_F(ExtensionServiceTest
, InstallAppsWithUnlimitedStorage
) {
2706 InitializeEmptyExtensionService();
2707 EXPECT_TRUE(registry_
->enabled_extensions().is_empty());
2711 // Install app1 with unlimited storage.
2712 const Extension
* extension
=
2713 PackAndInstallCRX(data_dir_
.AppendASCII("app1"), INSTALL_NEW
);
2714 ValidatePrefKeyCount(++pref_count
);
2715 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
2716 const std::string id1
= extension
->id();
2717 EXPECT_TRUE(extension
->HasAPIPermission(
2718 APIPermission::kUnlimitedStorage
));
2719 EXPECT_TRUE(extension
->web_extent().MatchesURL(
2720 extensions::AppLaunchInfo::GetFullLaunchURL(extension
)));
2722 extensions::AppLaunchInfo::GetFullLaunchURL(extension
).GetOrigin());
2723 EXPECT_TRUE(profile_
->GetExtensionSpecialStoragePolicy()->
2724 IsStorageUnlimited(origin1
));
2726 // Install app2 from the same origin with unlimited storage.
2727 extension
= PackAndInstallCRX(data_dir_
.AppendASCII("app2"), INSTALL_NEW
);
2728 ValidatePrefKeyCount(++pref_count
);
2729 ASSERT_EQ(2u, registry_
->enabled_extensions().size());
2730 const std::string id2
= extension
->id();
2731 EXPECT_TRUE(extension
->HasAPIPermission(
2732 APIPermission::kUnlimitedStorage
));
2733 EXPECT_TRUE(extension
->web_extent().MatchesURL(
2734 extensions::AppLaunchInfo::GetFullLaunchURL(extension
)));
2736 extensions::AppLaunchInfo::GetFullLaunchURL(extension
).GetOrigin());
2737 EXPECT_EQ(origin1
, origin2
);
2738 EXPECT_TRUE(profile_
->GetExtensionSpecialStoragePolicy()->
2739 IsStorageUnlimited(origin2
));
2742 // Uninstall one of them, unlimited storage should still be granted
2744 UninstallExtension(id1
, false);
2745 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
2746 EXPECT_TRUE(profile_
->GetExtensionSpecialStoragePolicy()->
2747 IsStorageUnlimited(origin1
));
2749 // Uninstall the other, unlimited storage should be revoked.
2750 UninstallExtension(id2
, false);
2751 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
2752 EXPECT_FALSE(profile_
->GetExtensionSpecialStoragePolicy()->
2753 IsStorageUnlimited(origin2
));
2756 TEST_F(ExtensionServiceTest
, InstallAppsAndCheckStorageProtection
) {
2757 InitializeEmptyExtensionService();
2758 EXPECT_TRUE(registry_
->enabled_extensions().is_empty());
2762 const Extension
* extension
=
2763 PackAndInstallCRX(data_dir_
.AppendASCII("app1"), INSTALL_NEW
);
2764 ValidatePrefKeyCount(++pref_count
);
2765 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
2766 EXPECT_TRUE(extension
->is_app());
2767 const std::string id1
= extension
->id();
2769 extensions::AppLaunchInfo::GetFullLaunchURL(extension
).GetOrigin());
2770 EXPECT_TRUE(profile_
->GetExtensionSpecialStoragePolicy()->
2771 IsStorageProtected(origin1
));
2773 // App 4 has a different origin (maps.google.com).
2774 extension
= PackAndInstallCRX(data_dir_
.AppendASCII("app4"), INSTALL_NEW
);
2775 ValidatePrefKeyCount(++pref_count
);
2776 ASSERT_EQ(2u, registry_
->enabled_extensions().size());
2777 const std::string id2
= extension
->id();
2779 extensions::AppLaunchInfo::GetFullLaunchURL(extension
).GetOrigin());
2780 ASSERT_NE(origin1
, origin2
);
2781 EXPECT_TRUE(profile_
->GetExtensionSpecialStoragePolicy()->
2782 IsStorageProtected(origin2
));
2784 UninstallExtension(id1
, false);
2785 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
2787 UninstallExtension(id2
, false);
2789 EXPECT_TRUE(registry_
->enabled_extensions().is_empty());
2790 EXPECT_FALSE(profile_
->GetExtensionSpecialStoragePolicy()->
2791 IsStorageProtected(origin1
));
2792 EXPECT_FALSE(profile_
->GetExtensionSpecialStoragePolicy()->
2793 IsStorageProtected(origin2
));
2796 // Test that when an extension version is reinstalled, nothing happens.
2797 TEST_F(ExtensionServiceTest
, Reinstall
) {
2798 InitializeEmptyExtensionService();
2800 // A simple extension that should install without error.
2801 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
2802 InstallCRX(path
, INSTALL_NEW
);
2804 ValidatePrefKeyCount(1);
2805 ValidateIntegerPref(good_crx
, "state", Extension::ENABLED
);
2806 ValidateIntegerPref(good_crx
, "location", Manifest::INTERNAL
);
2808 // Reinstall the same version, it should overwrite the previous one.
2809 InstallCRX(path
, INSTALL_UPDATED
);
2811 ValidatePrefKeyCount(1);
2812 ValidateIntegerPref(good_crx
, "state", Extension::ENABLED
);
2813 ValidateIntegerPref(good_crx
, "location", Manifest::INTERNAL
);
2816 // Test that we can determine if extensions came from the
2817 // Chrome web store.
2818 TEST_F(ExtensionServiceTest
, FromWebStore
) {
2819 InitializeEmptyExtensionService();
2821 // A simple extension that should install without error.
2822 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
2823 // Not from web store.
2824 const Extension
* extension
= InstallCRX(path
, INSTALL_NEW
);
2825 std::string id
= extension
->id();
2827 ValidatePrefKeyCount(1);
2828 ASSERT_TRUE(ValidateBooleanPref(good_crx
, "from_webstore", false));
2829 ASSERT_FALSE(extension
->from_webstore());
2831 // Test install from web store.
2832 InstallCRXFromWebStore(path
, INSTALL_UPDATED
); // From web store.
2834 ValidatePrefKeyCount(1);
2835 ASSERT_TRUE(ValidateBooleanPref(good_crx
, "from_webstore", true));
2837 // Reload so extension gets reinitialized with new value.
2838 service_
->ReloadExtensionsForTest();
2839 extension
= service_
->GetExtensionById(id
, false);
2840 ASSERT_TRUE(extension
->from_webstore());
2842 // Upgrade to version 2.0
2843 path
= data_dir_
.AppendASCII("good2.crx");
2844 UpdateExtension(good_crx
, path
, ENABLED
);
2845 ValidatePrefKeyCount(1);
2846 ASSERT_TRUE(ValidateBooleanPref(good_crx
, "from_webstore", true));
2849 // Test upgrading a signed extension.
2850 TEST_F(ExtensionServiceTest
, UpgradeSignedGood
) {
2851 InitializeEmptyExtensionService();
2853 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
2854 const Extension
* extension
= InstallCRX(path
, INSTALL_NEW
);
2855 std::string id
= extension
->id();
2857 ASSERT_EQ("1.0.0.0", extension
->version()->GetString());
2858 ASSERT_EQ(0u, GetErrors().size());
2860 // Upgrade to version 1.0.0.1.
2861 // Also test that the extension's old and new title are correctly retrieved.
2862 path
= data_dir_
.AppendASCII("good2.crx");
2863 InstallCRX(path
, INSTALL_UPDATED
, Extension::NO_FLAGS
, "My extension 1");
2864 extension
= service_
->GetExtensionById(id
, false);
2866 ASSERT_EQ("1.0.0.1", extension
->version()->GetString());
2867 ASSERT_EQ("My updated extension 1", extension
->name());
2868 ASSERT_EQ(0u, GetErrors().size());
2871 // Test upgrading a signed extension with a bad signature.
2872 TEST_F(ExtensionServiceTest
, UpgradeSignedBad
) {
2873 InitializeEmptyExtensionService();
2875 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
2876 InstallCRX(path
, INSTALL_NEW
);
2878 // Try upgrading with a bad signature. This should fail during the unpack,
2879 // because the key will not match the signature.
2880 path
= data_dir_
.AppendASCII("bad_signature.crx");
2881 InstallCRX(path
, INSTALL_FAILED
);
2884 // Test a normal update via the UpdateExtension API
2885 TEST_F(ExtensionServiceTest
, UpdateExtension
) {
2886 InitializeEmptyExtensionService();
2888 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
2890 const Extension
* good
= InstallCRX(path
, INSTALL_NEW
);
2891 ASSERT_EQ("1.0.0.0", good
->VersionString());
2892 ASSERT_EQ(good_crx
, good
->id());
2894 path
= data_dir_
.AppendASCII("good2.crx");
2895 UpdateExtension(good_crx
, path
, ENABLED
);
2896 ASSERT_EQ("1.0.0.1",
2897 service_
->GetExtensionById(good_crx
, false)->
2898 version()->GetString());
2901 // Extensions should not be updated during browser shutdown.
2902 TEST_F(ExtensionServiceTest
, UpdateExtensionDuringShutdown
) {
2903 InitializeEmptyExtensionService();
2905 // Install an extension.
2906 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
2907 const Extension
* good
= InstallCRX(path
, INSTALL_NEW
);
2908 ASSERT_EQ(good_crx
, good
->id());
2910 // Simulate shutdown.
2911 service_
->set_browser_terminating_for_test(true);
2913 // Update should fail and extension should not be updated.
2914 path
= data_dir_
.AppendASCII("good2.crx");
2915 bool updated
= service_
->UpdateExtension(good_crx
, path
, true, GURL(), NULL
);
2916 ASSERT_FALSE(updated
);
2917 ASSERT_EQ("1.0.0.0",
2918 service_
->GetExtensionById(good_crx
, false)->
2919 version()->GetString());
2922 // Test updating a not-already-installed extension - this should fail
2923 TEST_F(ExtensionServiceTest
, UpdateNotInstalledExtension
) {
2924 InitializeEmptyExtensionService();
2926 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
2927 UpdateExtension(good_crx
, path
, UPDATED
);
2928 base::RunLoop().RunUntilIdle();
2930 ASSERT_EQ(0u, registry_
->enabled_extensions().size());
2931 ASSERT_FALSE(installed_
);
2932 ASSERT_EQ(0u, loaded_
.size());
2935 // Makes sure you can't downgrade an extension via UpdateExtension
2936 TEST_F(ExtensionServiceTest
, UpdateWillNotDowngrade
) {
2937 InitializeEmptyExtensionService();
2939 base::FilePath path
= data_dir_
.AppendASCII("good2.crx");
2941 const Extension
* good
= InstallCRX(path
, INSTALL_NEW
);
2942 ASSERT_EQ("1.0.0.1", good
->VersionString());
2943 ASSERT_EQ(good_crx
, good
->id());
2945 // Change path from good2.crx -> good.crx
2946 path
= data_dir_
.AppendASCII("good.crx");
2947 UpdateExtension(good_crx
, path
, FAILED
);
2948 ASSERT_EQ("1.0.0.1",
2949 service_
->GetExtensionById(good_crx
, false)->
2950 version()->GetString());
2953 // Make sure calling update with an identical version does nothing
2954 TEST_F(ExtensionServiceTest
, UpdateToSameVersionIsNoop
) {
2955 InitializeEmptyExtensionService();
2957 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
2959 const Extension
* good
= InstallCRX(path
, INSTALL_NEW
);
2960 ASSERT_EQ(good_crx
, good
->id());
2961 UpdateExtension(good_crx
, path
, FAILED_SILENTLY
);
2964 // Tests that updating an extension does not clobber old state.
2965 TEST_F(ExtensionServiceTest
, UpdateExtensionPreservesState
) {
2966 InitializeEmptyExtensionService();
2968 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
2970 const Extension
* good
= InstallCRX(path
, INSTALL_NEW
);
2971 ASSERT_EQ("1.0.0.0", good
->VersionString());
2972 ASSERT_EQ(good_crx
, good
->id());
2974 // Disable it and allow it to run in incognito. These settings should carry
2975 // over to the updated version.
2976 service_
->DisableExtension(good
->id(), Extension::DISABLE_USER_ACTION
);
2977 extensions::util::SetIsIncognitoEnabled(good
->id(), profile_
.get(), true);
2978 service_
->extension_prefs()->SetDidExtensionEscalatePermissions(good
, true);
2980 path
= data_dir_
.AppendASCII("good2.crx");
2981 UpdateExtension(good_crx
, path
, INSTALLED
);
2982 ASSERT_EQ(1u, registry_
->disabled_extensions().size());
2983 const Extension
* good2
= service_
->GetExtensionById(good_crx
, true);
2984 ASSERT_EQ("1.0.0.1", good2
->version()->GetString());
2985 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(
2986 good2
->id(), profile_
.get()));
2987 EXPECT_TRUE(service_
->extension_prefs()->DidExtensionEscalatePermissions(
2991 // Tests that updating preserves extension location.
2992 TEST_F(ExtensionServiceTest
, UpdateExtensionPreservesLocation
) {
2993 InitializeEmptyExtensionService();
2995 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
2997 const Extension
* good
=
2998 InstallCRXWithLocation(path
, Manifest::EXTERNAL_PREF
, INSTALL_NEW
);
3000 ASSERT_EQ("1.0.0.0", good
->VersionString());
3001 ASSERT_EQ(good_crx
, good
->id());
3003 path
= data_dir_
.AppendASCII("good2.crx");
3004 UpdateExtension(good_crx
, path
, ENABLED
);
3005 const Extension
* good2
= service_
->GetExtensionById(good_crx
, false);
3006 ASSERT_EQ("1.0.0.1", good2
->version()->GetString());
3007 EXPECT_EQ(good2
->location(), Manifest::EXTERNAL_PREF
);
3010 // Makes sure that LOAD extension types can downgrade.
3011 TEST_F(ExtensionServiceTest
, LoadExtensionsCanDowngrade
) {
3012 InitializeEmptyExtensionService();
3014 base::ScopedTempDir temp
;
3015 ASSERT_TRUE(temp
.CreateUniqueTempDir());
3017 // We'll write the extension manifest dynamically to a temporary path
3018 // to make it easier to change the version number.
3019 base::FilePath extension_path
= temp
.path();
3020 base::FilePath manifest_path
=
3021 extension_path
.Append(extensions::kManifestFilename
);
3022 ASSERT_FALSE(base::PathExists(manifest_path
));
3024 // Start with version 2.0.
3025 base::DictionaryValue manifest
;
3026 manifest
.SetString("version", "2.0");
3027 manifest
.SetString("name", "LOAD Downgrade Test");
3028 manifest
.SetInteger("manifest_version", 2);
3030 JSONFileValueSerializer
serializer(manifest_path
);
3031 ASSERT_TRUE(serializer
.Serialize(manifest
));
3033 extensions::UnpackedInstaller::Create(service_
)->Load(extension_path
);
3034 base::RunLoop().RunUntilIdle();
3036 EXPECT_EQ(0u, GetErrors().size());
3037 ASSERT_EQ(1u, loaded_
.size());
3038 EXPECT_EQ(Manifest::UNPACKED
, loaded_
[0]->location());
3039 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3040 EXPECT_EQ("2.0", loaded_
[0]->VersionString());
3042 // Now set the version number to 1.0, reload the extensions and verify that
3043 // the downgrade was accepted.
3044 manifest
.SetString("version", "1.0");
3045 ASSERT_TRUE(serializer
.Serialize(manifest
));
3047 extensions::UnpackedInstaller::Create(service_
)->Load(extension_path
);
3048 base::RunLoop().RunUntilIdle();
3050 EXPECT_EQ(0u, GetErrors().size());
3051 ASSERT_EQ(1u, loaded_
.size());
3052 EXPECT_EQ(Manifest::UNPACKED
, loaded_
[0]->location());
3053 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3054 EXPECT_EQ("1.0", loaded_
[0]->VersionString());
3057 #if !defined(OS_CHROMEOS)
3058 // LOAD extensions with plugins require approval.
3059 TEST_F(ExtensionServiceTest
, LoadExtensionsWithPlugins
) {
3060 base::FilePath extension_with_plugin_path
= good1_path();
3061 base::FilePath extension_no_plugin_path
= good2_path();
3063 InitPluginService();
3064 InitializeEmptyExtensionService();
3065 InitializeProcessManager();
3066 service_
->set_show_extensions_prompts(true);
3068 // Start by canceling any install prompts.
3069 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
3070 switches::kAppsGalleryInstallAutoConfirmForTests
,
3073 // The extension that has a plugin should not install.
3074 extensions::UnpackedInstaller::Create(service_
)->Load(
3075 extension_with_plugin_path
);
3076 base::RunLoop().RunUntilIdle();
3077 EXPECT_EQ(0u, GetErrors().size());
3078 EXPECT_EQ(0u, loaded_
.size());
3079 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
3080 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
3082 // But the extension with no plugin should since there's no prompt.
3083 ExtensionErrorReporter::GetInstance()->ClearErrors();
3084 extensions::UnpackedInstaller::Create(service_
)->Load(
3085 extension_no_plugin_path
);
3086 base::RunLoop().RunUntilIdle();
3087 EXPECT_EQ(0u, GetErrors().size());
3088 EXPECT_EQ(1u, loaded_
.size());
3089 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3090 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
3091 EXPECT_TRUE(registry_
->enabled_extensions().Contains(good2
));
3093 // The plugin extension should install if we accept the dialog.
3094 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
3095 switches::kAppsGalleryInstallAutoConfirmForTests
,
3098 ExtensionErrorReporter::GetInstance()->ClearErrors();
3099 extensions::UnpackedInstaller::Create(service_
)->Load(
3100 extension_with_plugin_path
);
3101 base::RunLoop().RunUntilIdle();
3102 EXPECT_EQ(0u, GetErrors().size());
3103 EXPECT_EQ(2u, loaded_
.size());
3104 EXPECT_EQ(2u, registry_
->enabled_extensions().size());
3105 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
3106 EXPECT_TRUE(registry_
->enabled_extensions().Contains(good1
));
3107 EXPECT_TRUE(registry_
->enabled_extensions().Contains(good2
));
3109 // Make sure the granted permissions have been setup.
3110 scoped_refptr
<PermissionSet
> permissions(
3111 service_
->extension_prefs()->GetGrantedPermissions(good1
));
3112 EXPECT_FALSE(permissions
->IsEmpty());
3113 EXPECT_TRUE(permissions
->HasEffectiveFullAccess());
3114 EXPECT_FALSE(permissions
->apis().empty());
3115 EXPECT_TRUE(permissions
->HasAPIPermission(APIPermission::kPlugin
));
3117 // We should be able to reload the extension without getting another prompt.
3119 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
3120 switches::kAppsGalleryInstallAutoConfirmForTests
,
3123 service_
->ReloadExtension(good1
);
3124 base::RunLoop().RunUntilIdle();
3125 EXPECT_EQ(1u, loaded_
.size());
3126 EXPECT_EQ(2u, registry_
->enabled_extensions().size());
3127 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
3129 #endif // !defined(OS_CHROMEOS)
3133 bool IsExtension(const Extension
* extension
) {
3134 return extension
->GetType() == Manifest::TYPE_EXTENSION
;
3139 // Test adding a pending extension.
3140 TEST_F(ExtensionServiceTest
, AddPendingExtensionFromSync
) {
3141 InitializeEmptyExtensionService();
3143 const std::string
kFakeId(all_zero
);
3144 const GURL
kFakeUpdateURL("http:://fake.update/url");
3145 const bool kFakeInstallSilently(true);
3147 EXPECT_TRUE(service_
->pending_extension_manager()->AddFromSync(
3148 kFakeId
, kFakeUpdateURL
, &IsExtension
,
3149 kFakeInstallSilently
));
3151 const extensions::PendingExtensionInfo
* pending_extension_info
;
3152 ASSERT_TRUE((pending_extension_info
= service_
->pending_extension_manager()->
3154 EXPECT_EQ(kFakeUpdateURL
, pending_extension_info
->update_url());
3155 EXPECT_EQ(&IsExtension
, pending_extension_info
->should_allow_install_
);
3156 EXPECT_EQ(kFakeInstallSilently
, pending_extension_info
->install_silently());
3160 const char kGoodId
[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
3161 const char kGoodUpdateURL
[] = "http://good.update/url";
3162 const bool kGoodIsFromSync
= true;
3163 const bool kGoodInstallSilently
= true;
3166 // Test updating a pending extension.
3167 TEST_F(ExtensionServiceTest
, UpdatePendingExtension
) {
3168 InitializeEmptyExtensionService();
3169 EXPECT_TRUE(service_
->pending_extension_manager()->AddFromSync(
3170 kGoodId
, GURL(kGoodUpdateURL
), &IsExtension
,
3171 kGoodInstallSilently
));
3172 EXPECT_TRUE(service_
->pending_extension_manager()->IsIdPending(kGoodId
));
3174 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
3175 UpdateExtension(kGoodId
, path
, ENABLED
);
3177 EXPECT_FALSE(service_
->pending_extension_manager()->IsIdPending(kGoodId
));
3179 const Extension
* extension
= service_
->GetExtensionById(kGoodId
, true);
3180 ASSERT_TRUE(extension
);
3185 bool IsTheme(const Extension
* extension
) {
3186 return extension
->is_theme();
3191 // Test updating a pending theme.
3192 // Disabled due to ASAN failure. http://crbug.com/108320
3193 TEST_F(ExtensionServiceTest
, DISABLED_UpdatePendingTheme
) {
3194 InitializeEmptyExtensionService();
3195 EXPECT_TRUE(service_
->pending_extension_manager()->AddFromSync(
3196 theme_crx
, GURL(), &IsTheme
, false));
3197 EXPECT_TRUE(service_
->pending_extension_manager()->IsIdPending(theme_crx
));
3199 base::FilePath path
= data_dir_
.AppendASCII("theme.crx");
3200 UpdateExtension(theme_crx
, path
, ENABLED
);
3202 EXPECT_FALSE(service_
->pending_extension_manager()->IsIdPending(theme_crx
));
3204 const Extension
* extension
= service_
->GetExtensionById(theme_crx
, true);
3205 ASSERT_TRUE(extension
);
3208 service_
->extension_prefs()->IsExtensionDisabled(extension
->id()));
3209 EXPECT_TRUE(service_
->IsExtensionEnabled(theme_crx
));
3212 #if defined(OS_CHROMEOS)
3213 // Always fails on ChromeOS: http://crbug.com/79737
3214 #define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
3216 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
3218 // Test updating a pending CRX as if the source is an external extension
3219 // with an update URL. In this case we don't know if the CRX is a theme
3221 TEST_F(ExtensionServiceTest
, MAYBE_UpdatePendingExternalCrx
) {
3222 InitializeEmptyExtensionService();
3223 EXPECT_TRUE(service_
->pending_extension_manager()->AddFromExternalUpdateUrl(
3224 theme_crx
, GURL(), Manifest::EXTERNAL_PREF_DOWNLOAD
, Extension::NO_FLAGS
,
3227 EXPECT_TRUE(service_
->pending_extension_manager()->IsIdPending(theme_crx
));
3229 base::FilePath path
= data_dir_
.AppendASCII("theme.crx");
3230 UpdateExtension(theme_crx
, path
, ENABLED
);
3232 EXPECT_FALSE(service_
->pending_extension_manager()->IsIdPending(theme_crx
));
3234 const Extension
* extension
= service_
->GetExtensionById(theme_crx
, true);
3235 ASSERT_TRUE(extension
);
3238 service_
->extension_prefs()->IsExtensionDisabled(extension
->id()));
3239 EXPECT_TRUE(service_
->IsExtensionEnabled(extension
->id()));
3240 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(extension
->id(),
3244 // Test updating a pending CRX as if the source is an external extension
3245 // with an update URL. The external update should overwrite a sync update,
3246 // but a sync update should not overwrite a non-sync update.
3247 TEST_F(ExtensionServiceTest
, UpdatePendingExternalCrxWinsOverSync
) {
3248 InitializeEmptyExtensionService();
3250 // Add a crx to be installed from the update mechanism.
3251 EXPECT_TRUE(service_
->pending_extension_manager()->AddFromSync(
3252 kGoodId
, GURL(kGoodUpdateURL
), &IsExtension
,
3253 kGoodInstallSilently
));
3255 // Check that there is a pending crx, with is_from_sync set to true.
3256 const extensions::PendingExtensionInfo
* pending_extension_info
;
3257 ASSERT_TRUE((pending_extension_info
= service_
->pending_extension_manager()->
3259 EXPECT_TRUE(pending_extension_info
->is_from_sync());
3261 // Add a crx to be updated, with the same ID, from a non-sync source.
3262 EXPECT_TRUE(service_
->pending_extension_manager()->AddFromExternalUpdateUrl(
3263 kGoodId
, GURL(kGoodUpdateURL
), Manifest::EXTERNAL_PREF_DOWNLOAD
,
3264 Extension::NO_FLAGS
, false));
3266 // Check that there is a pending crx, with is_from_sync set to false.
3267 ASSERT_TRUE((pending_extension_info
= service_
->pending_extension_manager()->
3269 EXPECT_FALSE(pending_extension_info
->is_from_sync());
3270 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD
,
3271 pending_extension_info
->install_source());
3273 // Add a crx to be installed from the update mechanism.
3274 EXPECT_FALSE(service_
->pending_extension_manager()->AddFromSync(
3275 kGoodId
, GURL(kGoodUpdateURL
), &IsExtension
,
3276 kGoodInstallSilently
));
3278 // Check that the external, non-sync update was not overridden.
3279 ASSERT_TRUE((pending_extension_info
= service_
->pending_extension_manager()->
3281 EXPECT_FALSE(pending_extension_info
->is_from_sync());
3282 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD
,
3283 pending_extension_info
->install_source());
3286 // Updating a theme should fail if the updater is explicitly told that
3287 // the CRX is not a theme.
3288 TEST_F(ExtensionServiceTest
, UpdatePendingCrxThemeMismatch
) {
3289 InitializeEmptyExtensionService();
3290 EXPECT_TRUE(service_
->pending_extension_manager()->AddFromSync(
3291 theme_crx
, GURL(), &IsExtension
, true));
3293 EXPECT_TRUE(service_
->pending_extension_manager()->IsIdPending(theme_crx
));
3295 base::FilePath path
= data_dir_
.AppendASCII("theme.crx");
3296 UpdateExtension(theme_crx
, path
, FAILED_SILENTLY
);
3298 EXPECT_FALSE(service_
->pending_extension_manager()->IsIdPending(theme_crx
));
3300 const Extension
* extension
= service_
->GetExtensionById(theme_crx
, true);
3301 ASSERT_FALSE(extension
);
3304 // TODO(akalin): Test updating a pending extension non-silently once
3305 // we can mock out ExtensionInstallUI and inject our version into
3306 // UpdateExtension().
3308 // Test updating a pending extension which fails the should-install test.
3309 TEST_F(ExtensionServiceTest
, UpdatePendingExtensionFailedShouldInstallTest
) {
3310 InitializeEmptyExtensionService();
3311 // Add pending extension with a flipped is_theme.
3312 EXPECT_TRUE(service_
->pending_extension_manager()->AddFromSync(
3313 kGoodId
, GURL(kGoodUpdateURL
), &IsTheme
, kGoodInstallSilently
));
3314 EXPECT_TRUE(service_
->pending_extension_manager()->IsIdPending(kGoodId
));
3316 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
3317 UpdateExtension(kGoodId
, path
, UPDATED
);
3319 // TODO(akalin): Figure out how to check that the extensions
3320 // directory is cleaned up properly in OnExtensionInstalled().
3322 EXPECT_FALSE(service_
->pending_extension_manager()->IsIdPending(kGoodId
));
3325 // TODO(akalin): Figure out how to test that installs of pending
3326 // unsyncable extensions are blocked.
3328 // Test updating a pending extension for one that is not pending.
3329 TEST_F(ExtensionServiceTest
, UpdatePendingExtensionNotPending
) {
3330 InitializeEmptyExtensionService();
3332 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
3333 UpdateExtension(kGoodId
, path
, UPDATED
);
3335 EXPECT_FALSE(service_
->pending_extension_manager()->IsIdPending(kGoodId
));
3338 // Test updating a pending extension for one that is already
3340 TEST_F(ExtensionServiceTest
, UpdatePendingExtensionAlreadyInstalled
) {
3341 InitializeEmptyExtensionService();
3343 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
3344 const Extension
* good
= InstallCRX(path
, INSTALL_NEW
);
3345 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
3347 EXPECT_FALSE(good
->is_theme());
3349 // Use AddExtensionImpl() as AddFrom*() would balk.
3350 service_
->pending_extension_manager()->AddExtensionImpl(
3351 good
->id(), extensions::ManifestURL::GetUpdateURL(good
),
3352 Version(), &IsExtension
, kGoodIsFromSync
,
3353 kGoodInstallSilently
, Manifest::INTERNAL
,
3354 Extension::NO_FLAGS
, false);
3355 UpdateExtension(good
->id(), path
, ENABLED
);
3357 EXPECT_FALSE(service_
->pending_extension_manager()->IsIdPending(kGoodId
));
3360 #if defined(ENABLE_BLACKLIST_TESTS)
3361 // Tests blacklisting then unblacklisting extensions after the service has been
3363 TEST_F(ExtensionServiceTest
, SetUnsetBlacklistInPrefs
) {
3364 extensions::TestBlacklist test_blacklist
;
3365 // A profile with 3 extensions installed: good0, good1, and good2.
3366 InitializeGoodInstalledExtensionService();
3367 test_blacklist
.Attach(service_
->blacklist_
);
3370 const extensions::ExtensionSet
& enabled_extensions
=
3371 registry_
->enabled_extensions();
3372 const extensions::ExtensionSet
& blacklisted_extensions
=
3373 registry_
->blacklisted_extensions();
3375 EXPECT_TRUE(enabled_extensions
.Contains(good0
) &&
3376 !blacklisted_extensions
.Contains(good0
));
3377 EXPECT_TRUE(enabled_extensions
.Contains(good1
) &&
3378 !blacklisted_extensions
.Contains(good1
));
3379 EXPECT_TRUE(enabled_extensions
.Contains(good2
) &&
3380 !blacklisted_extensions
.Contains(good2
));
3382 EXPECT_FALSE(IsPrefExist(good0
, "blacklist"));
3383 EXPECT_FALSE(IsPrefExist(good1
, "blacklist"));
3384 EXPECT_FALSE(IsPrefExist(good2
, "blacklist"));
3385 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3387 // Blacklist good0 and good1 (and an invalid extension ID).
3388 test_blacklist
.SetBlacklistState(
3389 good0
, extensions::BLACKLISTED_MALWARE
, true);
3390 test_blacklist
.SetBlacklistState(
3391 good1
, extensions::BLACKLISTED_MALWARE
, true);
3392 test_blacklist
.SetBlacklistState(
3393 "invalid_id", extensions::BLACKLISTED_MALWARE
, true);
3394 base::RunLoop().RunUntilIdle();
3396 EXPECT_TRUE(!enabled_extensions
.Contains(good0
) &&
3397 blacklisted_extensions
.Contains(good0
));
3398 EXPECT_TRUE(!enabled_extensions
.Contains(good1
) &&
3399 blacklisted_extensions
.Contains(good1
));
3400 EXPECT_TRUE(enabled_extensions
.Contains(good2
) &&
3401 !blacklisted_extensions
.Contains(good2
));
3403 EXPECT_TRUE(ValidateBooleanPref(good0
, "blacklist", true));
3404 EXPECT_TRUE(ValidateBooleanPref(good1
, "blacklist", true));
3405 EXPECT_FALSE(IsPrefExist(good2
, "blacklist"));
3406 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3408 // Un-blacklist good1 and blacklist good2.
3409 test_blacklist
.Clear(false);
3410 test_blacklist
.SetBlacklistState(
3411 good0
, extensions::BLACKLISTED_MALWARE
, true);
3412 test_blacklist
.SetBlacklistState(
3413 good2
, extensions::BLACKLISTED_MALWARE
, true);
3414 test_blacklist
.SetBlacklistState(
3415 "invalid_id", extensions::BLACKLISTED_MALWARE
, true);
3416 base::RunLoop().RunUntilIdle();
3418 EXPECT_TRUE(!enabled_extensions
.Contains(good0
) &&
3419 blacklisted_extensions
.Contains(good0
));
3420 EXPECT_TRUE(enabled_extensions
.Contains(good1
) &&
3421 !blacklisted_extensions
.Contains(good1
));
3422 EXPECT_TRUE(!enabled_extensions
.Contains(good2
) &&
3423 blacklisted_extensions
.Contains(good2
));
3425 EXPECT_TRUE(ValidateBooleanPref(good0
, "blacklist", true));
3426 EXPECT_FALSE(IsPrefExist(good1
, "blacklist"));
3427 EXPECT_TRUE(ValidateBooleanPref(good2
, "blacklist", true));
3428 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3430 #endif // defined(ENABLE_BLACKLIST_TESTS)
3432 #if defined(ENABLE_BLACKLIST_TESTS)
3433 // Tests trying to install a blacklisted extension.
3434 TEST_F(ExtensionServiceTest
, BlacklistedExtensionWillNotInstall
) {
3435 scoped_refptr
<FakeSafeBrowsingDatabaseManager
> blacklist_db(
3436 new FakeSafeBrowsingDatabaseManager(true));
3437 Blacklist::ScopedDatabaseManagerForTest
scoped_blacklist_db(blacklist_db
);
3439 InitializeEmptyExtensionService();
3442 // After blacklisting good_crx, we cannot install it.
3443 blacklist_db
->SetUnsafe(good_crx
).NotifyUpdate();
3444 base::RunLoop().RunUntilIdle();
3446 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
3447 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3448 // decide to install this silently. Somebody should fix these tests, all
3449 // 6,000 lines of them. Hah!
3450 InstallCRX(path
, INSTALL_FAILED
, Extension::WAS_INSTALLED_BY_DEFAULT
);
3451 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
3453 #endif // defined(ENABLE_BLACKLIST_TESTS)
3455 #if defined(ENABLE_BLACKLIST_TESTS)
3456 // Unload blacklisted extension on policy change.
3457 TEST_F(ExtensionServiceTest
, UnloadBlacklistedExtensionPolicy
) {
3458 extensions::TestBlacklist test_blacklist
;
3460 // A profile with no extensions installed.
3461 InitializeEmptyExtensionService();
3462 test_blacklist
.Attach(service_
->blacklist_
);
3464 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
3466 const Extension
* good
= InstallCRX(path
, INSTALL_NEW
);
3467 EXPECT_EQ(good_crx
, good
->id());
3468 UpdateExtension(good_crx
, path
, FAILED_SILENTLY
);
3469 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3471 base::ListValue whitelist
;
3472 PrefService
* prefs
= service_
->extension_prefs()->pref_service();
3473 whitelist
.Append(new base::StringValue(good_crx
));
3474 prefs
->Set(extensions::pref_names::kInstallAllowList
, whitelist
);
3476 test_blacklist
.SetBlacklistState(
3477 good_crx
, extensions::BLACKLISTED_MALWARE
, true);
3478 base::RunLoop().RunUntilIdle();
3480 // The good_crx is blacklisted and the whitelist doesn't negate it.
3481 ASSERT_TRUE(ValidateBooleanPref(good_crx
, "blacklist", true));
3482 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
3484 #endif // defined(ENABLE_BLACKLIST_TESTS)
3486 #if defined(ENABLE_BLACKLIST_TESTS)
3487 // Tests that a blacklisted extension is eventually unloaded on startup, if it
3489 TEST_F(ExtensionServiceTest
, WillNotLoadBlacklistedExtensionsFromDirectory
) {
3490 extensions::TestBlacklist test_blacklist
;
3492 // A profile with 3 extensions installed: good0, good1, and good2.
3493 InitializeGoodInstalledExtensionService();
3494 test_blacklist
.Attach(service_
->blacklist_
);
3496 // Blacklist good1 before the service initializes.
3497 test_blacklist
.SetBlacklistState(
3498 good1
, extensions::BLACKLISTED_MALWARE
, false);
3502 ASSERT_EQ(3u, loaded_
.size()); // hasn't had time to blacklist yet
3504 base::RunLoop().RunUntilIdle();
3506 ASSERT_EQ(1u, registry_
->blacklisted_extensions().size());
3507 ASSERT_EQ(2u, registry_
->enabled_extensions().size());
3509 ASSERT_TRUE(registry_
->enabled_extensions().Contains(good0
));
3510 ASSERT_TRUE(registry_
->blacklisted_extensions().Contains(good1
));
3511 ASSERT_TRUE(registry_
->enabled_extensions().Contains(good2
));
3513 #endif // defined(ENABLE_BLACKLIST_TESTS)
3515 #if defined(ENABLE_BLACKLIST_TESTS)
3516 // Tests extensions blacklisted in prefs on startup; one still blacklisted by
3517 // safe browsing, the other not. The not-blacklisted one should recover.
3518 TEST_F(ExtensionServiceTest
, BlacklistedInPrefsFromStartup
) {
3519 extensions::TestBlacklist test_blacklist
;
3521 InitializeGoodInstalledExtensionService();
3522 test_blacklist
.Attach(service_
->blacklist_
);
3523 service_
->extension_prefs()->SetExtensionBlacklisted(good0
, true);
3524 service_
->extension_prefs()->SetExtensionBlacklisted(good1
, true);
3526 test_blacklist
.SetBlacklistState(
3527 good1
, extensions::BLACKLISTED_MALWARE
, false);
3531 ASSERT_EQ(2u, registry_
->blacklisted_extensions().size());
3532 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
3534 ASSERT_TRUE(registry_
->blacklisted_extensions().Contains(good0
));
3535 ASSERT_TRUE(registry_
->blacklisted_extensions().Contains(good1
));
3536 ASSERT_TRUE(registry_
->enabled_extensions().Contains(good2
));
3538 // Give time for the blacklist to update.
3539 base::RunLoop().RunUntilIdle();
3541 ASSERT_EQ(1u, registry_
->blacklisted_extensions().size());
3542 ASSERT_EQ(2u, registry_
->enabled_extensions().size());
3544 ASSERT_TRUE(registry_
->enabled_extensions().Contains(good0
));
3545 ASSERT_TRUE(registry_
->blacklisted_extensions().Contains(good1
));
3546 ASSERT_TRUE(registry_
->enabled_extensions().Contains(good2
));
3548 #endif // defined(ENABLE_BLACKLIST_TESTS)
3550 #if defined(ENABLE_BLACKLIST_TESTS)
3551 // Extension is added to blacklist with BLACKLISTED_POTENTIALLY_UNWANTED state
3552 // after it is installed. It is then successfully re-enabled by the user.
3553 TEST_F(ExtensionServiceTest
, GreylistedExtensionDisabled
) {
3554 extensions::TestBlacklist test_blacklist
;
3555 // A profile with 3 extensions installed: good0, good1, and good2.
3556 InitializeGoodInstalledExtensionService();
3557 test_blacklist
.Attach(service_
->blacklist_
);
3560 const extensions::ExtensionSet
& enabled_extensions
=
3561 registry_
->enabled_extensions();
3562 const extensions::ExtensionSet
& disabled_extensions
=
3563 registry_
->disabled_extensions();
3565 EXPECT_TRUE(enabled_extensions
.Contains(good0
));
3566 EXPECT_TRUE(enabled_extensions
.Contains(good1
));
3567 EXPECT_TRUE(enabled_extensions
.Contains(good2
));
3569 // Blacklist good0 and good1 (and an invalid extension ID).
3570 test_blacklist
.SetBlacklistState(
3571 good0
, extensions::BLACKLISTED_CWS_POLICY_VIOLATION
, true);
3572 test_blacklist
.SetBlacklistState(
3573 good1
, extensions::BLACKLISTED_POTENTIALLY_UNWANTED
, true);
3574 test_blacklist
.SetBlacklistState(
3575 "invalid_id", extensions::BLACKLISTED_MALWARE
, true);
3576 base::RunLoop().RunUntilIdle();
3578 EXPECT_FALSE(enabled_extensions
.Contains(good0
));
3579 EXPECT_TRUE(disabled_extensions
.Contains(good0
));
3580 EXPECT_FALSE(enabled_extensions
.Contains(good1
));
3581 EXPECT_TRUE(disabled_extensions
.Contains(good1
));
3582 EXPECT_TRUE(enabled_extensions
.Contains(good2
));
3583 EXPECT_FALSE(disabled_extensions
.Contains(good2
));
3585 ValidateIntegerPref(
3586 good0
, "blacklist_state", extensions::BLACKLISTED_CWS_POLICY_VIOLATION
);
3587 ValidateIntegerPref(
3588 good1
, "blacklist_state", extensions::BLACKLISTED_POTENTIALLY_UNWANTED
);
3590 // Now user enables good0.
3591 service_
->EnableExtension(good0
);
3593 EXPECT_TRUE(enabled_extensions
.Contains(good0
));
3594 EXPECT_FALSE(disabled_extensions
.Contains(good0
));
3595 EXPECT_FALSE(enabled_extensions
.Contains(good1
));
3596 EXPECT_TRUE(disabled_extensions
.Contains(good1
));
3598 // Remove extensions from blacklist.
3599 test_blacklist
.SetBlacklistState(
3600 good0
, extensions::NOT_BLACKLISTED
, true);
3601 test_blacklist
.SetBlacklistState(
3602 good1
, extensions::NOT_BLACKLISTED
, true);
3603 base::RunLoop().RunUntilIdle();
3605 // All extensions are enabled.
3606 EXPECT_TRUE(enabled_extensions
.Contains(good0
));
3607 EXPECT_FALSE(disabled_extensions
.Contains(good0
));
3608 EXPECT_TRUE(enabled_extensions
.Contains(good1
));
3609 EXPECT_FALSE(disabled_extensions
.Contains(good1
));
3610 EXPECT_TRUE(enabled_extensions
.Contains(good2
));
3611 EXPECT_FALSE(disabled_extensions
.Contains(good2
));
3613 #endif // defined(ENABLE_BLACKLIST_TESTS)
3615 #if defined(ENABLE_BLACKLIST_TESTS)
3616 // When extension is removed from greylist, do not re-enable it if it is
3617 // disabled by user.
3618 TEST_F(ExtensionServiceTest
, GreylistDontEnableManuallyDisabled
) {
3619 extensions::TestBlacklist test_blacklist
;
3620 // A profile with 3 extensions installed: good0, good1, and good2.
3621 InitializeGoodInstalledExtensionService();
3622 test_blacklist
.Attach(service_
->blacklist_
);
3625 const extensions::ExtensionSet
& enabled_extensions
=
3626 registry_
->enabled_extensions();
3627 const extensions::ExtensionSet
& disabled_extensions
=
3628 registry_
->disabled_extensions();
3630 // Manually disable.
3631 service_
->DisableExtension(good0
, extensions::Extension::DISABLE_USER_ACTION
);
3633 test_blacklist
.SetBlacklistState(
3634 good0
, extensions::BLACKLISTED_CWS_POLICY_VIOLATION
, true);
3635 test_blacklist
.SetBlacklistState(
3636 good1
, extensions::BLACKLISTED_POTENTIALLY_UNWANTED
, true);
3637 test_blacklist
.SetBlacklistState(
3638 good2
, extensions::BLACKLISTED_SECURITY_VULNERABILITY
, true);
3639 base::RunLoop().RunUntilIdle();
3641 // All extensions disabled.
3642 EXPECT_FALSE(enabled_extensions
.Contains(good0
));
3643 EXPECT_TRUE(disabled_extensions
.Contains(good0
));
3644 EXPECT_FALSE(enabled_extensions
.Contains(good1
));
3645 EXPECT_TRUE(disabled_extensions
.Contains(good1
));
3646 EXPECT_FALSE(enabled_extensions
.Contains(good2
));
3647 EXPECT_TRUE(disabled_extensions
.Contains(good2
));
3649 // Greylisted extension can be enabled.
3650 service_
->EnableExtension(good1
);
3651 EXPECT_TRUE(enabled_extensions
.Contains(good1
));
3652 EXPECT_FALSE(disabled_extensions
.Contains(good1
));
3654 // good1 is now manually disabled.
3655 service_
->DisableExtension(good1
, extensions::Extension::DISABLE_USER_ACTION
);
3656 EXPECT_FALSE(enabled_extensions
.Contains(good1
));
3657 EXPECT_TRUE(disabled_extensions
.Contains(good1
));
3659 // Remove extensions from blacklist.
3660 test_blacklist
.SetBlacklistState(
3661 good0
, extensions::NOT_BLACKLISTED
, true);
3662 test_blacklist
.SetBlacklistState(
3663 good1
, extensions::NOT_BLACKLISTED
, true);
3664 test_blacklist
.SetBlacklistState(
3665 good2
, extensions::NOT_BLACKLISTED
, true);
3666 base::RunLoop().RunUntilIdle();
3668 // good0 and good1 remain disabled.
3669 EXPECT_FALSE(enabled_extensions
.Contains(good0
));
3670 EXPECT_TRUE(disabled_extensions
.Contains(good0
));
3671 EXPECT_FALSE(enabled_extensions
.Contains(good1
));
3672 EXPECT_TRUE(disabled_extensions
.Contains(good1
));
3673 EXPECT_TRUE(enabled_extensions
.Contains(good2
));
3674 EXPECT_FALSE(disabled_extensions
.Contains(good2
));
3676 #endif // defined(ENABLE_BLACKLIST_TESTS)
3678 #if defined(ENABLE_BLACKLIST_TESTS)
3679 // Blacklisted extension with unknown state are not enabled/disabled.
3680 TEST_F(ExtensionServiceTest
, GreylistUnknownDontChange
) {
3681 extensions::TestBlacklist test_blacklist
;
3682 // A profile with 3 extensions installed: good0, good1, and good2.
3683 InitializeGoodInstalledExtensionService();
3684 test_blacklist
.Attach(service_
->blacklist_
);
3687 const extensions::ExtensionSet
& enabled_extensions
=
3688 registry_
->enabled_extensions();
3689 const extensions::ExtensionSet
& disabled_extensions
=
3690 registry_
->disabled_extensions();
3692 test_blacklist
.SetBlacklistState(
3693 good0
, extensions::BLACKLISTED_CWS_POLICY_VIOLATION
, true);
3694 test_blacklist
.SetBlacklistState(
3695 good1
, extensions::BLACKLISTED_POTENTIALLY_UNWANTED
, true);
3696 base::RunLoop().RunUntilIdle();
3698 EXPECT_FALSE(enabled_extensions
.Contains(good0
));
3699 EXPECT_TRUE(disabled_extensions
.Contains(good0
));
3700 EXPECT_FALSE(enabled_extensions
.Contains(good1
));
3701 EXPECT_TRUE(disabled_extensions
.Contains(good1
));
3702 EXPECT_TRUE(enabled_extensions
.Contains(good2
));
3703 EXPECT_FALSE(disabled_extensions
.Contains(good2
));
3705 test_blacklist
.SetBlacklistState(
3706 good0
, extensions::NOT_BLACKLISTED
, true);
3707 test_blacklist
.SetBlacklistState(
3708 good1
, extensions::BLACKLISTED_UNKNOWN
, true);
3709 test_blacklist
.SetBlacklistState(
3710 good2
, extensions::BLACKLISTED_UNKNOWN
, true);
3711 base::RunLoop().RunUntilIdle();
3713 // good0 re-enabled, other remain as they were.
3714 EXPECT_TRUE(enabled_extensions
.Contains(good0
));
3715 EXPECT_FALSE(disabled_extensions
.Contains(good0
));
3716 EXPECT_FALSE(enabled_extensions
.Contains(good1
));
3717 EXPECT_TRUE(disabled_extensions
.Contains(good1
));
3718 EXPECT_TRUE(enabled_extensions
.Contains(good2
));
3719 EXPECT_FALSE(disabled_extensions
.Contains(good2
));
3721 #endif // defined(ENABLE_BLACKLIST_TESTS)
3723 // Will not install extension blacklisted by policy.
3724 TEST_F(ExtensionServiceTest
, BlacklistedByPolicyWillNotInstall
) {
3725 InitializeEmptyExtensionService();
3727 // Blacklist everything.
3729 ListPrefUpdate
update(profile_
->GetPrefs(),
3730 extensions::pref_names::kInstallDenyList
);
3731 base::ListValue
* blacklist
= update
.Get();
3732 blacklist
->Append(new base::StringValue("*"));
3735 // Blacklist prevents us from installing good_crx.
3736 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
3737 InstallCRX(path
, INSTALL_FAILED
);
3738 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
3740 // Now whitelist this particular extension.
3742 ListPrefUpdate
update(profile_
->GetPrefs(),
3743 extensions::pref_names::kInstallAllowList
);
3744 base::ListValue
* whitelist
= update
.Get();
3745 whitelist
->Append(new base::StringValue(good_crx
));
3748 // Ensure we can now install good_crx.
3749 InstallCRX(path
, INSTALL_NEW
);
3750 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3753 // Extension blacklisted by policy get unloaded after installing.
3754 TEST_F(ExtensionServiceTest
, BlacklistedByPolicyRemovedIfRunning
) {
3755 InitializeEmptyExtensionService();
3757 // Install good_crx.
3758 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
3759 InstallCRX(path
, INSTALL_NEW
);
3760 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3762 { // Scope for pref update notification.
3763 PrefService
* prefs
= profile_
->GetPrefs();
3764 ListPrefUpdate
update(prefs
, extensions::pref_names::kInstallDenyList
);
3765 base::ListValue
* blacklist
= update
.Get();
3766 ASSERT_TRUE(blacklist
!= NULL
);
3768 // Blacklist this extension.
3769 blacklist
->Append(new base::StringValue(good_crx
));
3772 // Extension should not be running now.
3773 base::RunLoop().RunUntilIdle();
3774 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
3777 // Tests that component extensions are not blacklisted by policy.
3778 TEST_F(ExtensionServiceTest
, ComponentExtensionWhitelisted
) {
3779 InitializeEmptyExtensionService();
3781 // Blacklist everything.
3783 ListPrefUpdate
update(profile_
->GetPrefs(),
3784 extensions::pref_names::kInstallDenyList
);
3785 base::ListValue
* blacklist
= update
.Get();
3786 blacklist
->Append(new base::StringValue("*"));
3789 // Install a component extension.
3790 base::FilePath path
= data_dir_
3791 .AppendASCII("good")
3792 .AppendASCII("Extensions")
3794 .AppendASCII("1.0.0.0");
3795 std::string manifest
;
3796 ASSERT_TRUE(base::ReadFileToString(
3797 path
.Append(extensions::kManifestFilename
), &manifest
));
3798 service_
->component_loader()->Add(manifest
, path
);
3801 // Extension should be installed despite blacklist.
3802 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
3803 EXPECT_TRUE(service_
->GetExtensionById(good0
, false));
3805 // Poke external providers and make sure the extension is still present.
3806 service_
->CheckForExternalUpdates();
3807 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
3808 EXPECT_TRUE(service_
->GetExtensionById(good0
, false));
3810 // Extension should not be uninstalled on blacklist changes.
3812 ListPrefUpdate
update(profile_
->GetPrefs(),
3813 extensions::pref_names::kInstallDenyList
);
3814 base::ListValue
* blacklist
= update
.Get();
3815 blacklist
->Append(new base::StringValue(good0
));
3817 base::RunLoop().RunUntilIdle();
3818 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
3819 EXPECT_TRUE(service_
->GetExtensionById(good0
, false));
3822 // Tests that policy-installed extensions are not blacklisted by policy.
3823 TEST_F(ExtensionServiceTest
, PolicyInstalledExtensionsWhitelisted
) {
3824 InitializeEmptyExtensionService();
3827 // Blacklist everything.
3828 ListPrefUpdate
blacklist_update(
3829 profile_
->GetPrefs(), extensions::pref_names::kInstallDenyList
);
3830 base::ListValue
* blacklist
= blacklist_update
.Get();
3831 blacklist
->AppendString("*");
3833 // Mark good.crx for force-installation.
3834 DictionaryPrefUpdate
forcelist_update(
3835 profile_
->GetPrefs(),
3836 extensions::pref_names::kInstallForceList
);
3837 extensions::ExternalPolicyLoader::AddExtension(
3838 forcelist_update
.Get(), good_crx
, "http://example.com/update_url");
3841 // Have policy force-install an extension.
3842 MockExtensionProvider
* provider
=
3843 new MockExtensionProvider(service_
,
3844 Manifest::EXTERNAL_POLICY_DOWNLOAD
);
3845 AddMockExternalProvider(provider
);
3846 provider
->UpdateOrAddExtension(good_crx
, "1.0.0.0",
3847 data_dir_
.AppendASCII("good.crx"));
3849 // Reloading extensions should find our externally registered extension
3851 content::WindowedNotificationObserver
observer(
3852 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
3853 content::NotificationService::AllSources());
3854 service_
->CheckForExternalUpdates();
3857 // Extension should be installed despite blacklist.
3858 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
3859 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, false));
3861 // Blacklist update should not uninstall the extension.
3863 ListPrefUpdate
update(profile_
->GetPrefs(),
3864 extensions::pref_names::kInstallDenyList
);
3865 base::ListValue
* blacklist
= update
.Get();
3866 blacklist
->Append(new base::StringValue(good0
));
3868 base::RunLoop().RunUntilIdle();
3869 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
3870 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, false));
3873 // Tests that extensions cannot be installed if the policy provider prohibits
3874 // it. This functionality is implemented in CrxInstaller::ConfirmInstall().
3875 TEST_F(ExtensionServiceTest
, ManagementPolicyProhibitsInstall
) {
3876 InitializeEmptyExtensionService();
3878 management_policy_
->UnregisterAllProviders();
3879 extensions::TestManagementPolicyProvider
provider_(
3880 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD
);
3881 management_policy_
->RegisterProvider(&provider_
);
3883 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_FAILED
);
3884 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
3887 // Tests that extensions cannot be loaded from prefs if the policy provider
3888 // prohibits it. This functionality is implemented in InstalledLoader::Load().
3889 TEST_F(ExtensionServiceTest
, ManagementPolicyProhibitsLoadFromPrefs
) {
3890 InitializeEmptyExtensionService();
3892 // Create a fake extension to be loaded as though it were read from prefs.
3893 base::FilePath path
= data_dir_
.AppendASCII("management")
3894 .AppendASCII("simple_extension");
3895 base::DictionaryValue manifest
;
3896 manifest
.SetString(keys::kName
, "simple_extension");
3897 manifest
.SetString(keys::kVersion
, "1");
3898 // UNPACKED is for extensions loaded from a directory. We use it here, even
3899 // though we're testing loading from prefs, so that we don't need to provide
3900 // an extension key.
3901 extensions::ExtensionInfo
extension_info(
3902 &manifest
, std::string(), path
, Manifest::UNPACKED
);
3904 // Ensure we can load it with no management policy in place.
3905 management_policy_
->UnregisterAllProviders();
3906 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
3907 extensions::InstalledLoader(service_
).Load(extension_info
, false);
3908 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3910 const Extension
* extension
= (registry_
->enabled_extensions().begin())->get();
3911 EXPECT_TRUE(service_
->UninstallExtension(extension
->id(), false, NULL
));
3912 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
3914 // Ensure we cannot load it if management policy prohibits installation.
3915 extensions::TestManagementPolicyProvider
provider_(
3916 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD
);
3917 management_policy_
->RegisterProvider(&provider_
);
3919 extensions::InstalledLoader(service_
).Load(extension_info
, false);
3920 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
3923 // Tests disabling an extension when prohibited by the ManagementPolicy.
3924 TEST_F(ExtensionServiceTest
, ManagementPolicyProhibitsDisable
) {
3925 InitializeEmptyExtensionService();
3927 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
3928 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3929 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
3931 management_policy_
->UnregisterAllProviders();
3932 extensions::TestManagementPolicyProvider
provider(
3933 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS
);
3934 management_policy_
->RegisterProvider(&provider
);
3936 // Attempt to disable it.
3937 service_
->DisableExtension(good_crx
, Extension::DISABLE_USER_ACTION
);
3939 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3940 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, false));
3941 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
3944 // Tests uninstalling an extension when prohibited by the ManagementPolicy.
3945 TEST_F(ExtensionServiceTest
, ManagementPolicyProhibitsUninstall
) {
3946 InitializeEmptyExtensionService();
3948 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
3949 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3950 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
3952 management_policy_
->UnregisterAllProviders();
3953 extensions::TestManagementPolicyProvider
provider(
3954 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS
);
3955 management_policy_
->RegisterProvider(&provider
);
3957 // Attempt to uninstall it.
3958 EXPECT_FALSE(service_
->UninstallExtension(good_crx
, false, NULL
));
3960 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3961 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, false));
3964 // Tests that previously installed extensions that are now prohibited from
3965 // being installed are removed.
3966 TEST_F(ExtensionServiceTest
, ManagementPolicyUnloadsAllProhibited
) {
3967 InitializeEmptyExtensionService();
3969 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
3970 InstallCRX(data_dir_
.AppendASCII("page_action.crx"), INSTALL_NEW
);
3971 EXPECT_EQ(2u, registry_
->enabled_extensions().size());
3972 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
3974 management_policy_
->UnregisterAllProviders();
3975 extensions::TestManagementPolicyProvider
provider(
3976 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD
);
3977 management_policy_
->RegisterProvider(&provider
);
3979 // Run the policy check.
3980 service_
->CheckManagementPolicy();
3981 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
3982 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
3985 // Tests that previously disabled extensions that are now required to be
3986 // enabled are re-enabled on reinstall.
3987 TEST_F(ExtensionServiceTest
, ManagementPolicyRequiresEnable
) {
3988 InitializeEmptyExtensionService();
3990 // Install, then disable, an extension.
3991 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
3992 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
3993 service_
->DisableExtension(good_crx
, Extension::DISABLE_USER_ACTION
);
3994 EXPECT_EQ(1u, registry_
->disabled_extensions().size());
3996 // Register an ExtensionMnagementPolicy that requires the extension to remain
3998 management_policy_
->UnregisterAllProviders();
3999 extensions::TestManagementPolicyProvider
provider(
4000 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED
);
4001 management_policy_
->RegisterProvider(&provider
);
4003 // Reinstall the extension.
4004 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_UPDATED
);
4005 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4006 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4009 // Flaky on windows; http://crbug.com/309833
4011 #define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
4013 #define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
4015 TEST_F(ExtensionServiceTest
, MAYBE_ExternalExtensionAutoAcknowledgement
) {
4016 InitializeEmptyExtensionService();
4017 set_extensions_enabled(true);
4020 // Register and install an external extension.
4021 MockExtensionProvider
* provider
=
4022 new MockExtensionProvider(service_
, Manifest::EXTERNAL_PREF
);
4023 AddMockExternalProvider(provider
);
4024 provider
->UpdateOrAddExtension(good_crx
, "1.0.0.0",
4025 data_dir_
.AppendASCII("good.crx"));
4028 // Have policy force-install an extension.
4029 MockExtensionProvider
* provider
=
4030 new MockExtensionProvider(service_
,
4031 Manifest::EXTERNAL_POLICY_DOWNLOAD
);
4032 AddMockExternalProvider(provider
);
4033 provider
->UpdateOrAddExtension(page_action
, "1.0.0.0",
4034 data_dir_
.AppendASCII("page_action.crx"));
4037 // Providers are set up. Let them run.
4039 content::WindowedNotificationObserver
observer(
4040 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
4041 base::Bind(&WaitForCountNotificationsCallback
, &count
));
4042 service_
->CheckForExternalUpdates();
4046 ASSERT_EQ(2u, registry_
->enabled_extensions().size());
4047 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, false));
4048 EXPECT_TRUE(service_
->GetExtensionById(page_action
, false));
4049 ExtensionPrefs
* prefs
= service_
->extension_prefs();
4050 ASSERT_TRUE(!prefs
->IsExternalExtensionAcknowledged(good_crx
));
4051 ASSERT_TRUE(prefs
->IsExternalExtensionAcknowledged(page_action
));
4054 #if !defined(OS_CHROMEOS)
4055 // This tests if default apps are installed correctly.
4056 TEST_F(ExtensionServiceTest
, DefaultAppsInstall
) {
4057 InitializeEmptyExtensionService();
4058 set_extensions_enabled(true);
4061 std::string json_data
=
4063 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
4064 " \"external_crx\": \"good.crx\","
4065 " \"external_version\": \"1.0.0.0\","
4066 " \"is_bookmark_app\": false"
4069 default_apps::Provider
* provider
=
4070 new default_apps::Provider(
4073 new extensions::ExternalTestingLoader(json_data
, data_dir_
),
4075 Manifest::INVALID_LOCATION
,
4076 Extension::FROM_WEBSTORE
| Extension::WAS_INSTALLED_BY_DEFAULT
);
4078 AddMockExternalProvider(provider
);
4081 ASSERT_EQ(0u, registry_
->enabled_extensions().size());
4082 content::WindowedNotificationObserver
observer(
4083 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
4084 content::NotificationService::AllSources());
4085 service_
->CheckForExternalUpdates();
4088 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
4089 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, false));
4090 const Extension
* extension
= service_
->GetExtensionById(good_crx
, false);
4091 EXPECT_TRUE(extension
->from_webstore());
4092 EXPECT_TRUE(extension
->was_installed_by_default());
4096 // Tests disabling extensions
4097 TEST_F(ExtensionServiceTest
, DisableExtension
) {
4098 InitializeEmptyExtensionService();
4100 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
4101 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, true));
4102 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, false));
4104 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4105 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4106 EXPECT_EQ(0u, registry_
->terminated_extensions().size());
4107 EXPECT_EQ(0u, registry_
->blacklisted_extensions().size());
4110 service_
->DisableExtension(good_crx
, Extension::DISABLE_USER_ACTION
);
4112 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, true));
4113 EXPECT_FALSE(service_
->GetExtensionById(good_crx
, false));
4114 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4115 EXPECT_EQ(1u, registry_
->disabled_extensions().size());
4116 EXPECT_EQ(0u, registry_
->terminated_extensions().size());
4117 EXPECT_EQ(0u, registry_
->blacklisted_extensions().size());
4120 TEST_F(ExtensionServiceTest
, TerminateExtension
) {
4121 InitializeEmptyExtensionService();
4123 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
4124 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4125 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4126 EXPECT_EQ(0u, registry_
->terminated_extensions().size());
4127 EXPECT_EQ(0u, registry_
->blacklisted_extensions().size());
4129 TerminateExtension(good_crx
);
4131 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4132 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4133 EXPECT_EQ(1u, registry_
->terminated_extensions().size());
4134 EXPECT_EQ(0u, registry_
->blacklisted_extensions().size());
4137 TEST_F(ExtensionServiceTest
, DisableTerminatedExtension
) {
4138 InitializeEmptyExtensionService();
4140 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
4141 TerminateExtension(good_crx
);
4142 EXPECT_TRUE(service_
->GetTerminatedExtension(good_crx
));
4145 service_
->DisableExtension(good_crx
, Extension::DISABLE_USER_ACTION
);
4147 EXPECT_FALSE(service_
->GetTerminatedExtension(good_crx
));
4148 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, true));
4150 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4151 EXPECT_EQ(1u, registry_
->disabled_extensions().size());
4152 EXPECT_EQ(0u, registry_
->terminated_extensions().size());
4153 EXPECT_EQ(0u, registry_
->blacklisted_extensions().size());
4156 // Tests disabling all extensions (simulating --disable-extensions flag).
4157 TEST_F(ExtensionServiceTest
, DisableAllExtensions
) {
4158 InitializeEmptyExtensionService();
4160 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
4161 InstallCRX(path
, INSTALL_NEW
);
4163 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4164 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4166 // Disable extensions.
4167 service_
->set_extensions_enabled(false);
4168 service_
->ReloadExtensionsForTest();
4170 // There shouldn't be extensions in either list.
4171 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4172 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4174 // This shouldn't do anything when all extensions are disabled.
4175 service_
->EnableExtension(good_crx
);
4176 service_
->ReloadExtensionsForTest();
4178 // There still shouldn't be extensions in either list.
4179 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4180 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4182 // And then re-enable the extensions.
4183 service_
->set_extensions_enabled(true);
4184 service_
->ReloadExtensionsForTest();
4186 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4187 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4190 // Tests reloading extensions.
4191 TEST_F(ExtensionServiceTest
, ReloadExtensions
) {
4192 InitializeEmptyExtensionService();
4194 // Simple extension that should install without error.
4195 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
4196 InstallCRX(path
, INSTALL_NEW
,
4197 Extension::FROM_WEBSTORE
| Extension::WAS_INSTALLED_BY_DEFAULT
);
4198 const char* extension_id
= good_crx
;
4199 service_
->DisableExtension(extension_id
, Extension::DISABLE_USER_ACTION
);
4201 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4202 EXPECT_EQ(1u, registry_
->disabled_extensions().size());
4204 service_
->ReloadExtensionsForTest();
4206 // The creation flags should not change when reloading the extension.
4207 const Extension
* extension
= service_
->GetExtensionById(good_crx
, true);
4208 EXPECT_TRUE(extension
->from_webstore());
4209 EXPECT_TRUE(extension
->was_installed_by_default());
4210 EXPECT_FALSE(extension
->from_bookmark());
4212 // Extension counts shouldn't change.
4213 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4214 EXPECT_EQ(1u, registry_
->disabled_extensions().size());
4216 service_
->EnableExtension(extension_id
);
4218 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4219 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4221 // Need to clear |loaded_| manually before reloading as the
4222 // EnableExtension() call above inserted into it and
4223 // UnloadAllExtensions() doesn't send out notifications.
4225 service_
->ReloadExtensionsForTest();
4227 // Extension counts shouldn't change.
4228 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4229 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4232 // Tests reloading an extension.
4233 TEST_F(ExtensionServiceTest
, ReloadExtension
) {
4234 InitializeEmptyExtensionService();
4235 InitializeProcessManager();
4237 // Simple extension that should install without error.
4238 const char* extension_id
= "behllobkkfkfnphdnhnkndlbkcpglgmj";
4239 base::FilePath ext
= data_dir_
4240 .AppendASCII("good")
4241 .AppendASCII("Extensions")
4242 .AppendASCII(extension_id
)
4243 .AppendASCII("1.0.0.0");
4244 extensions::UnpackedInstaller::Create(service_
)->Load(ext
);
4245 base::RunLoop().RunUntilIdle();
4247 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4248 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4250 service_
->ReloadExtension(extension_id
);
4252 // Extension should be disabled now, waiting to be reloaded.
4253 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4254 EXPECT_EQ(1u, registry_
->disabled_extensions().size());
4255 EXPECT_EQ(Extension::DISABLE_RELOAD
,
4256 service_
->extension_prefs()->GetDisableReasons(extension_id
));
4258 // Reloading again should not crash.
4259 service_
->ReloadExtension(extension_id
);
4262 base::RunLoop().RunUntilIdle();
4264 // Extension should be enabled again.
4265 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4266 EXPECT_EQ(0u, registry_
->disabled_extensions().size());
4269 TEST_F(ExtensionServiceTest
, UninstallExtension
) {
4270 InitializeEmptyExtensionService();
4271 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
4272 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4273 UninstallExtension(good_crx
, false);
4274 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4277 TEST_F(ExtensionServiceTest
, UninstallTerminatedExtension
) {
4278 InitializeEmptyExtensionService();
4279 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
4280 TerminateExtension(good_crx
);
4281 UninstallExtension(good_crx
, false);
4284 // Tests the uninstaller helper.
4285 TEST_F(ExtensionServiceTest
, UninstallExtensionHelper
) {
4286 InitializeEmptyExtensionService();
4287 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
4288 UninstallExtension(good_crx
, true);
4291 TEST_F(ExtensionServiceTest
, UninstallExtensionHelperTerminated
) {
4292 InitializeEmptyExtensionService();
4293 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
4294 TerminateExtension(good_crx
);
4295 UninstallExtension(good_crx
, true);
4298 // An extension disabled because of unsupported requirements should re-enabled
4299 // if updated to a version with supported requirements as long as there are no
4300 // other disable reasons.
4301 TEST_F(ExtensionServiceTest
, UpgradingRequirementsEnabled
) {
4302 InitializeEmptyExtensionService();
4305 base::FilePath path
= data_dir_
.AppendASCII("requirements");
4306 base::FilePath pem_path
= data_dir_
.AppendASCII("requirements")
4307 .AppendASCII("v1_good.pem");
4308 const Extension
* extension_v1
= PackAndInstallCRX(path
.AppendASCII("v1_good"),
4311 std::string id
= extension_v1
->id();
4312 EXPECT_TRUE(service_
->IsExtensionEnabled(id
));
4314 base::FilePath v2_bad_requirements_crx
= GetTemporaryFile();
4316 PackCRX(path
.AppendASCII("v2_bad_requirements"),
4318 v2_bad_requirements_crx
);
4319 UpdateExtension(id
, v2_bad_requirements_crx
, INSTALLED
);
4320 EXPECT_FALSE(service_
->IsExtensionEnabled(id
));
4322 base::FilePath v3_good_crx
= GetTemporaryFile();
4324 PackCRX(path
.AppendASCII("v3_good"), pem_path
, v3_good_crx
);
4325 UpdateExtension(id
, v3_good_crx
, ENABLED
);
4326 EXPECT_TRUE(service_
->IsExtensionEnabled(id
));
4329 // Extensions disabled through user action should stay disabled.
4330 TEST_F(ExtensionServiceTest
, UpgradingRequirementsDisabled
) {
4331 InitializeEmptyExtensionService();
4334 base::FilePath path
= data_dir_
.AppendASCII("requirements");
4335 base::FilePath pem_path
= data_dir_
.AppendASCII("requirements")
4336 .AppendASCII("v1_good.pem");
4337 const Extension
* extension_v1
= PackAndInstallCRX(path
.AppendASCII("v1_good"),
4340 std::string id
= extension_v1
->id();
4341 service_
->DisableExtension(id
, Extension::DISABLE_USER_ACTION
);
4342 EXPECT_FALSE(service_
->IsExtensionEnabled(id
));
4344 base::FilePath v2_bad_requirements_crx
= GetTemporaryFile();
4346 PackCRX(path
.AppendASCII("v2_bad_requirements"),
4348 v2_bad_requirements_crx
);
4349 UpdateExtension(id
, v2_bad_requirements_crx
, INSTALLED
);
4350 EXPECT_FALSE(service_
->IsExtensionEnabled(id
));
4352 base::FilePath v3_good_crx
= GetTemporaryFile();
4354 PackCRX(path
.AppendASCII("v3_good"), pem_path
, v3_good_crx
);
4355 UpdateExtension(id
, v3_good_crx
, INSTALLED
);
4356 EXPECT_FALSE(service_
->IsExtensionEnabled(id
));
4359 // The extension should not re-enabled because it was disabled from a
4360 // permission increase.
4361 TEST_F(ExtensionServiceTest
, UpgradingRequirementsPermissions
) {
4362 InitializeEmptyExtensionService();
4365 base::FilePath path
= data_dir_
.AppendASCII("requirements");
4366 base::FilePath pem_path
= data_dir_
.AppendASCII("requirements")
4367 .AppendASCII("v1_good.pem");
4368 const Extension
* extension_v1
= PackAndInstallCRX(path
.AppendASCII("v1_good"),
4371 std::string id
= extension_v1
->id();
4372 EXPECT_TRUE(service_
->IsExtensionEnabled(id
));
4374 base::FilePath v2_bad_requirements_and_permissions_crx
= GetTemporaryFile();
4376 PackCRX(path
.AppendASCII("v2_bad_requirements_and_permissions"),
4378 v2_bad_requirements_and_permissions_crx
);
4379 UpdateExtension(id
, v2_bad_requirements_and_permissions_crx
, INSTALLED
);
4380 EXPECT_FALSE(service_
->IsExtensionEnabled(id
));
4382 base::FilePath v3_bad_permissions_crx
= GetTemporaryFile();
4384 PackCRX(path
.AppendASCII("v3_bad_permissions"),
4386 v3_bad_permissions_crx
);
4387 UpdateExtension(id
, v3_bad_permissions_crx
, INSTALLED
);
4388 EXPECT_FALSE(service_
->IsExtensionEnabled(id
));
4391 // Unpacked extensions are not allowed to be installed if they have unsupported
4393 TEST_F(ExtensionServiceTest
, UnpackedRequirements
) {
4394 InitializeEmptyExtensionService();
4397 base::FilePath path
= data_dir_
.AppendASCII("requirements")
4398 .AppendASCII("v2_bad_requirements");
4399 extensions::UnpackedInstaller::Create(service_
)->Load(path
);
4400 base::RunLoop().RunUntilIdle();
4401 EXPECT_EQ(1u, GetErrors().size());
4402 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4405 class ExtensionCookieCallback
{
4407 ExtensionCookieCallback()
4409 weak_factory_(base::MessageLoop::current()) {}
4411 void SetCookieCallback(bool result
) {
4412 base::MessageLoop::current()->PostTask(FROM_HERE
,
4413 base::Bind(&base::MessageLoop::Quit
, weak_factory_
.GetWeakPtr()));
4417 void GetAllCookiesCallback(const net::CookieList
& list
) {
4418 base::MessageLoop::current()->PostTask(FROM_HERE
,
4419 base::Bind(&base::MessageLoop::Quit
, weak_factory_
.GetWeakPtr()));
4422 net::CookieList list_
;
4424 base::WeakPtrFactory
<base::MessageLoop
> weak_factory_
;
4427 // Verifies extension state is removed upon uninstall.
4428 TEST_F(ExtensionServiceTest
, ClearExtensionData
) {
4429 InitializeEmptyExtensionService();
4430 ExtensionCookieCallback callback
;
4432 // Load a test extension.
4433 base::FilePath path
= data_dir_
;
4434 path
= path
.AppendASCII("good.crx");
4435 const Extension
* extension
= InstallCRX(path
, INSTALL_NEW
);
4436 ASSERT_TRUE(extension
);
4437 GURL
ext_url(extension
->url());
4438 std::string origin_id
= webkit_database::GetIdentifierFromOrigin(ext_url
);
4440 // Set a cookie for the extension.
4441 net::CookieMonster
* cookie_monster
=
4442 profile_
->GetRequestContextForExtensions()->GetURLRequestContext()->
4443 cookie_store()->GetCookieMonster();
4444 ASSERT_TRUE(cookie_monster
);
4445 net::CookieOptions options
;
4446 cookie_monster
->SetCookieWithOptionsAsync(
4447 ext_url
, "dummy=value", options
,
4448 base::Bind(&ExtensionCookieCallback::SetCookieCallback
,
4449 base::Unretained(&callback
)));
4450 base::RunLoop().RunUntilIdle();
4451 EXPECT_TRUE(callback
.result_
);
4453 cookie_monster
->GetAllCookiesForURLAsync(
4455 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback
,
4456 base::Unretained(&callback
)));
4457 base::RunLoop().RunUntilIdle();
4458 EXPECT_EQ(1U, callback
.list_
.size());
4461 webkit_database::DatabaseTracker
* db_tracker
=
4462 BrowserContext::GetDefaultStoragePartition(profile_
.get())->
4463 GetDatabaseTracker();
4464 base::string16 db_name
= base::UTF8ToUTF16("db");
4465 base::string16 description
= base::UTF8ToUTF16("db_description");
4467 db_tracker
->DatabaseOpened(origin_id
, db_name
, description
, 1, &size
);
4468 db_tracker
->DatabaseClosed(origin_id
, db_name
);
4469 std::vector
<webkit_database::OriginInfo
> origins
;
4470 db_tracker
->GetAllOriginsInfo(&origins
);
4471 EXPECT_EQ(1U, origins
.size());
4472 EXPECT_EQ(origin_id
, origins
[0].GetOriginIdentifier());
4474 // Create local storage. We only simulate this by creating the backing files.
4475 // Note: This test depends on details of how the dom_storage library
4476 // stores data in the host file system.
4477 base::FilePath lso_dir_path
=
4478 profile_
->GetPath().AppendASCII("Local Storage");
4479 base::FilePath lso_file_path
= lso_dir_path
.AppendASCII(origin_id
)
4480 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4481 EXPECT_TRUE(base::CreateDirectory(lso_dir_path
));
4482 EXPECT_EQ(0, file_util::WriteFile(lso_file_path
, NULL
, 0));
4483 EXPECT_TRUE(base::PathExists(lso_file_path
));
4485 // Create indexed db. Similarly, it is enough to only simulate this by
4486 // creating the directory on the disk.
4487 IndexedDBContext
* idb_context
=
4488 BrowserContext::GetDefaultStoragePartition(profile_
.get())->
4489 GetIndexedDBContext();
4490 idb_context
->SetTaskRunnerForTesting(
4491 base::MessageLoop::current()->message_loop_proxy().get());
4492 base::FilePath idb_path
= idb_context
->GetFilePathForTesting(origin_id
);
4493 EXPECT_TRUE(base::CreateDirectory(idb_path
));
4494 EXPECT_TRUE(base::DirectoryExists(idb_path
));
4496 // Uninstall the extension.
4497 service_
->UninstallExtension(good_crx
, false, NULL
);
4498 base::RunLoop().RunUntilIdle();
4500 // Check that the cookie is gone.
4501 cookie_monster
->GetAllCookiesForURLAsync(
4503 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback
,
4504 base::Unretained(&callback
)));
4505 base::RunLoop().RunUntilIdle();
4506 EXPECT_EQ(0U, callback
.list_
.size());
4508 // The database should have vanished as well.
4510 db_tracker
->GetAllOriginsInfo(&origins
);
4511 EXPECT_EQ(0U, origins
.size());
4513 // Check that the LSO file has been removed.
4514 EXPECT_FALSE(base::PathExists(lso_file_path
));
4516 // Check if the indexed db has disappeared too.
4517 EXPECT_FALSE(base::DirectoryExists(idb_path
));
4520 // Verifies app state is removed upon uninstall.
4521 TEST_F(ExtensionServiceTest
, ClearAppData
) {
4522 InitializeEmptyExtensionService();
4523 ExtensionCookieCallback callback
;
4527 // Install app1 with unlimited storage.
4528 const Extension
* extension
=
4529 PackAndInstallCRX(data_dir_
.AppendASCII("app1"), INSTALL_NEW
);
4530 ValidatePrefKeyCount(++pref_count
);
4531 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
4532 const std::string id1
= extension
->id();
4533 EXPECT_TRUE(extension
->HasAPIPermission(
4534 APIPermission::kUnlimitedStorage
));
4536 extensions::AppLaunchInfo::GetFullLaunchURL(extension
).GetOrigin());
4537 EXPECT_TRUE(profile_
->GetExtensionSpecialStoragePolicy()->
4538 IsStorageUnlimited(origin1
));
4539 std::string origin_id
= webkit_database::GetIdentifierFromOrigin(origin1
);
4541 // Install app2 from the same origin with unlimited storage.
4542 extension
= PackAndInstallCRX(data_dir_
.AppendASCII("app2"), INSTALL_NEW
);
4543 ValidatePrefKeyCount(++pref_count
);
4544 ASSERT_EQ(2u, registry_
->enabled_extensions().size());
4545 const std::string id2
= extension
->id();
4546 EXPECT_TRUE(extension
->HasAPIPermission(
4547 APIPermission::kUnlimitedStorage
));
4548 EXPECT_TRUE(extension
->web_extent().MatchesURL(
4549 extensions::AppLaunchInfo::GetFullLaunchURL(extension
)));
4551 extensions::AppLaunchInfo::GetFullLaunchURL(extension
).GetOrigin());
4552 EXPECT_EQ(origin1
, origin2
);
4553 EXPECT_TRUE(profile_
->GetExtensionSpecialStoragePolicy()->
4554 IsStorageUnlimited(origin2
));
4556 // Set a cookie for the extension.
4557 net::CookieMonster
* cookie_monster
=
4558 profile_
->GetRequestContext()->GetURLRequestContext()->
4559 cookie_store()->GetCookieMonster();
4560 ASSERT_TRUE(cookie_monster
);
4561 net::CookieOptions options
;
4562 cookie_monster
->SetCookieWithOptionsAsync(
4563 origin1
, "dummy=value", options
,
4564 base::Bind(&ExtensionCookieCallback::SetCookieCallback
,
4565 base::Unretained(&callback
)));
4566 base::RunLoop().RunUntilIdle();
4567 EXPECT_TRUE(callback
.result_
);
4569 cookie_monster
->GetAllCookiesForURLAsync(
4571 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback
,
4572 base::Unretained(&callback
)));
4573 base::RunLoop().RunUntilIdle();
4574 EXPECT_EQ(1U, callback
.list_
.size());
4577 webkit_database::DatabaseTracker
* db_tracker
=
4578 BrowserContext::GetDefaultStoragePartition(profile_
.get())->
4579 GetDatabaseTracker();
4580 base::string16 db_name
= base::UTF8ToUTF16("db");
4581 base::string16 description
= base::UTF8ToUTF16("db_description");
4583 db_tracker
->DatabaseOpened(origin_id
, db_name
, description
, 1, &size
);
4584 db_tracker
->DatabaseClosed(origin_id
, db_name
);
4585 std::vector
<webkit_database::OriginInfo
> origins
;
4586 db_tracker
->GetAllOriginsInfo(&origins
);
4587 EXPECT_EQ(1U, origins
.size());
4588 EXPECT_EQ(origin_id
, origins
[0].GetOriginIdentifier());
4590 // Create local storage. We only simulate this by creating the backing files.
4591 // Note: This test depends on details of how the dom_storage library
4592 // stores data in the host file system.
4593 base::FilePath lso_dir_path
=
4594 profile_
->GetPath().AppendASCII("Local Storage");
4595 base::FilePath lso_file_path
= lso_dir_path
.AppendASCII(origin_id
)
4596 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4597 EXPECT_TRUE(base::CreateDirectory(lso_dir_path
));
4598 EXPECT_EQ(0, file_util::WriteFile(lso_file_path
, NULL
, 0));
4599 EXPECT_TRUE(base::PathExists(lso_file_path
));
4601 // Create indexed db. Similarly, it is enough to only simulate this by
4602 // creating the directory on the disk.
4603 IndexedDBContext
* idb_context
=
4604 BrowserContext::GetDefaultStoragePartition(profile_
.get())->
4605 GetIndexedDBContext();
4606 idb_context
->SetTaskRunnerForTesting(
4607 base::MessageLoop::current()->message_loop_proxy().get());
4608 base::FilePath idb_path
= idb_context
->GetFilePathForTesting(origin_id
);
4609 EXPECT_TRUE(base::CreateDirectory(idb_path
));
4610 EXPECT_TRUE(base::DirectoryExists(idb_path
));
4612 // Uninstall one of them, unlimited storage should still be granted
4614 UninstallExtension(id1
, false);
4615 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4616 EXPECT_TRUE(profile_
->GetExtensionSpecialStoragePolicy()->
4617 IsStorageUnlimited(origin1
));
4619 // Check that the cookie is still there.
4620 cookie_monster
->GetAllCookiesForURLAsync(
4622 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback
,
4623 base::Unretained(&callback
)));
4624 base::RunLoop().RunUntilIdle();
4625 EXPECT_EQ(1U, callback
.list_
.size());
4627 // Now uninstall the other. Storage should be cleared for the apps.
4628 UninstallExtension(id2
, false);
4629 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4630 EXPECT_FALSE(profile_
->GetExtensionSpecialStoragePolicy()->
4631 IsStorageUnlimited(origin1
));
4633 // Check that the cookie is gone.
4634 cookie_monster
->GetAllCookiesForURLAsync(
4636 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback
,
4637 base::Unretained(&callback
)));
4638 base::RunLoop().RunUntilIdle();
4639 EXPECT_EQ(0U, callback
.list_
.size());
4641 // The database should have vanished as well.
4643 db_tracker
->GetAllOriginsInfo(&origins
);
4644 EXPECT_EQ(0U, origins
.size());
4646 // Check that the LSO file has been removed.
4647 EXPECT_FALSE(base::PathExists(lso_file_path
));
4649 // Check if the indexed db has disappeared too.
4650 EXPECT_FALSE(base::DirectoryExists(idb_path
));
4653 // Tests loading single extensions (like --load-extension)
4654 // Flaky crashes. http://crbug.com/231806
4655 TEST_F(ExtensionServiceTest
, DISABLED_LoadExtension
) {
4656 InitializeEmptyExtensionService();
4658 base::FilePath ext1
= data_dir_
4659 .AppendASCII("good")
4660 .AppendASCII("Extensions")
4661 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4662 .AppendASCII("1.0.0.0");
4663 extensions::UnpackedInstaller::Create(service_
)->Load(ext1
);
4664 base::RunLoop().RunUntilIdle();
4665 EXPECT_EQ(0u, GetErrors().size());
4666 ASSERT_EQ(1u, loaded_
.size());
4667 EXPECT_EQ(Manifest::UNPACKED
, loaded_
[0]->location());
4668 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4670 ValidatePrefKeyCount(1);
4672 base::FilePath no_manifest
= data_dir_
4674 // .AppendASCII("Extensions")
4675 .AppendASCII("cccccccccccccccccccccccccccccccc")
4677 extensions::UnpackedInstaller::Create(service_
)->Load(no_manifest
);
4678 base::RunLoop().RunUntilIdle();
4679 EXPECT_EQ(1u, GetErrors().size());
4680 ASSERT_EQ(1u, loaded_
.size());
4681 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
4684 std::string id
= loaded_
[0]->id();
4685 EXPECT_FALSE(unloaded_id_
.length());
4686 service_
->UninstallExtension(id
, false, NULL
);
4687 base::RunLoop().RunUntilIdle();
4688 EXPECT_EQ(id
, unloaded_id_
);
4689 ASSERT_EQ(0u, loaded_
.size());
4690 EXPECT_EQ(0u, registry_
->enabled_extensions().size());
4693 // Tests that we generate IDs when they are not specified in the manifest for
4694 // --load-extension.
4695 TEST_F(ExtensionServiceTest
, GenerateID
) {
4696 InitializeEmptyExtensionService();
4698 base::FilePath no_id_ext
= data_dir_
.AppendASCII("no_id");
4699 extensions::UnpackedInstaller::Create(service_
)->Load(no_id_ext
);
4700 base::RunLoop().RunUntilIdle();
4701 EXPECT_EQ(0u, GetErrors().size());
4702 ASSERT_EQ(1u, loaded_
.size());
4703 ASSERT_TRUE(Extension::IdIsValid(loaded_
[0]->id()));
4704 EXPECT_EQ(loaded_
[0]->location(), Manifest::UNPACKED
);
4706 ValidatePrefKeyCount(1);
4708 std::string previous_id
= loaded_
[0]->id();
4710 // If we reload the same path, we should get the same extension ID.
4711 extensions::UnpackedInstaller::Create(service_
)->Load(no_id_ext
);
4712 base::RunLoop().RunUntilIdle();
4713 ASSERT_EQ(1u, loaded_
.size());
4714 ASSERT_EQ(previous_id
, loaded_
[0]->id());
4717 TEST_F(ExtensionServiceTest
, UnpackedValidatesLocales
) {
4718 InitializeEmptyExtensionService();
4720 base::FilePath bad_locale
= data_dir_
.AppendASCII("unpacked").
4721 AppendASCII("bad_messages_file");
4722 extensions::UnpackedInstaller::Create(service_
)->Load(bad_locale
);
4723 base::RunLoop().RunUntilIdle();
4724 EXPECT_EQ(1u, GetErrors().size());
4725 base::FilePath ms_messages_file
= bad_locale
.AppendASCII("_locales")
4727 .AppendASCII("messages.json");
4728 EXPECT_THAT(base::UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
4730 base::UTF16ToUTF8(ms_messages_file
.LossyDisplayName())),
4731 testing::HasSubstr("Dictionary keys must be quoted.")));
4732 ASSERT_EQ(0u, loaded_
.size());
4735 void ExtensionServiceTest::TestExternalProvider(
4736 MockExtensionProvider
* provider
, Manifest::Location location
) {
4737 // Verify that starting with no providers loads no extensions.
4739 ASSERT_EQ(0u, loaded_
.size());
4741 provider
->set_visit_count(0);
4743 // Register a test extension externally using the mock registry provider.
4744 base::FilePath source_path
= data_dir_
.AppendASCII("good.crx");
4746 // Add the extension.
4747 provider
->UpdateOrAddExtension(good_crx
, "1.0.0.0", source_path
);
4749 // Reloading extensions should find our externally registered extension
4751 content::WindowedNotificationObserver
observer(
4752 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
4753 content::NotificationService::AllSources());
4754 service_
->CheckForExternalUpdates();
4757 ASSERT_EQ(0u, GetErrors().size());
4758 ASSERT_EQ(1u, loaded_
.size());
4759 ASSERT_EQ(location
, loaded_
[0]->location());
4760 ASSERT_EQ("1.0.0.0", loaded_
[0]->version()->GetString());
4761 ValidatePrefKeyCount(1);
4762 ValidateIntegerPref(good_crx
, "state", Extension::ENABLED
);
4763 ValidateIntegerPref(good_crx
, "location", location
);
4765 // Reload extensions without changing anything. The extension should be
4768 service_
->ReloadExtensionsForTest();
4769 base::RunLoop().RunUntilIdle();
4770 ASSERT_EQ(0u, GetErrors().size());
4771 ASSERT_EQ(1u, loaded_
.size());
4772 ValidatePrefKeyCount(1);
4773 ValidateIntegerPref(good_crx
, "state", Extension::ENABLED
);
4774 ValidateIntegerPref(good_crx
, "location", location
);
4776 // Now update the extension with a new version. We should get upgraded.
4777 source_path
= source_path
.DirName().AppendASCII("good2.crx");
4778 provider
->UpdateOrAddExtension(good_crx
, "1.0.0.1", source_path
);
4781 content::WindowedNotificationObserver
observer_2(
4782 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
4783 content::NotificationService::AllSources());
4784 service_
->CheckForExternalUpdates();
4786 ASSERT_EQ(0u, GetErrors().size());
4787 ASSERT_EQ(1u, loaded_
.size());
4788 ASSERT_EQ("1.0.0.1", loaded_
[0]->version()->GetString());
4789 ValidatePrefKeyCount(1);
4790 ValidateIntegerPref(good_crx
, "state", Extension::ENABLED
);
4791 ValidateIntegerPref(good_crx
, "location", location
);
4793 // Uninstall the extension and reload. Nothing should happen because the
4794 // preference should prevent us from reinstalling.
4795 std::string id
= loaded_
[0]->id();
4797 management_policy_
->MustRemainEnabled(loaded_
[0].get(), NULL
);
4798 service_
->UninstallExtension(id
, false, NULL
);
4799 base::RunLoop().RunUntilIdle();
4801 base::FilePath install_path
= extensions_install_dir_
.AppendASCII(id
);
4803 // Policy controlled extensions should not have been touched by uninstall.
4804 ASSERT_TRUE(base::PathExists(install_path
));
4806 // The extension should also be gone from the install directory.
4807 ASSERT_FALSE(base::PathExists(install_path
));
4809 service_
->CheckForExternalUpdates();
4810 base::RunLoop().RunUntilIdle();
4811 ASSERT_EQ(0u, loaded_
.size());
4812 ValidatePrefKeyCount(1);
4813 ValidateIntegerPref(good_crx
, "state",
4814 Extension::EXTERNAL_EXTENSION_UNINSTALLED
);
4815 ValidateIntegerPref(good_crx
, "location", location
);
4817 // Now clear the preference and reinstall.
4818 SetPrefInteg(good_crx
, "state", Extension::ENABLED
);
4821 content::WindowedNotificationObserver
observer(
4822 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
4823 content::NotificationService::AllSources());
4824 service_
->CheckForExternalUpdates();
4826 ASSERT_EQ(1u, loaded_
.size());
4828 ValidatePrefKeyCount(1);
4829 ValidateIntegerPref(good_crx
, "state", Extension::ENABLED
);
4830 ValidateIntegerPref(good_crx
, "location", location
);
4832 if (management_policy_
->MustRemainEnabled(loaded_
[0].get(), NULL
)) {
4833 EXPECT_EQ(2, provider
->visit_count());
4835 // Now test an externally triggered uninstall (deleting the registry key or
4837 provider
->RemoveExtension(good_crx
);
4840 service_
->OnExternalProviderReady(provider
);
4841 base::RunLoop().RunUntilIdle();
4842 ASSERT_EQ(0u, loaded_
.size());
4843 ValidatePrefKeyCount(0);
4845 // The extension should also be gone from the install directory.
4846 ASSERT_FALSE(base::PathExists(install_path
));
4848 // Now test the case where user uninstalls and then the extension is removed
4849 // from the external provider.
4850 content::WindowedNotificationObserver
observer(
4851 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
4852 content::NotificationService::AllSources());
4853 provider
->UpdateOrAddExtension(good_crx
, "1.0.0.1", source_path
);
4854 service_
->CheckForExternalUpdates();
4857 ASSERT_EQ(1u, loaded_
.size());
4858 ASSERT_EQ(0u, GetErrors().size());
4862 service_
->UninstallExtension(id
, false, NULL
);
4863 base::RunLoop().RunUntilIdle();
4864 ASSERT_EQ(0u, loaded_
.size());
4866 // Then remove the extension from the extension provider.
4867 provider
->RemoveExtension(good_crx
);
4869 // Should still be at 0.
4871 extensions::InstalledLoader(service_
).LoadAllExtensions();
4872 base::RunLoop().RunUntilIdle();
4873 ASSERT_EQ(0u, loaded_
.size());
4874 ValidatePrefKeyCount(1);
4876 EXPECT_EQ(5, provider
->visit_count());
4880 // Tests the external installation feature
4882 TEST_F(ExtensionServiceTest
, ExternalInstallRegistry
) {
4883 // This should all work, even when normal extension installation is disabled.
4884 InitializeEmptyExtensionService();
4885 set_extensions_enabled(false);
4887 // Now add providers. Extension system takes ownership of the objects.
4888 MockExtensionProvider
* reg_provider
=
4889 new MockExtensionProvider(service_
, Manifest::EXTERNAL_REGISTRY
);
4890 AddMockExternalProvider(reg_provider
);
4891 TestExternalProvider(reg_provider
, Manifest::EXTERNAL_REGISTRY
);
4895 TEST_F(ExtensionServiceTest
, ExternalInstallPref
) {
4896 InitializeEmptyExtensionService();
4898 // Now add providers. Extension system takes ownership of the objects.
4899 MockExtensionProvider
* pref_provider
=
4900 new MockExtensionProvider(service_
, Manifest::EXTERNAL_PREF
);
4902 AddMockExternalProvider(pref_provider
);
4903 TestExternalProvider(pref_provider
, Manifest::EXTERNAL_PREF
);
4906 TEST_F(ExtensionServiceTest
, ExternalInstallPrefUpdateUrl
) {
4907 // This should all work, even when normal extension installation is disabled.
4908 InitializeEmptyExtensionService();
4909 set_extensions_enabled(false);
4911 // TODO(skerner): The mock provider is not a good model of a provider
4912 // that works with update URLs, because it adds file and version info.
4913 // Extend the mock to work with update URLs. This test checks the
4914 // behavior that is common to all external extension visitors. The
4915 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4916 // what the visitor does results in an extension being downloaded and
4918 MockExtensionProvider
* pref_provider
=
4919 new MockExtensionProvider(service_
,
4920 Manifest::EXTERNAL_PREF_DOWNLOAD
);
4921 AddMockExternalProvider(pref_provider
);
4922 TestExternalProvider(pref_provider
, Manifest::EXTERNAL_PREF_DOWNLOAD
);
4925 TEST_F(ExtensionServiceTest
, ExternalInstallPolicyUpdateUrl
) {
4926 // This should all work, even when normal extension installation is disabled.
4927 InitializeEmptyExtensionService();
4928 set_extensions_enabled(false);
4930 // TODO(skerner): The mock provider is not a good model of a provider
4931 // that works with update URLs, because it adds file and version info.
4932 // Extend the mock to work with update URLs. This test checks the
4933 // behavior that is common to all external extension visitors. The
4934 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4935 // what the visitor does results in an extension being downloaded and
4937 MockExtensionProvider
* pref_provider
=
4938 new MockExtensionProvider(service_
,
4939 Manifest::EXTERNAL_POLICY_DOWNLOAD
);
4940 AddMockExternalProvider(pref_provider
);
4941 TestExternalProvider(pref_provider
, Manifest::EXTERNAL_POLICY_DOWNLOAD
);
4944 // Tests that external extensions get uninstalled when the external extension
4945 // providers can't account for them.
4946 TEST_F(ExtensionServiceTest
, ExternalUninstall
) {
4947 // Start the extensions service with one external extension already installed.
4948 base::FilePath source_install_dir
= data_dir_
4949 .AppendASCII("good")
4950 .AppendASCII("Extensions");
4951 base::FilePath pref_path
= source_install_dir
4953 .AppendASCII("PreferencesExternal");
4955 // This initializes the extensions service with no ExternalProviders.
4956 InitializeInstalledExtensionService(pref_path
, source_install_dir
);
4957 set_extensions_enabled(false);
4961 ASSERT_EQ(0u, GetErrors().size());
4962 ASSERT_EQ(0u, loaded_
.size());
4964 // Verify that it's not the disabled extensions flag causing it not to load.
4965 set_extensions_enabled(true);
4966 service_
->ReloadExtensionsForTest();
4967 base::RunLoop().RunUntilIdle();
4969 ASSERT_EQ(0u, GetErrors().size());
4970 ASSERT_EQ(0u, loaded_
.size());
4973 // Test that running multiple update checks simultaneously does not
4974 // keep the update from succeeding.
4975 TEST_F(ExtensionServiceTest
, MultipleExternalUpdateCheck
) {
4976 InitializeEmptyExtensionService();
4978 MockExtensionProvider
* provider
=
4979 new MockExtensionProvider(service_
, Manifest::EXTERNAL_PREF
);
4980 AddMockExternalProvider(provider
);
4982 // Verify that starting with no providers loads no extensions.
4984 ASSERT_EQ(0u, loaded_
.size());
4986 // Start two checks for updates.
4987 provider
->set_visit_count(0);
4988 service_
->CheckForExternalUpdates();
4989 service_
->CheckForExternalUpdates();
4990 base::RunLoop().RunUntilIdle();
4992 // Two calls should cause two checks for external extensions.
4993 EXPECT_EQ(2, provider
->visit_count());
4994 EXPECT_EQ(0u, GetErrors().size());
4995 EXPECT_EQ(0u, loaded_
.size());
4997 // Register a test extension externally using the mock registry provider.
4998 base::FilePath source_path
= data_dir_
.AppendASCII("good.crx");
4999 provider
->UpdateOrAddExtension(good_crx
, "1.0.0.0", source_path
);
5001 // Two checks for external updates should find the extension, and install it
5003 content::WindowedNotificationObserver
observer(
5004 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
5005 content::NotificationService::AllSources());
5006 provider
->set_visit_count(0);
5007 service_
->CheckForExternalUpdates();
5008 service_
->CheckForExternalUpdates();
5010 EXPECT_EQ(2, provider
->visit_count());
5011 ASSERT_EQ(0u, GetErrors().size());
5012 ASSERT_EQ(1u, loaded_
.size());
5013 ASSERT_EQ(Manifest::EXTERNAL_PREF
, loaded_
[0]->location());
5014 ASSERT_EQ("1.0.0.0", loaded_
[0]->version()->GetString());
5015 ValidatePrefKeyCount(1);
5016 ValidateIntegerPref(good_crx
, "state", Extension::ENABLED
);
5017 ValidateIntegerPref(good_crx
, "location", Manifest::EXTERNAL_PREF
);
5019 provider
->RemoveExtension(good_crx
);
5020 provider
->set_visit_count(0);
5021 service_
->CheckForExternalUpdates();
5022 service_
->CheckForExternalUpdates();
5023 base::RunLoop().RunUntilIdle();
5025 // Two calls should cause two checks for external extensions.
5026 // Because the external source no longer includes good_crx,
5027 // good_crx will be uninstalled. So, expect that no extensions
5029 EXPECT_EQ(2, provider
->visit_count());
5030 EXPECT_EQ(0u, GetErrors().size());
5031 EXPECT_EQ(0u, loaded_
.size());
5034 TEST_F(ExtensionServiceTest
, ExternalPrefProvider
) {
5035 InitializeEmptyExtensionService();
5037 // Test some valid extension records.
5038 // Set a base path to avoid erroring out on relative paths.
5039 // Paths starting with // are absolute on every platform we support.
5040 base::FilePath
base_path(FILE_PATH_LITERAL("//base/path"));
5041 ASSERT_TRUE(base_path
.IsAbsolute());
5042 MockProviderVisitor
visitor(base_path
);
5043 std::string json_data
=
5045 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5046 " \"external_crx\": \"RandomExtension.crx\","
5047 " \"external_version\": \"1.0\""
5049 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5050 " \"external_crx\": \"RandomExtension2.crx\","
5051 " \"external_version\": \"2.0\""
5053 " \"cccccccccccccccccccccccccccccccc\": {"
5054 " \"external_update_url\": \"http:\\\\foo.com/update\""
5057 EXPECT_EQ(3, visitor
.Visit(json_data
));
5059 // Simulate an external_extensions.json file that contains seven invalid
5061 // - One that is missing the 'external_crx' key.
5062 // - One that is missing the 'external_version' key.
5063 // - One that is specifying .. in the path.
5064 // - One that specifies both a file and update URL.
5065 // - One that specifies no file or update URL.
5066 // - One that has an update URL that is not well formed.
5067 // - One that contains a malformed version.
5068 // - One that has an invalid id.
5069 // - One that has a non-dictionary value.
5070 // - One that has an integer 'external_version' instead of a string.
5071 // The final extension is valid, and we check that it is read to make sure
5072 // failures don't stop valid records from being read.
5075 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5076 " \"external_version\": \"1.0\""
5078 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5079 " \"external_crx\": \"RandomExtension.crx\""
5081 " \"cccccccccccccccccccccccccccccccc\": {"
5082 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
5083 " \"external_version\": \"2.0\""
5085 " \"dddddddddddddddddddddddddddddddd\": {"
5086 " \"external_crx\": \"RandomExtension2.crx\","
5087 " \"external_version\": \"2.0\","
5088 " \"external_update_url\": \"http:\\\\foo.com/update\""
5090 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
5092 " \"ffffffffffffffffffffffffffffffff\": {"
5093 " \"external_update_url\": \"This string is not a valid URL\""
5095 " \"gggggggggggggggggggggggggggggggg\": {"
5096 " \"external_crx\": \"RandomExtension3.crx\","
5097 " \"external_version\": \"This is not a valid version!\""
5099 " \"This is not a valid id!\": {},"
5100 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
5101 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
5102 " \"external_crx\": \"RandomExtension4.crx\","
5103 " \"external_version\": 1.0"
5105 " \"pppppppppppppppppppppppppppppppp\": {"
5106 " \"external_crx\": \"RandomValidExtension.crx\","
5107 " \"external_version\": \"1.0\""
5110 EXPECT_EQ(1, visitor
.Visit(json_data
));
5112 // Check that if a base path is not provided, use of a relative
5114 base::FilePath empty
;
5115 MockProviderVisitor
visitor_no_relative_paths(empty
);
5117 // Use absolute paths. Expect success.
5120 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5121 " \"external_crx\": \"//RandomExtension1.crx\","
5122 " \"external_version\": \"3.0\""
5124 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5125 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
5126 " \"external_version\": \"3.0\""
5129 EXPECT_EQ(2, visitor_no_relative_paths
.Visit(json_data
));
5131 // Use a relative path. Expect that it will error out.
5134 " \"cccccccccccccccccccccccccccccccc\": {"
5135 " \"external_crx\": \"RandomExtension2.crx\","
5136 " \"external_version\": \"3.0\""
5139 EXPECT_EQ(0, visitor_no_relative_paths
.Visit(json_data
));
5141 // Test supported_locales.
5144 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5145 " \"external_crx\": \"RandomExtension.crx\","
5146 " \"external_version\": \"1.0\","
5147 " \"supported_locales\": [ \"en\" ]"
5149 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
5150 " \"external_crx\": \"RandomExtension2.crx\","
5151 " \"external_version\": \"2.0\","
5152 " \"supported_locales\": [ \"en-GB\" ]"
5154 " \"cccccccccccccccccccccccccccccccc\": {"
5155 " \"external_crx\": \"RandomExtension2.crx\","
5156 " \"external_version\": \"3.0\","
5157 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
5161 ScopedBrowserLocale
guard("en-US");
5162 EXPECT_EQ(2, visitor
.Visit(json_data
));
5165 // Test keep_if_present.
5168 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5169 " \"external_crx\": \"RandomExtension.crx\","
5170 " \"external_version\": \"1.0\","
5171 " \"keep_if_present\": true"
5175 EXPECT_EQ(0, visitor
.Visit(json_data
));
5178 // Test is_bookmark_app.
5179 MockProviderVisitor
from_bookmark_visitor(
5180 base_path
, Extension::FROM_BOOKMARK
);
5183 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5184 " \"external_crx\": \"RandomExtension.crx\","
5185 " \"external_version\": \"1.0\","
5186 " \"is_bookmark_app\": true"
5189 EXPECT_EQ(1, from_bookmark_visitor
.Visit(json_data
));
5191 // Test is_from_webstore.
5192 MockProviderVisitor
from_webstore_visitor(
5193 base_path
, Extension::FROM_WEBSTORE
);
5196 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
5197 " \"external_crx\": \"RandomExtension.crx\","
5198 " \"external_version\": \"1.0\","
5199 " \"is_from_webstore\": true"
5202 EXPECT_EQ(1, from_webstore_visitor
.Visit(json_data
));
5205 // Test loading good extensions from the profile directory.
5206 TEST_F(ExtensionServiceTest
, LoadAndRelocalizeExtensions
) {
5207 // Ensure we're testing in "en" and leave global state untouched.
5208 extension_l10n_util::ScopedLocaleForTest
testLocale("en");
5210 // Initialize the test dir with a good Preferences/extensions.
5211 base::FilePath source_install_dir
= data_dir_
5212 .AppendASCII("l10n");
5213 base::FilePath pref_path
=
5214 source_install_dir
.Append(chrome::kPreferencesFilename
);
5215 InitializeInstalledExtensionService(pref_path
, source_install_dir
);
5219 ASSERT_EQ(3u, loaded_
.size());
5221 // This was equal to "sr" on load.
5222 ValidateStringPref(loaded_
[0]->id(), keys::kCurrentLocale
, "en");
5224 // These are untouched by re-localization.
5225 ValidateStringPref(loaded_
[1]->id(), keys::kCurrentLocale
, "en");
5226 EXPECT_FALSE(IsPrefExist(loaded_
[1]->id(), keys::kCurrentLocale
));
5228 // This one starts with Serbian name, and gets re-localized into English.
5229 EXPECT_EQ("My name is simple.", loaded_
[0]->name());
5231 // These are untouched by re-localization.
5232 EXPECT_EQ("My name is simple.", loaded_
[1]->name());
5233 EXPECT_EQ("no l10n", loaded_
[2]->name());
5236 class ExtensionsReadyRecorder
: public content::NotificationObserver
{
5238 ExtensionsReadyRecorder() : ready_(false) {
5239 registrar_
.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY
,
5240 content::NotificationService::AllSources());
5243 void set_ready(bool value
) { ready_
= value
; }
5244 bool ready() { return ready_
; }
5247 virtual void Observe(int type
,
5248 const content::NotificationSource
& source
,
5249 const content::NotificationDetails
& details
) OVERRIDE
{
5251 case chrome::NOTIFICATION_EXTENSIONS_READY
:
5259 content::NotificationRegistrar registrar_
;
5263 // Test that we get enabled/disabled correctly for all the pref/command-line
5264 // combinations. We don't want to derive from the ExtensionServiceTest class
5265 // for this test, so we use ExtensionServiceTestSimple.
5267 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
5269 TEST(ExtensionServiceTestSimple
, Enabledness
) {
5270 // Make sure the PluginService singleton is destroyed at the end of the test.
5271 base::ShadowingAtExitManager at_exit_manager
;
5272 #if defined(ENABLE_PLUGINS)
5273 content::PluginService::GetInstance()->Init();
5274 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
5277 ExtensionErrorReporter::Init(false); // no noisy errors
5278 ExtensionsReadyRecorder recorder
;
5279 scoped_ptr
<TestingProfile
> profile(new TestingProfile());
5280 content::TestBrowserThreadBundle thread_bundle_
;
5281 #if defined OS_CHROMEOS
5282 chromeos::ScopedTestDeviceSettingsService device_settings_service
;
5283 chromeos::ScopedTestCrosSettings cros_settings
;
5284 scoped_ptr
<chromeos::ScopedTestUserManager
> user_manager(
5285 new chromeos::ScopedTestUserManager
);
5287 scoped_ptr
<CommandLine
> command_line
;
5288 base::FilePath install_dir
= profile
->GetPath()
5289 .AppendASCII(extensions::kInstallDirectoryName
);
5291 // By default, we are enabled.
5292 command_line
.reset(new CommandLine(CommandLine::NO_PROGRAM
));
5293 ExtensionService
* service
= static_cast<extensions::TestExtensionSystem
*>(
5294 ExtensionSystem::Get(profile
.get()))->
5295 CreateExtensionService(
5299 EXPECT_TRUE(service
->extensions_enabled());
5301 base::RunLoop().RunUntilIdle();
5302 EXPECT_TRUE(recorder
.ready());
5303 #if defined OS_CHROMEOS
5304 user_manager
.reset();
5307 // If either the command line or pref is set, we are disabled.
5308 recorder
.set_ready(false);
5309 profile
.reset(new TestingProfile());
5310 command_line
->AppendSwitch(switches::kDisableExtensions
);
5311 service
= static_cast<extensions::TestExtensionSystem
*>(
5312 ExtensionSystem::Get(profile
.get()))->
5313 CreateExtensionService(
5317 EXPECT_FALSE(service
->extensions_enabled());
5319 base::RunLoop().RunUntilIdle();
5320 EXPECT_TRUE(recorder
.ready());
5322 recorder
.set_ready(false);
5323 profile
.reset(new TestingProfile());
5324 profile
->GetPrefs()->SetBoolean(prefs::kDisableExtensions
, true);
5325 service
= static_cast<extensions::TestExtensionSystem
*>(
5326 ExtensionSystem::Get(profile
.get()))->
5327 CreateExtensionService(
5331 EXPECT_FALSE(service
->extensions_enabled());
5333 base::RunLoop().RunUntilIdle();
5334 EXPECT_TRUE(recorder
.ready());
5336 recorder
.set_ready(false);
5337 profile
.reset(new TestingProfile());
5338 profile
->GetPrefs()->SetBoolean(prefs::kDisableExtensions
, true);
5339 command_line
.reset(new CommandLine(CommandLine::NO_PROGRAM
));
5340 service
= static_cast<extensions::TestExtensionSystem
*>(
5341 ExtensionSystem::Get(profile
.get()))->
5342 CreateExtensionService(
5346 EXPECT_FALSE(service
->extensions_enabled());
5348 base::RunLoop().RunUntilIdle();
5349 EXPECT_TRUE(recorder
.ready());
5351 // Explicitly delete all the resources used in this test.
5354 // Execute any pending deletion tasks.
5355 base::RunLoop().RunUntilIdle();
5358 // Test loading extensions that require limited and unlimited storage quotas.
5359 TEST_F(ExtensionServiceTest
, StorageQuota
) {
5360 InitializeEmptyExtensionService();
5362 base::FilePath extensions_path
= data_dir_
5363 .AppendASCII("storage_quota");
5365 base::FilePath limited_quota_ext
=
5366 extensions_path
.AppendASCII("limited_quota")
5367 .AppendASCII("1.0");
5369 // The old permission name for unlimited quota was "unlimited_storage", but
5370 // we changed it to "unlimitedStorage". This tests both versions.
5371 base::FilePath unlimited_quota_ext
=
5372 extensions_path
.AppendASCII("unlimited_quota")
5373 .AppendASCII("1.0");
5374 base::FilePath unlimited_quota_ext2
=
5375 extensions_path
.AppendASCII("unlimited_quota")
5376 .AppendASCII("2.0");
5377 extensions::UnpackedInstaller::Create(service_
)->Load(limited_quota_ext
);
5378 extensions::UnpackedInstaller::Create(service_
)->Load(unlimited_quota_ext
);
5379 extensions::UnpackedInstaller::Create(service_
)->Load(unlimited_quota_ext2
);
5380 base::RunLoop().RunUntilIdle();
5382 ASSERT_EQ(3u, loaded_
.size());
5383 EXPECT_TRUE(profile_
.get());
5384 EXPECT_FALSE(profile_
->IsOffTheRecord());
5385 EXPECT_FALSE(profile_
->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5386 loaded_
[0]->url()));
5387 EXPECT_TRUE(profile_
->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5388 loaded_
[1]->url()));
5389 EXPECT_TRUE(profile_
->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5390 loaded_
[2]->url()));
5393 // Tests ComponentLoader::Add().
5394 TEST_F(ExtensionServiceTest
, ComponentExtensions
) {
5395 InitializeEmptyExtensionService();
5397 // Component extensions should work even when extensions are disabled.
5398 set_extensions_enabled(false);
5400 base::FilePath path
= data_dir_
5401 .AppendASCII("good")
5402 .AppendASCII("Extensions")
5403 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
5404 .AppendASCII("1.0.0.0");
5406 std::string manifest
;
5407 ASSERT_TRUE(base::ReadFileToString(
5408 path
.Append(extensions::kManifestFilename
), &manifest
));
5410 service_
->component_loader()->Add(manifest
, path
);
5413 // Note that we do not pump messages -- the extension should be loaded
5416 EXPECT_EQ(0u, GetErrors().size());
5417 ASSERT_EQ(1u, loaded_
.size());
5418 EXPECT_EQ(Manifest::COMPONENT
, loaded_
[0]->location());
5419 EXPECT_EQ(1u, registry_
->enabled_extensions().size());
5421 // Component extensions get a prefs entry on first install.
5422 ValidatePrefKeyCount(1);
5424 // Reload all extensions, and make sure it comes back.
5425 std::string extension_id
= (*registry_
->enabled_extensions().begin())->id();
5427 service_
->ReloadExtensionsForTest();
5428 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
5429 EXPECT_EQ(extension_id
, (*registry_
->enabled_extensions().begin())->id());
5434 class TestSyncProcessorStub
: public syncer::SyncChangeProcessor
{
5435 virtual syncer::SyncError
ProcessSyncChanges(
5436 const tracked_objects::Location
& from_here
,
5437 const syncer::SyncChangeList
& change_list
) OVERRIDE
{
5438 return syncer::SyncError();
5441 virtual syncer::SyncDataList
GetAllSyncData(
5442 syncer::ModelType type
) const OVERRIDE
{
5443 return syncer::SyncDataList();
5449 TEST_F(ExtensionServiceTest
, DeferredSyncStartupPreInstalledComponent
) {
5450 InitializeEmptyExtensionService();
5451 InitializeExtensionSyncService();
5453 bool flare_was_called
= false;
5454 syncer::ModelType
triggered_type(syncer::UNSPECIFIED
);
5455 base::WeakPtrFactory
<ExtensionServiceTest
> factory(this);
5456 extension_sync_service_
->SetSyncStartFlare(
5457 base::Bind(&ExtensionServiceTest::MockSyncStartFlare
,
5458 factory
.GetWeakPtr(),
5459 &flare_was_called
, // Safe due to WeakPtrFactory scope.
5460 &triggered_type
)); // Safe due to WeakPtrFactory scope.
5462 // Install a component extension.
5463 std::string manifest
;
5464 ASSERT_TRUE(base::ReadFileToString(
5465 good0_path().Append(extensions::kManifestFilename
), &manifest
));
5466 service_
->component_loader()->Add(manifest
, good0_path());
5467 ASSERT_FALSE(service_
->is_ready());
5469 ASSERT_TRUE(service_
->is_ready());
5471 // Extensions added before service is_ready() don't trigger sync startup.
5472 EXPECT_FALSE(flare_was_called
);
5473 ASSERT_EQ(syncer::UNSPECIFIED
, triggered_type
);
5476 TEST_F(ExtensionServiceTest
, DeferredSyncStartupPreInstalledNormal
) {
5477 InitializeGoodInstalledExtensionService();
5478 InitializeExtensionSyncService();
5480 bool flare_was_called
= false;
5481 syncer::ModelType
triggered_type(syncer::UNSPECIFIED
);
5482 base::WeakPtrFactory
<ExtensionServiceTest
> factory(this);
5483 extension_sync_service_
->SetSyncStartFlare(
5484 base::Bind(&ExtensionServiceTest::MockSyncStartFlare
,
5485 factory
.GetWeakPtr(),
5486 &flare_was_called
, // Safe due to WeakPtrFactory scope.
5487 &triggered_type
)); // Safe due to WeakPtrFactory scope.
5489 ASSERT_FALSE(service_
->is_ready());
5491 ASSERT_EQ(3u, loaded_
.size());
5492 ASSERT_TRUE(service_
->is_ready());
5494 // Extensions added before service is_ready() don't trigger sync startup.
5495 EXPECT_FALSE(flare_was_called
);
5496 ASSERT_EQ(syncer::UNSPECIFIED
, triggered_type
);
5499 TEST_F(ExtensionServiceTest
, DeferredSyncStartupOnInstall
) {
5500 InitializeEmptyExtensionService();
5501 InitializeExtensionSyncService();
5503 ASSERT_TRUE(service_
->is_ready());
5505 bool flare_was_called
= false;
5506 syncer::ModelType
triggered_type(syncer::UNSPECIFIED
);
5507 base::WeakPtrFactory
<ExtensionServiceTest
> factory(this);
5508 extension_sync_service_
->SetSyncStartFlare(
5509 base::Bind(&ExtensionServiceTest::MockSyncStartFlare
,
5510 factory
.GetWeakPtr(),
5511 &flare_was_called
, // Safe due to WeakPtrFactory scope.
5512 &triggered_type
)); // Safe due to WeakPtrFactory scope.
5514 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
5515 InstallCRX(path
, INSTALL_NEW
);
5517 EXPECT_TRUE(flare_was_called
);
5518 EXPECT_EQ(syncer::EXTENSIONS
, triggered_type
);
5521 flare_was_called
= false;
5522 triggered_type
= syncer::UNSPECIFIED
;
5524 // Once sync starts, flare should no longer be invoked.
5525 extension_sync_service_
->MergeDataAndStartSyncing(
5526 syncer::EXTENSIONS
, syncer::SyncDataList(),
5527 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5528 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5529 path
= data_dir_
.AppendASCII("page_action.crx");
5530 InstallCRX(path
, INSTALL_NEW
);
5531 EXPECT_FALSE(flare_was_called
);
5532 ASSERT_EQ(syncer::UNSPECIFIED
, triggered_type
);
5535 TEST_F(ExtensionServiceTest
, DisableExtensionFromSync
) {
5536 // Start the extensions service with one external extension already installed.
5537 base::FilePath source_install_dir
= data_dir_
5538 .AppendASCII("good")
5539 .AppendASCII("Extensions");
5540 base::FilePath pref_path
=
5541 source_install_dir
.DirName().Append(chrome::kPreferencesFilename
);
5543 InitializeInstalledExtensionService(pref_path
, source_install_dir
);
5544 InitializeExtensionSyncService();
5546 // The user has enabled sync.
5547 ProfileSyncService
* sync_service
=
5548 ProfileSyncServiceFactory::GetForProfile(profile_
.get());
5549 sync_service
->SetSyncSetupCompleted();
5552 ASSERT_TRUE(service_
->is_ready());
5554 ASSERT_EQ(3u, loaded_
.size());
5556 // We start enabled.
5557 const Extension
* extension
= service_
->GetExtensionById(good0
, true);
5558 ASSERT_TRUE(extension
);
5559 ASSERT_TRUE(service_
->IsExtensionEnabled(good0
));
5560 extensions::ExtensionSyncData
disable_good_crx(*extension
, false, false);
5562 // Then sync data arrives telling us to disable |good0|.
5563 syncer::SyncDataList sync_data
;
5564 sync_data
.push_back(disable_good_crx
.GetSyncData());
5565 extension_sync_service_
->MergeDataAndStartSyncing(
5566 syncer::EXTENSIONS
, sync_data
,
5567 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5568 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5569 ASSERT_FALSE(service_
->IsExtensionEnabled(good0
));
5572 TEST_F(ExtensionServiceTest
, DontDisableExtensionWithPendingEnableFromSync
) {
5573 // Start the extensions service with one external extension already installed.
5574 base::FilePath source_install_dir
= data_dir_
5575 .AppendASCII("good")
5576 .AppendASCII("Extensions");
5577 base::FilePath pref_path
=
5578 source_install_dir
.DirName().Append(chrome::kPreferencesFilename
);
5580 InitializeInstalledExtensionService(pref_path
, source_install_dir
);
5581 InitializeExtensionSyncService();
5583 // The user has enabled sync.
5584 ProfileSyncService
* sync_service
=
5585 ProfileSyncServiceFactory::GetForProfile(profile_
.get());
5586 sync_service
->SetSyncSetupCompleted();
5589 ASSERT_TRUE(service_
->is_ready());
5590 ASSERT_EQ(3u, loaded_
.size());
5592 const Extension
* extension
= service_
->GetExtensionById(good0
, true);
5593 ASSERT_TRUE(service_
->IsExtensionEnabled(good0
));
5595 // Disable extension before first sync data arrives.
5596 service_
->DisableExtension(good0
, Extension::DISABLE_USER_ACTION
);
5597 ASSERT_FALSE(service_
->IsExtensionEnabled(good0
));
5599 // Enable extension - this is now the most recent state.
5600 service_
->EnableExtension(good0
);
5601 ASSERT_TRUE(service_
->IsExtensionEnabled(good0
));
5603 // Now sync data comes in that says to disable good0. This should be
5605 extensions::ExtensionSyncData
disable_good_crx(*extension
, false, false);
5606 syncer::SyncDataList sync_data
;
5607 sync_data
.push_back(disable_good_crx
.GetSyncData());
5608 extension_sync_service_
->MergeDataAndStartSyncing(
5609 syncer::EXTENSIONS
, sync_data
,
5610 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5611 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5613 // The extension was enabled locally before the sync data arrived, so it
5614 // should still be enabled now.
5615 ASSERT_TRUE(service_
->IsExtensionEnabled(good0
));
5618 TEST_F(ExtensionServiceTest
, GetSyncData
) {
5619 InitializeEmptyExtensionService();
5620 InitializeExtensionSyncService();
5621 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
5622 const Extension
* extension
= service_
->GetInstalledExtension(good_crx
);
5623 ASSERT_TRUE(extension
);
5625 extension_sync_service_
->MergeDataAndStartSyncing(
5626 syncer::EXTENSIONS
, syncer::SyncDataList(),
5627 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5628 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5630 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5631 syncer::EXTENSIONS
);
5632 ASSERT_EQ(list
.size(), 1U);
5633 extensions::ExtensionSyncData
data(list
[0]);
5634 EXPECT_EQ(extension
->id(), data
.id());
5635 EXPECT_FALSE(data
.uninstalled());
5636 EXPECT_EQ(service_
->IsExtensionEnabled(good_crx
), data
.enabled());
5637 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()),
5638 data
.incognito_enabled());
5639 EXPECT_TRUE(data
.version().Equals(*extension
->version()));
5640 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension
),
5642 EXPECT_EQ(extension
->name(), data
.name());
5645 TEST_F(ExtensionServiceTest
, GetSyncDataTerminated
) {
5646 InitializeEmptyExtensionService();
5647 InitializeExtensionSyncService();
5648 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
5649 TerminateExtension(good_crx
);
5650 const Extension
* extension
= service_
->GetInstalledExtension(good_crx
);
5651 ASSERT_TRUE(extension
);
5653 TestSyncProcessorStub processor
;
5654 extension_sync_service_
->MergeDataAndStartSyncing(
5655 syncer::EXTENSIONS
, syncer::SyncDataList(),
5656 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5657 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5659 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5660 syncer::EXTENSIONS
);
5661 ASSERT_EQ(list
.size(), 1U);
5662 extensions::ExtensionSyncData
data(list
[0]);
5663 EXPECT_EQ(extension
->id(), data
.id());
5664 EXPECT_FALSE(data
.uninstalled());
5665 EXPECT_EQ(service_
->IsExtensionEnabled(good_crx
), data
.enabled());
5666 EXPECT_EQ(extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()),
5667 data
.incognito_enabled());
5668 EXPECT_TRUE(data
.version().Equals(*extension
->version()));
5669 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension
),
5671 EXPECT_EQ(extension
->name(), data
.name());
5674 TEST_F(ExtensionServiceTest
, GetSyncDataFilter
) {
5675 InitializeEmptyExtensionService();
5676 InitializeExtensionSyncService();
5677 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
5678 const Extension
* extension
= service_
->GetInstalledExtension(good_crx
);
5679 ASSERT_TRUE(extension
);
5681 TestSyncProcessorStub processor
;
5682 extension_sync_service_
->MergeDataAndStartSyncing(syncer::APPS
,
5683 syncer::SyncDataList(),
5684 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5685 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5687 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5688 syncer::EXTENSIONS
);
5689 ASSERT_EQ(list
.size(), 0U);
5692 TEST_F(ExtensionServiceTest
, GetSyncExtensionDataUserSettings
) {
5693 InitializeEmptyExtensionService();
5694 InitializeProcessManager();
5695 InitializeExtensionSyncService();
5696 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
5697 const Extension
* extension
= service_
->GetInstalledExtension(good_crx
);
5698 ASSERT_TRUE(extension
);
5700 TestSyncProcessorStub processor
;
5701 extension_sync_service_
->MergeDataAndStartSyncing(
5702 syncer::EXTENSIONS
, syncer::SyncDataList(),
5703 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5704 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5707 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5708 syncer::EXTENSIONS
);
5709 ASSERT_EQ(list
.size(), 1U);
5710 extensions::ExtensionSyncData
data(list
[0]);
5711 EXPECT_TRUE(data
.enabled());
5712 EXPECT_FALSE(data
.incognito_enabled());
5715 service_
->DisableExtension(good_crx
, Extension::DISABLE_USER_ACTION
);
5717 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5718 syncer::EXTENSIONS
);
5719 ASSERT_EQ(list
.size(), 1U);
5720 extensions::ExtensionSyncData
data(list
[0]);
5721 EXPECT_FALSE(data
.enabled());
5722 EXPECT_FALSE(data
.incognito_enabled());
5725 extensions::util::SetIsIncognitoEnabled(good_crx
, profile_
.get(), true);
5727 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5728 syncer::EXTENSIONS
);
5729 ASSERT_EQ(list
.size(), 1U);
5730 extensions::ExtensionSyncData
data(list
[0]);
5731 EXPECT_FALSE(data
.enabled());
5732 EXPECT_TRUE(data
.incognito_enabled());
5735 service_
->EnableExtension(good_crx
);
5737 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5738 syncer::EXTENSIONS
);
5739 ASSERT_EQ(list
.size(), 1U);
5740 extensions::ExtensionSyncData
data(list
[0]);
5741 EXPECT_TRUE(data
.enabled());
5742 EXPECT_TRUE(data
.incognito_enabled());
5746 TEST_F(ExtensionServiceTest
, SyncForUninstalledExternalExtension
) {
5747 InitializeEmptyExtensionService();
5748 InitializeExtensionSyncService();
5749 InstallCRXWithLocation(data_dir_
.AppendASCII("good.crx"),
5750 Manifest::EXTERNAL_PREF
, INSTALL_NEW
);
5751 const Extension
* extension
= service_
->GetInstalledExtension(good_crx
);
5752 ASSERT_TRUE(extension
);
5754 TestSyncProcessorStub processor
;
5755 extension_sync_service_
->MergeDataAndStartSyncing(
5756 syncer::EXTENSIONS
, syncer::SyncDataList(),
5757 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5758 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5760 UninstallExtension(good_crx
, false);
5761 EXPECT_TRUE(service_
->IsExternalExtensionUninstalled(good_crx
));
5763 sync_pb::EntitySpecifics specifics
;
5764 sync_pb::AppSpecifics
* app_specifics
= specifics
.mutable_app();
5765 sync_pb::ExtensionSpecifics
* extension_specifics
=
5766 app_specifics
->mutable_extension();
5767 extension_specifics
->set_id(good_crx
);
5768 extension_specifics
->set_version("1.0");
5769 extension_specifics
->set_enabled(true);
5771 syncer::SyncData sync_data
=
5772 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
5773 syncer::SyncChange
sync_change(FROM_HERE
,
5774 syncer::SyncChange::ACTION_UPDATE
,
5776 syncer::SyncChangeList
list(1);
5777 list
[0] = sync_change
;
5779 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
5780 EXPECT_TRUE(service_
->IsExternalExtensionUninstalled(good_crx
));
5783 TEST_F(ExtensionServiceTest
, GetSyncAppDataUserSettings
) {
5784 InitializeEmptyExtensionService();
5785 InitializeExtensionSyncService();
5786 const Extension
* app
=
5787 PackAndInstallCRX(data_dir_
.AppendASCII("app"), INSTALL_NEW
);
5789 ASSERT_TRUE(app
->is_app());
5791 TestSyncProcessorStub processor
;
5792 extension_sync_service_
->MergeDataAndStartSyncing(syncer::APPS
,
5793 syncer::SyncDataList(),
5794 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5795 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5797 syncer::StringOrdinal initial_ordinal
=
5798 syncer::StringOrdinal::CreateInitialOrdinal();
5800 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5802 ASSERT_EQ(list
.size(), 1U);
5804 extensions::AppSyncData
app_sync_data(list
[0]);
5805 EXPECT_TRUE(initial_ordinal
.Equals(app_sync_data
.app_launch_ordinal()));
5806 EXPECT_TRUE(initial_ordinal
.Equals(app_sync_data
.page_ordinal()));
5809 AppSorting
* sorting
= service_
->extension_prefs()->app_sorting();
5810 sorting
->SetAppLaunchOrdinal(app
->id(), initial_ordinal
.CreateAfter());
5812 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5814 ASSERT_EQ(list
.size(), 1U);
5816 extensions::AppSyncData
app_sync_data(list
[0]);
5817 EXPECT_TRUE(initial_ordinal
.LessThan(app_sync_data
.app_launch_ordinal()));
5818 EXPECT_TRUE(initial_ordinal
.Equals(app_sync_data
.page_ordinal()));
5821 sorting
->SetPageOrdinal(app
->id(), initial_ordinal
.CreateAfter());
5823 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5825 ASSERT_EQ(list
.size(), 1U);
5827 extensions::AppSyncData
app_sync_data(list
[0]);
5828 EXPECT_TRUE(initial_ordinal
.LessThan(app_sync_data
.app_launch_ordinal()));
5829 EXPECT_TRUE(initial_ordinal
.LessThan(app_sync_data
.page_ordinal()));
5833 TEST_F(ExtensionServiceTest
, GetSyncAppDataUserSettingsOnExtensionMoved
) {
5834 InitializeEmptyExtensionService();
5835 InitializeExtensionSyncService();
5836 const size_t kAppCount
= 3;
5837 const Extension
* apps
[kAppCount
];
5838 apps
[0] = PackAndInstallCRX(data_dir_
.AppendASCII("app1"), INSTALL_NEW
);
5839 apps
[1] = PackAndInstallCRX(data_dir_
.AppendASCII("app2"), INSTALL_NEW
);
5840 apps
[2] = PackAndInstallCRX(data_dir_
.AppendASCII("app4"), INSTALL_NEW
);
5841 for (size_t i
= 0; i
< kAppCount
; ++i
) {
5842 ASSERT_TRUE(apps
[i
]);
5843 ASSERT_TRUE(apps
[i
]->is_app());
5846 TestSyncProcessorStub processor
;
5847 extension_sync_service_
->MergeDataAndStartSyncing(syncer::APPS
,
5848 syncer::SyncDataList(),
5849 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5850 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5852 service_
->OnExtensionMoved(apps
[0]->id(), apps
[1]->id(), apps
[2]->id());
5854 syncer::SyncDataList list
= extension_sync_service_
->GetAllSyncData(
5856 ASSERT_EQ(list
.size(), 3U);
5858 extensions::AppSyncData data
[kAppCount
];
5859 for (size_t i
= 0; i
< kAppCount
; ++i
) {
5860 data
[i
] = extensions::AppSyncData(list
[i
]);
5863 // The sync data is not always in the same order our apps were installed in,
5864 // so we do that sorting here so we can make sure the values are changed as
5866 syncer::StringOrdinal app_launch_ordinals
[kAppCount
];
5867 for (size_t i
= 0; i
< kAppCount
; ++i
) {
5868 for (size_t j
= 0; j
< kAppCount
; ++j
) {
5869 if (apps
[i
]->id() == data
[j
].id())
5870 app_launch_ordinals
[i
] = data
[j
].app_launch_ordinal();
5874 EXPECT_TRUE(app_launch_ordinals
[1].LessThan(app_launch_ordinals
[0]));
5875 EXPECT_TRUE(app_launch_ordinals
[0].LessThan(app_launch_ordinals
[2]));
5879 TEST_F(ExtensionServiceTest
, GetSyncDataList
) {
5880 InitializeEmptyExtensionService();
5881 InitializeExtensionSyncService();
5882 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
5883 InstallCRX(data_dir_
.AppendASCII("page_action.crx"), INSTALL_NEW
);
5884 InstallCRX(data_dir_
.AppendASCII("theme.crx"), INSTALL_NEW
);
5885 InstallCRX(data_dir_
.AppendASCII("theme2.crx"), INSTALL_NEW
);
5887 TestSyncProcessorStub processor
;
5888 extension_sync_service_
->MergeDataAndStartSyncing(
5889 syncer::APPS
, syncer::SyncDataList(),
5890 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5891 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5892 extension_sync_service_
->MergeDataAndStartSyncing(
5893 syncer::EXTENSIONS
, syncer::SyncDataList(),
5894 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5895 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5897 service_
->DisableExtension(page_action
, Extension::DISABLE_USER_ACTION
);
5898 TerminateExtension(theme2_crx
);
5900 EXPECT_EQ(0u, extension_sync_service_
->GetAllSyncData(syncer::APPS
).size());
5901 EXPECT_EQ(2u, extension_sync_service_
->
5902 GetAllSyncData(syncer::EXTENSIONS
).size());
5905 TEST_F(ExtensionServiceTest
, ProcessSyncDataUninstall
) {
5906 InitializeEmptyExtensionService();
5907 InitializeExtensionSyncService();
5908 TestSyncProcessorStub processor
;
5909 extension_sync_service_
->MergeDataAndStartSyncing(
5910 syncer::EXTENSIONS
, syncer::SyncDataList(),
5911 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
5912 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
5914 sync_pb::EntitySpecifics specifics
;
5915 sync_pb::ExtensionSpecifics
* ext_specifics
= specifics
.mutable_extension();
5916 ext_specifics
->set_id(good_crx
);
5917 ext_specifics
->set_version("1.0");
5918 syncer::SyncData sync_data
=
5919 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
5920 syncer::SyncChange
sync_change(FROM_HERE
,
5921 syncer::SyncChange::ACTION_DELETE
,
5923 syncer::SyncChangeList
list(1);
5924 list
[0] = sync_change
;
5926 // Should do nothing.
5927 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
5928 EXPECT_FALSE(service_
->GetExtensionById(good_crx
, true));
5930 // Install the extension.
5931 base::FilePath extension_path
= data_dir_
.AppendASCII("good.crx");
5932 InstallCRX(extension_path
, INSTALL_NEW
);
5933 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, true));
5935 // Should uninstall the extension.
5936 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
5937 EXPECT_FALSE(service_
->GetExtensionById(good_crx
, true));
5939 // Should again do nothing.
5940 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
5941 EXPECT_FALSE(service_
->GetExtensionById(good_crx
, true));
5944 TEST_F(ExtensionServiceTest
, ProcessSyncDataWrongType
) {
5945 InitializeEmptyExtensionService();
5946 InitializeExtensionSyncService();
5948 // Install the extension.
5949 base::FilePath extension_path
= data_dir_
.AppendASCII("good.crx");
5950 InstallCRX(extension_path
, INSTALL_NEW
);
5951 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, true));
5953 sync_pb::EntitySpecifics specifics
;
5954 sync_pb::AppSpecifics
* app_specifics
= specifics
.mutable_app();
5955 sync_pb::ExtensionSpecifics
* extension_specifics
=
5956 app_specifics
->mutable_extension();
5957 extension_specifics
->set_id(good_crx
);
5958 extension_specifics
->set_version(
5959 service_
->GetInstalledExtension(good_crx
)->version()->GetString());
5962 extension_specifics
->set_enabled(true);
5963 syncer::SyncData sync_data
=
5964 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
5965 syncer::SyncChange
sync_change(FROM_HERE
,
5966 syncer::SyncChange::ACTION_DELETE
,
5968 syncer::SyncChangeList
list(1);
5969 list
[0] = sync_change
;
5971 // Should do nothing
5972 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
5973 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, true));
5977 extension_specifics
->set_enabled(false);
5978 syncer::SyncData sync_data
=
5979 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
5980 syncer::SyncChange
sync_change(FROM_HERE
,
5981 syncer::SyncChange::ACTION_UPDATE
,
5983 syncer::SyncChangeList
list(1);
5984 list
[0] = sync_change
;
5986 // Should again do nothing.
5987 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
5988 EXPECT_TRUE(service_
->GetExtensionById(good_crx
, false));
5992 TEST_F(ExtensionServiceTest
, ProcessSyncDataSettings
) {
5993 InitializeEmptyExtensionService();
5994 InitializeProcessManager();
5995 InitializeExtensionSyncService();
5996 TestSyncProcessorStub processor
;
5997 extension_sync_service_
->MergeDataAndStartSyncing(
5998 syncer::EXTENSIONS
, syncer::SyncDataList(),
5999 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
6000 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
6002 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
6003 EXPECT_TRUE(service_
->IsExtensionEnabled(good_crx
));
6004 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()));
6006 sync_pb::EntitySpecifics specifics
;
6007 sync_pb::ExtensionSpecifics
* ext_specifics
= specifics
.mutable_extension();
6008 ext_specifics
->set_id(good_crx
);
6009 ext_specifics
->set_version(
6010 service_
->GetInstalledExtension(good_crx
)->version()->GetString());
6011 ext_specifics
->set_enabled(false);
6014 syncer::SyncData sync_data
=
6015 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
6016 syncer::SyncChange
sync_change(FROM_HERE
,
6017 syncer::SyncChange::ACTION_UPDATE
,
6019 syncer::SyncChangeList
list(1);
6020 list
[0] = sync_change
;
6021 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
6022 EXPECT_FALSE(service_
->IsExtensionEnabled(good_crx
));
6024 extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()));
6028 ext_specifics
->set_enabled(true);
6029 ext_specifics
->set_incognito_enabled(true);
6030 syncer::SyncData sync_data
=
6031 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
6032 syncer::SyncChange
sync_change(FROM_HERE
,
6033 syncer::SyncChange::ACTION_UPDATE
,
6035 syncer::SyncChangeList
list(1);
6036 list
[0] = sync_change
;
6037 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
6038 EXPECT_TRUE(service_
->IsExtensionEnabled(good_crx
));
6039 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()));
6043 ext_specifics
->set_enabled(false);
6044 ext_specifics
->set_incognito_enabled(true);
6045 syncer::SyncData sync_data
=
6046 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
6047 syncer::SyncChange
sync_change(FROM_HERE
,
6048 syncer::SyncChange::ACTION_UPDATE
,
6050 syncer::SyncChangeList
list(1);
6051 list
[0] = sync_change
;
6052 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
6053 EXPECT_FALSE(service_
->IsExtensionEnabled(good_crx
));
6054 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()));
6057 EXPECT_FALSE(service_
->pending_extension_manager()->IsIdPending(good_crx
));
6060 TEST_F(ExtensionServiceTest
, ProcessSyncDataTerminatedExtension
) {
6061 InitializeExtensionServiceWithUpdater();
6062 InitializeExtensionSyncService();
6063 TestSyncProcessorStub processor
;
6064 extension_sync_service_
->MergeDataAndStartSyncing(
6065 syncer::EXTENSIONS
, syncer::SyncDataList(),
6066 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
6067 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
6069 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
6070 TerminateExtension(good_crx
);
6071 EXPECT_TRUE(service_
->IsExtensionEnabled(good_crx
));
6072 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()));
6074 sync_pb::EntitySpecifics specifics
;
6075 sync_pb::ExtensionSpecifics
* ext_specifics
= specifics
.mutable_extension();
6076 ext_specifics
->set_id(good_crx
);
6077 ext_specifics
->set_version(
6078 service_
->GetInstalledExtension(good_crx
)->version()->GetString());
6079 ext_specifics
->set_enabled(false);
6080 ext_specifics
->set_incognito_enabled(true);
6081 syncer::SyncData sync_data
=
6082 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
6083 syncer::SyncChange
sync_change(FROM_HERE
,
6084 syncer::SyncChange::ACTION_UPDATE
,
6086 syncer::SyncChangeList
list(1);
6087 list
[0] = sync_change
;
6089 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
6090 EXPECT_FALSE(service_
->IsExtensionEnabled(good_crx
));
6091 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()));
6093 EXPECT_FALSE(service_
->pending_extension_manager()->IsIdPending(good_crx
));
6096 TEST_F(ExtensionServiceTest
, ProcessSyncDataVersionCheck
) {
6097 InitializeExtensionServiceWithUpdater();
6098 InitializeExtensionSyncService();
6099 TestSyncProcessorStub processor
;
6100 extension_sync_service_
->MergeDataAndStartSyncing(
6101 syncer::EXTENSIONS
, syncer::SyncDataList(),
6102 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
6103 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
6105 InstallCRX(data_dir_
.AppendASCII("good.crx"), INSTALL_NEW
);
6106 EXPECT_TRUE(service_
->IsExtensionEnabled(good_crx
));
6107 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()));
6109 sync_pb::EntitySpecifics specifics
;
6110 sync_pb::ExtensionSpecifics
* ext_specifics
= specifics
.mutable_extension();
6111 ext_specifics
->set_id(good_crx
);
6112 ext_specifics
->set_enabled(true);
6115 ext_specifics
->set_version(
6116 service_
->GetInstalledExtension(good_crx
)->version()->GetString());
6117 syncer::SyncData sync_data
=
6118 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
6119 syncer::SyncChange
sync_change(FROM_HERE
,
6120 syncer::SyncChange::ACTION_UPDATE
,
6122 syncer::SyncChangeList
list(1);
6123 list
[0] = sync_change
;
6125 // Should do nothing if extension version == sync version.
6126 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
6127 EXPECT_FALSE(service_
->updater()->WillCheckSoon());
6130 // Should do nothing if extension version > sync version (but see
6131 // the TODO in ProcessExtensionSyncData).
6133 ext_specifics
->set_version("0.0.0.0");
6134 syncer::SyncData sync_data
=
6135 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
6136 syncer::SyncChange
sync_change(FROM_HERE
,
6137 syncer::SyncChange::ACTION_UPDATE
,
6139 syncer::SyncChangeList
list(1);
6140 list
[0] = sync_change
;
6142 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
6143 EXPECT_FALSE(service_
->updater()->WillCheckSoon());
6146 // Should kick off an update if extension version < sync version.
6148 ext_specifics
->set_version("9.9.9.9");
6149 syncer::SyncData sync_data
=
6150 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
6151 syncer::SyncChange
sync_change(FROM_HERE
,
6152 syncer::SyncChange::ACTION_UPDATE
,
6154 syncer::SyncChangeList
list(1);
6155 list
[0] = sync_change
;
6157 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
6158 EXPECT_TRUE(service_
->updater()->WillCheckSoon());
6161 EXPECT_FALSE(service_
->pending_extension_manager()->IsIdPending(good_crx
));
6164 TEST_F(ExtensionServiceTest
, ProcessSyncDataNotInstalled
) {
6165 InitializeExtensionServiceWithUpdater();
6166 InitializeExtensionSyncService();
6167 TestSyncProcessorStub processor
;
6168 extension_sync_service_
->MergeDataAndStartSyncing(
6169 syncer::EXTENSIONS
, syncer::SyncDataList(),
6170 scoped_ptr
<syncer::SyncChangeProcessor
>(new TestSyncProcessorStub
),
6171 scoped_ptr
<syncer::SyncErrorFactory
>(new syncer::SyncErrorFactoryMock()));
6173 sync_pb::EntitySpecifics specifics
;
6174 sync_pb::ExtensionSpecifics
* ext_specifics
= specifics
.mutable_extension();
6175 ext_specifics
->set_id(good_crx
);
6176 ext_specifics
->set_enabled(false);
6177 ext_specifics
->set_incognito_enabled(true);
6178 ext_specifics
->set_update_url("http://www.google.com/");
6179 ext_specifics
->set_version("1.2.3.4");
6180 syncer::SyncData sync_data
=
6181 syncer::SyncData::CreateLocalData(good_crx
, "Name", specifics
);
6182 syncer::SyncChange
sync_change(FROM_HERE
,
6183 syncer::SyncChange::ACTION_UPDATE
,
6185 syncer::SyncChangeList
list(1);
6186 list
[0] = sync_change
;
6189 EXPECT_TRUE(service_
->IsExtensionEnabled(good_crx
));
6190 EXPECT_FALSE(extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()));
6191 extension_sync_service_
->ProcessSyncChanges(FROM_HERE
, list
);
6192 EXPECT_TRUE(service_
->updater()->WillCheckSoon());
6193 EXPECT_FALSE(service_
->IsExtensionEnabled(good_crx
));
6194 EXPECT_TRUE(extensions::util::IsIncognitoEnabled(good_crx
, profile_
.get()));
6196 const extensions::PendingExtensionInfo
* info
;
6197 EXPECT_TRUE((info
= service_
->pending_extension_manager()->
6198 GetById(good_crx
)));
6199 EXPECT_EQ(ext_specifics
->update_url(), info
->update_url().spec());
6200 EXPECT_TRUE(info
->is_from_sync());
6201 EXPECT_TRUE(info
->install_silently());
6202 EXPECT_EQ(Manifest::INTERNAL
, info
->install_source());
6203 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
6206 TEST_F(ExtensionServiceTest
, InstallPriorityExternalUpdateUrl
) {
6207 InitializeEmptyExtensionService();
6209 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
6210 InstallCRX(path
, INSTALL_NEW
);
6211 ValidatePrefKeyCount(1u);
6212 ValidateIntegerPref(good_crx
, "state", Extension::ENABLED
);
6213 ValidateIntegerPref(good_crx
, "location", Manifest::INTERNAL
);
6215 extensions::PendingExtensionManager
* pending
=
6216 service_
->pending_extension_manager();
6217 EXPECT_FALSE(pending
->IsIdPending(kGoodId
));
6219 // Skip install when the location is the same.
6221 service_
->OnExternalExtensionUpdateUrlFound(
6222 kGoodId
, GURL(kGoodUpdateURL
), Manifest::INTERNAL
,
6223 Extension::NO_FLAGS
, false));
6224 EXPECT_FALSE(pending
->IsIdPending(kGoodId
));
6226 // Install when the location has higher priority.
6228 service_
->OnExternalExtensionUpdateUrlFound(
6229 kGoodId
, GURL(kGoodUpdateURL
), Manifest::EXTERNAL_POLICY_DOWNLOAD
,
6230 Extension::NO_FLAGS
, false));
6231 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6233 // Try the low priority again. Should be rejected.
6235 service_
->OnExternalExtensionUpdateUrlFound(
6236 kGoodId
, GURL(kGoodUpdateURL
), Manifest::EXTERNAL_PREF_DOWNLOAD
,
6237 Extension::NO_FLAGS
, false));
6238 // The existing record should still be present in the pending extension
6240 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6242 pending
->Remove(kGoodId
);
6244 // Skip install when the location has the same priority as the installed
6246 EXPECT_FALSE(service_
->OnExternalExtensionUpdateUrlFound(
6247 kGoodId
, GURL(kGoodUpdateURL
), Manifest::INTERNAL
,
6248 Extension::NO_FLAGS
, false));
6250 EXPECT_FALSE(pending
->IsIdPending(kGoodId
));
6253 TEST_F(ExtensionServiceTest
, InstallPriorityExternalLocalFile
) {
6254 Version
older_version("0.1.0.0");
6255 Version
newer_version("2.0.0.0");
6257 // We don't want the extension to be installed. A path that doesn't
6258 // point to a valid CRX ensures this.
6259 const base::FilePath kInvalidPathToCrx
= base::FilePath();
6261 const int kCreationFlags
= 0;
6262 const bool kDontMarkAcknowledged
= false;
6264 InitializeEmptyExtensionService();
6266 // The test below uses install source constants to test that
6267 // priority is enforced. It assumes a specific ranking of install
6268 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
6269 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
6270 // The following assertions verify these assumptions:
6271 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY
,
6272 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY
,
6273 Manifest::EXTERNAL_PREF
));
6274 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY
,
6275 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY
,
6276 Manifest::INTERNAL
));
6277 ASSERT_EQ(Manifest::EXTERNAL_PREF
,
6278 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF
,
6279 Manifest::INTERNAL
));
6281 extensions::PendingExtensionManager
* pending
=
6282 service_
->pending_extension_manager();
6283 EXPECT_FALSE(pending
->IsIdPending(kGoodId
));
6286 // Simulate an external source adding the extension as INTERNAL.
6287 content::WindowedNotificationObserver
observer(
6288 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6289 content::NotificationService::AllSources());
6291 service_
->OnExternalExtensionFileFound(
6292 kGoodId
, &older_version
, kInvalidPathToCrx
,
6293 Manifest::INTERNAL
, kCreationFlags
, kDontMarkAcknowledged
));
6294 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6296 VerifyCrxInstall(kInvalidPathToCrx
, INSTALL_FAILED
);
6300 // Simulate an external source adding the extension as EXTERNAL_PREF.
6301 content::WindowedNotificationObserver
observer(
6302 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6303 content::NotificationService::AllSources());
6305 service_
->OnExternalExtensionFileFound(
6306 kGoodId
, &older_version
, kInvalidPathToCrx
,
6307 Manifest::EXTERNAL_PREF
, kCreationFlags
, kDontMarkAcknowledged
));
6308 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6310 VerifyCrxInstall(kInvalidPathToCrx
, INSTALL_FAILED
);
6313 // Simulate an external source adding as EXTERNAL_PREF again.
6314 // This is rejected because the version and the location are the same as
6315 // the previous installation, which is still pending.
6317 service_
->OnExternalExtensionFileFound(
6318 kGoodId
, &older_version
, kInvalidPathToCrx
,
6319 Manifest::EXTERNAL_PREF
, kCreationFlags
, kDontMarkAcknowledged
));
6320 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6322 // Try INTERNAL again. Should fail.
6324 service_
->OnExternalExtensionFileFound(
6325 kGoodId
, &older_version
, kInvalidPathToCrx
,
6326 Manifest::INTERNAL
, kCreationFlags
, kDontMarkAcknowledged
));
6327 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6330 // Now the registry adds the extension.
6331 content::WindowedNotificationObserver
observer(
6332 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6333 content::NotificationService::AllSources());
6335 service_
->OnExternalExtensionFileFound(kGoodId
,
6338 Manifest::EXTERNAL_REGISTRY
,
6340 kDontMarkAcknowledged
));
6341 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6343 VerifyCrxInstall(kInvalidPathToCrx
, INSTALL_FAILED
);
6346 // Registry outranks both external pref and internal, so both fail.
6348 service_
->OnExternalExtensionFileFound(
6349 kGoodId
, &older_version
, kInvalidPathToCrx
,
6350 Manifest::EXTERNAL_PREF
, kCreationFlags
, kDontMarkAcknowledged
));
6351 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6354 service_
->OnExternalExtensionFileFound(
6355 kGoodId
, &older_version
, kInvalidPathToCrx
,
6356 Manifest::INTERNAL
, kCreationFlags
, kDontMarkAcknowledged
));
6357 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6359 pending
->Remove(kGoodId
);
6361 // Install the extension.
6362 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
6363 const Extension
* ext
= InstallCRX(path
, INSTALL_NEW
);
6364 ValidatePrefKeyCount(1u);
6365 ValidateIntegerPref(good_crx
, "state", Extension::ENABLED
);
6366 ValidateIntegerPref(good_crx
, "location", Manifest::INTERNAL
);
6368 // Now test the logic of OnExternalExtensionFileFound() when the extension
6369 // being added is already installed.
6371 // Tests assume |older_version| is less than the installed version, and
6372 // |newer_version| is greater. Verify this:
6373 ASSERT_TRUE(older_version
.IsOlderThan(ext
->VersionString()));
6374 ASSERT_TRUE(ext
->version()->IsOlderThan(newer_version
.GetString()));
6376 // An external install for the same location should fail if the version is
6377 // older, or the same, and succeed if the version is newer.
6379 // Older than the installed version...
6381 service_
->OnExternalExtensionFileFound(
6382 kGoodId
, &older_version
, kInvalidPathToCrx
,
6383 Manifest::INTERNAL
, kCreationFlags
, kDontMarkAcknowledged
));
6384 EXPECT_FALSE(pending
->IsIdPending(kGoodId
));
6386 // Same version as the installed version...
6388 service_
->OnExternalExtensionFileFound(
6389 kGoodId
, ext
->version(), kInvalidPathToCrx
,
6390 Manifest::INTERNAL
, kCreationFlags
, kDontMarkAcknowledged
));
6391 EXPECT_FALSE(pending
->IsIdPending(kGoodId
));
6393 // Newer than the installed version...
6395 service_
->OnExternalExtensionFileFound(
6396 kGoodId
, &newer_version
, kInvalidPathToCrx
,
6397 Manifest::INTERNAL
, kCreationFlags
, kDontMarkAcknowledged
));
6398 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6400 // An external install for a higher priority install source should succeed
6401 // if the version is greater. |older_version| is not...
6403 service_
->OnExternalExtensionFileFound(
6404 kGoodId
, &older_version
, kInvalidPathToCrx
,
6405 Manifest::EXTERNAL_PREF
, kCreationFlags
, kDontMarkAcknowledged
));
6406 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6408 // |newer_version| is newer.
6410 service_
->OnExternalExtensionFileFound(
6411 kGoodId
, &newer_version
, kInvalidPathToCrx
,
6412 Manifest::EXTERNAL_PREF
, kCreationFlags
, kDontMarkAcknowledged
));
6413 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6415 // An external install for an even higher priority install source should
6416 // succeed if the version is greater.
6418 service_
->OnExternalExtensionFileFound(
6419 kGoodId
, &newer_version
, kInvalidPathToCrx
,
6420 Manifest::EXTERNAL_REGISTRY
, kCreationFlags
, kDontMarkAcknowledged
));
6421 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6423 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
6424 // adding from external pref will now fail.
6426 service_
->OnExternalExtensionFileFound(
6427 kGoodId
, &newer_version
, kInvalidPathToCrx
,
6428 Manifest::EXTERNAL_PREF
, kCreationFlags
, kDontMarkAcknowledged
));
6429 EXPECT_TRUE(pending
->IsIdPending(kGoodId
));
6432 TEST_F(ExtensionServiceTest
, ConcurrentExternalLocalFile
) {
6433 Version
kVersion123("1.2.3");
6434 Version
kVersion124("1.2.4");
6435 Version
kVersion125("1.2.5");
6436 const base::FilePath kInvalidPathToCrx
= base::FilePath();
6437 const int kCreationFlags
= 0;
6438 const bool kDontMarkAcknowledged
= false;
6440 InitializeEmptyExtensionService();
6442 extensions::PendingExtensionManager
* pending
=
6443 service_
->pending_extension_manager();
6444 EXPECT_FALSE(pending
->IsIdPending(kGoodId
));
6446 // An external provider starts installing from a local crx.
6448 service_
->OnExternalExtensionFileFound(
6449 kGoodId
, &kVersion123
, kInvalidPathToCrx
,
6450 Manifest::EXTERNAL_PREF
, kCreationFlags
, kDontMarkAcknowledged
));
6451 const extensions::PendingExtensionInfo
* info
;
6452 EXPECT_TRUE((info
= pending
->GetById(kGoodId
)));
6453 EXPECT_TRUE(info
->version().IsValid());
6454 EXPECT_TRUE(info
->version().Equals(kVersion123
));
6456 // Adding a newer version overrides the currently pending version.
6458 service_
->OnExternalExtensionFileFound(
6459 kGoodId
, &kVersion124
, kInvalidPathToCrx
,
6460 Manifest::EXTERNAL_PREF
, kCreationFlags
, kDontMarkAcknowledged
));
6461 EXPECT_TRUE((info
= pending
->GetById(kGoodId
)));
6462 EXPECT_TRUE(info
->version().IsValid());
6463 EXPECT_TRUE(info
->version().Equals(kVersion124
));
6465 // Adding an older version fails.
6467 service_
->OnExternalExtensionFileFound(
6468 kGoodId
, &kVersion123
, kInvalidPathToCrx
,
6469 Manifest::EXTERNAL_PREF
, kCreationFlags
, kDontMarkAcknowledged
));
6470 EXPECT_TRUE((info
= pending
->GetById(kGoodId
)));
6471 EXPECT_TRUE(info
->version().IsValid());
6472 EXPECT_TRUE(info
->version().Equals(kVersion124
));
6474 // Adding an older version fails even when coming from a higher-priority
6477 service_
->OnExternalExtensionFileFound(
6478 kGoodId
, &kVersion123
, kInvalidPathToCrx
,
6479 Manifest::EXTERNAL_REGISTRY
, kCreationFlags
, kDontMarkAcknowledged
));
6480 EXPECT_TRUE((info
= pending
->GetById(kGoodId
)));
6481 EXPECT_TRUE(info
->version().IsValid());
6482 EXPECT_TRUE(info
->version().Equals(kVersion124
));
6484 // Adding the latest version from the webstore overrides a specific version.
6485 GURL
kUpdateUrl("http://example.com/update");
6487 service_
->OnExternalExtensionUpdateUrlFound(
6488 kGoodId
, kUpdateUrl
, Manifest::EXTERNAL_POLICY_DOWNLOAD
,
6489 Extension::NO_FLAGS
, false));
6490 EXPECT_TRUE((info
= pending
->GetById(kGoodId
)));
6491 EXPECT_FALSE(info
->version().IsValid());
6494 // This makes sure we can package and install CRX files that use whitelisted
6496 TEST_F(ExtensionServiceTest
, InstallWhitelistedExtension
) {
6497 std::string test_id
= "hdkklepkcpckhnpgjnmbdfhehckloojk";
6498 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6499 switches::kWhitelistedExtensionID
, test_id
);
6501 InitializeEmptyExtensionService();
6502 base::FilePath path
= data_dir_
6503 .AppendASCII("permissions");
6504 base::FilePath pem_path
= path
6505 .AppendASCII("whitelist.pem");
6507 .AppendASCII("whitelist");
6509 const Extension
* extension
= PackAndInstallCRX(path
, pem_path
, INSTALL_NEW
);
6510 EXPECT_EQ(0u, GetErrors().size());
6511 ASSERT_EQ(1u, registry_
->enabled_extensions().size());
6512 EXPECT_EQ(test_id
, extension
->id());
6515 // Test that when multiple sources try to install an extension,
6516 // we consistently choose the right one. To make tests easy to read,
6517 // methods that fake requests to install crx files in several ways
6519 class ExtensionSourcePriorityTest
: public ExtensionServiceTest
{
6521 virtual void SetUp() {
6522 ExtensionServiceTest::SetUp();
6524 // All tests use a single extension. Put the id and path in member vars
6525 // that all methods can read.
6527 crx_path_
= data_dir_
.AppendASCII("good.crx");
6530 // Fake an external source adding a URL to fetch an extension from.
6531 bool AddPendingExternalPrefUrl() {
6532 return service_
->pending_extension_manager()->AddFromExternalUpdateUrl(
6533 crx_id_
, GURL(), Manifest::EXTERNAL_PREF_DOWNLOAD
,
6534 Extension::NO_FLAGS
, false);
6537 // Fake an external file from external_extensions.json.
6538 bool AddPendingExternalPrefFileInstall() {
6539 Version
version("1.0.0.0");
6541 return service_
->OnExternalExtensionFileFound(
6542 crx_id_
, &version
, crx_path_
, Manifest::EXTERNAL_PREF
,
6543 Extension::NO_FLAGS
, false);
6546 // Fake a request from sync to install an extension.
6547 bool AddPendingSyncInstall() {
6548 return service_
->pending_extension_manager()->AddFromSync(
6549 crx_id_
, GURL(kGoodUpdateURL
), &IsExtension
, kGoodInstallSilently
);
6552 // Fake a policy install.
6553 bool AddPendingPolicyInstall() {
6554 // Get path to the CRX with id |kGoodId|.
6555 return service_
->OnExternalExtensionUpdateUrlFound(
6556 crx_id_
, GURL(), Manifest::EXTERNAL_POLICY_DOWNLOAD
,
6557 Extension::NO_FLAGS
, false);
6560 // Get the install source of a pending extension.
6561 Manifest::Location
GetPendingLocation() {
6562 const extensions::PendingExtensionInfo
* info
;
6563 EXPECT_TRUE((info
= service_
->pending_extension_manager()->
6565 return info
->install_source();
6568 // Is an extension pending from a sync request?
6569 bool GetPendingIsFromSync() {
6570 const extensions::PendingExtensionInfo
* info
;
6571 EXPECT_TRUE((info
= service_
->pending_extension_manager()->
6573 return info
->is_from_sync();
6576 // Is the CRX id these tests use pending?
6577 bool IsCrxPending() {
6578 return service_
->pending_extension_manager()->IsIdPending(crx_id_
);
6581 // Is an extension installed?
6582 bool IsCrxInstalled() {
6583 return (service_
->GetExtensionById(crx_id_
, true) != NULL
);
6587 // All tests use a single extension. Making the id and path member
6588 // vars avoids pasing the same argument to every method.
6589 std::string crx_id_
;
6590 base::FilePath crx_path_
;
6593 // Test that a pending request for installation of an external CRX from
6594 // an update URL overrides a pending request to install the same extension
6596 TEST_F(ExtensionSourcePriorityTest
, PendingExternalFileOverSync
) {
6597 InitializeEmptyExtensionService();
6599 ASSERT_FALSE(IsCrxInstalled());
6601 // Install pending extension from sync.
6602 content::WindowedNotificationObserver
observer(
6603 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6604 content::NotificationService::AllSources());
6605 EXPECT_TRUE(AddPendingSyncInstall());
6606 ASSERT_EQ(Manifest::INTERNAL
, GetPendingLocation());
6607 EXPECT_TRUE(GetPendingIsFromSync());
6608 ASSERT_FALSE(IsCrxInstalled());
6610 // Install pending as external prefs json would.
6611 AddPendingExternalPrefFileInstall();
6612 ASSERT_EQ(Manifest::EXTERNAL_PREF
, GetPendingLocation());
6613 ASSERT_FALSE(IsCrxInstalled());
6615 // Another request from sync should be ignored.
6616 EXPECT_FALSE(AddPendingSyncInstall());
6617 ASSERT_EQ(Manifest::EXTERNAL_PREF
, GetPendingLocation());
6618 ASSERT_FALSE(IsCrxInstalled());
6621 VerifyCrxInstall(crx_path_
, INSTALL_NEW
);
6622 ASSERT_TRUE(IsCrxInstalled());
6625 // Test that an install of an external CRX from an update overrides
6626 // an install of the same extension from sync.
6627 TEST_F(ExtensionSourcePriorityTest
, PendingExternalUrlOverSync
) {
6628 InitializeEmptyExtensionService();
6629 ASSERT_FALSE(IsCrxInstalled());
6631 EXPECT_TRUE(AddPendingSyncInstall());
6632 ASSERT_EQ(Manifest::INTERNAL
, GetPendingLocation());
6633 EXPECT_TRUE(GetPendingIsFromSync());
6634 ASSERT_FALSE(IsCrxInstalled());
6636 ASSERT_TRUE(AddPendingExternalPrefUrl());
6637 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD
, GetPendingLocation());
6638 EXPECT_FALSE(GetPendingIsFromSync());
6639 ASSERT_FALSE(IsCrxInstalled());
6641 EXPECT_FALSE(AddPendingSyncInstall());
6642 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD
, GetPendingLocation());
6643 EXPECT_FALSE(GetPendingIsFromSync());
6644 ASSERT_FALSE(IsCrxInstalled());
6647 // Test that an external install request stops sync from installing
6648 // the same extension.
6649 TEST_F(ExtensionSourcePriorityTest
, InstallExternalBlocksSyncRequest
) {
6650 InitializeEmptyExtensionService();
6651 ASSERT_FALSE(IsCrxInstalled());
6653 // External prefs starts an install.
6654 AddPendingExternalPrefFileInstall();
6656 // Crx installer was made, but has not yet run.
6657 ASSERT_FALSE(IsCrxInstalled());
6659 // Before the CRX installer runs, Sync requests that the same extension
6660 // be installed. Should fail, because an external source is pending.
6661 content::WindowedNotificationObserver
observer(
6662 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6663 content::NotificationService::AllSources());
6664 ASSERT_FALSE(AddPendingSyncInstall());
6666 // Wait for the external source to install.
6668 VerifyCrxInstall(crx_path_
, INSTALL_NEW
);
6669 ASSERT_TRUE(IsCrxInstalled());
6671 // Now that the extension is installed, sync request should fail
6672 // because the extension is already installed.
6673 ASSERT_FALSE(AddPendingSyncInstall());
6676 // Test that installing an external extension displays a GlobalError.
6677 TEST_F(ExtensionServiceTest
, ExternalInstallGlobalError
) {
6678 FeatureSwitch::ScopedOverride
prompt(
6679 FeatureSwitch::prompt_for_external_extensions(), true);
6681 InitializeEmptyExtensionService();
6682 MockExtensionProvider
* provider
=
6683 new MockExtensionProvider(service_
, Manifest::EXTERNAL_PREF
);
6684 AddMockExternalProvider(provider
);
6686 service_
->UpdateExternalExtensionAlert();
6687 // Should return false, meaning there aren't any extensions that the user
6688 // needs to know about.
6689 EXPECT_FALSE(extensions::HasExternalInstallError(service_
));
6691 // This is a normal extension, installed normally.
6692 // This should NOT trigger an alert.
6693 set_extensions_enabled(true);
6694 base::FilePath path
= data_dir_
.AppendASCII("good.crx");
6695 InstallCRX(path
, INSTALL_NEW
);
6697 service_
->CheckForExternalUpdates();
6698 base::RunLoop().RunUntilIdle();
6699 EXPECT_FALSE(extensions::HasExternalInstallError(service_
));
6701 // A hosted app, installed externally.
6702 // This should NOT trigger an alert.
6703 provider
->UpdateOrAddExtension(hosted_app
, "1.0.0.0",
6704 data_dir_
.AppendASCII("hosted_app.crx"));
6706 content::WindowedNotificationObserver
observer(
6707 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6708 content::NotificationService::AllSources());
6709 service_
->CheckForExternalUpdates();
6711 EXPECT_FALSE(extensions::HasExternalInstallError(service_
));
6713 // Another normal extension, but installed externally.
6714 // This SHOULD trigger an alert.
6715 provider
->UpdateOrAddExtension(page_action
, "1.0.0.0",
6716 data_dir_
.AppendASCII("page_action.crx"));
6718 content::WindowedNotificationObserver
observer2(
6719 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6720 content::NotificationService::AllSources());
6721 service_
->CheckForExternalUpdates();
6723 EXPECT_TRUE(extensions::HasExternalInstallError(service_
));
6726 // Test that external extensions are initially disabled, and that enabling
6727 // them clears the prompt.
6728 TEST_F(ExtensionServiceTest
, ExternalInstallInitiallyDisabled
) {
6729 FeatureSwitch::ScopedOverride
prompt(
6730 FeatureSwitch::prompt_for_external_extensions(), true);
6732 InitializeEmptyExtensionService();
6733 MockExtensionProvider
* provider
=
6734 new MockExtensionProvider(service_
, Manifest::EXTERNAL_PREF
);
6735 AddMockExternalProvider(provider
);
6737 provider
->UpdateOrAddExtension(page_action
, "1.0.0.0",
6738 data_dir_
.AppendASCII("page_action.crx"));
6740 content::WindowedNotificationObserver
observer(
6741 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6742 content::NotificationService::AllSources());
6743 service_
->CheckForExternalUpdates();
6745 EXPECT_TRUE(extensions::HasExternalInstallError(service_
));
6746 EXPECT_FALSE(service_
->IsExtensionEnabled(page_action
));
6748 const Extension
* extension
=
6749 registry_
->disabled_extensions().GetByID(page_action
);
6750 EXPECT_TRUE(extension
);
6751 EXPECT_EQ(page_action
, extension
->id());
6753 service_
->EnableExtension(page_action
);
6754 EXPECT_FALSE(extensions::HasExternalInstallError(service_
));
6755 EXPECT_TRUE(service_
->IsExtensionEnabled(page_action
));
6758 // Test that installing multiple external extensions works.
6759 // Flaky on windows; http://crbug.com/295757 .
6761 #define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
6763 #define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
6765 TEST_F(ExtensionServiceTest
, MAYBE_ExternalInstallMultiple
) {
6766 FeatureSwitch::ScopedOverride
prompt(
6767 FeatureSwitch::prompt_for_external_extensions(), true);
6769 InitializeEmptyExtensionService();
6770 MockExtensionProvider
* provider
=
6771 new MockExtensionProvider(service_
, Manifest::EXTERNAL_PREF
);
6772 AddMockExternalProvider(provider
);
6774 provider
->UpdateOrAddExtension(page_action
, "1.0.0.0",
6775 data_dir_
.AppendASCII("page_action.crx"));
6776 provider
->UpdateOrAddExtension(good_crx
, "1.0.0.0",
6777 data_dir_
.AppendASCII("good.crx"));
6778 provider
->UpdateOrAddExtension(theme_crx
, "2.0",
6779 data_dir_
.AppendASCII("theme.crx"));
6782 content::WindowedNotificationObserver
observer(
6783 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6784 base::Bind(&WaitForCountNotificationsCallback
, &count
));
6785 service_
->CheckForExternalUpdates();
6787 EXPECT_TRUE(extensions::HasExternalInstallError(service_
));
6788 EXPECT_FALSE(service_
->IsExtensionEnabled(page_action
));
6789 EXPECT_FALSE(service_
->IsExtensionEnabled(good_crx
));
6790 EXPECT_FALSE(service_
->IsExtensionEnabled(theme_crx
));
6792 service_
->EnableExtension(page_action
);
6793 EXPECT_TRUE(extensions::HasExternalInstallError(service_
));
6794 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_
));
6795 service_
->EnableExtension(theme_crx
);
6796 EXPECT_TRUE(extensions::HasExternalInstallError(service_
));
6797 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_
));
6798 service_
->EnableExtension(good_crx
);
6799 EXPECT_FALSE(extensions::HasExternalInstallError(service_
));
6800 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_
));
6803 // Test that there is a bubble for external extensions that update
6804 // from the webstore if the profile is not new.
6805 TEST_F(ExtensionServiceTest
, ExternalInstallUpdatesFromWebstoreOldProfile
) {
6806 FeatureSwitch::ScopedOverride
prompt(
6807 FeatureSwitch::prompt_for_external_extensions(), true);
6809 // This sets up the ExtensionPrefs used by our ExtensionService to be
6811 ExtensionServiceInitParams params
= CreateDefaultInitParams();
6812 params
.is_first_run
= false;
6813 InitializeExtensionService(params
);
6815 base::FilePath crx_path
= temp_dir_
.path().AppendASCII("webstore.crx");
6816 PackCRX(data_dir_
.AppendASCII("update_from_webstore"),
6817 data_dir_
.AppendASCII("update_from_webstore.pem"),
6820 MockExtensionProvider
* provider
=
6821 new MockExtensionProvider(service_
, Manifest::EXTERNAL_PREF
);
6822 AddMockExternalProvider(provider
);
6823 provider
->UpdateOrAddExtension(updates_from_webstore
, "1", crx_path
);
6825 content::WindowedNotificationObserver
observer(
6826 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6827 content::NotificationService::AllSources());
6828 service_
->CheckForExternalUpdates();
6830 EXPECT_TRUE(extensions::HasExternalInstallError(service_
));
6831 EXPECT_TRUE(extensions::HasExternalInstallBubble(service_
));
6832 EXPECT_FALSE(service_
->IsExtensionEnabled(updates_from_webstore
));
6835 // Test that there is no bubble for external extensions if the profile is new.
6836 TEST_F(ExtensionServiceTest
, ExternalInstallUpdatesFromWebstoreNewProfile
) {
6837 FeatureSwitch::ScopedOverride
prompt(
6838 FeatureSwitch::prompt_for_external_extensions(), true);
6840 InitializeEmptyExtensionService();
6842 base::FilePath crx_path
= temp_dir_
.path().AppendASCII("webstore.crx");
6843 PackCRX(data_dir_
.AppendASCII("update_from_webstore"),
6844 data_dir_
.AppendASCII("update_from_webstore.pem"),
6847 MockExtensionProvider
* provider
=
6848 new MockExtensionProvider(service_
, Manifest::EXTERNAL_PREF
);
6849 AddMockExternalProvider(provider
);
6850 provider
->UpdateOrAddExtension(updates_from_webstore
, "1", crx_path
);
6852 content::WindowedNotificationObserver
observer(
6853 chrome::NOTIFICATION_CRX_INSTALLER_DONE
,
6854 content::NotificationService::AllSources());
6855 service_
->CheckForExternalUpdates();
6857 EXPECT_TRUE(extensions::HasExternalInstallError(service_
));
6858 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_
));
6859 EXPECT_FALSE(service_
->IsExtensionEnabled(updates_from_webstore
));
6862 TEST_F(ExtensionServiceTest
, InstallBlacklistedExtension
) {
6863 InitializeEmptyExtensionService();
6865 scoped_refptr
<Extension
> extension
= extensions::ExtensionBuilder()
6866 .SetManifest(extensions::DictionaryBuilder()
6867 .Set("name", "extension")
6868 .Set("version", "1.0")
6869 .Set("manifest_version", 2).Build())
6871 ASSERT_TRUE(extension
.get());
6872 const std::string
& id
= extension
->id();
6874 std::set
<std::string
> id_set
;
6876 extensions::ExtensionNotificationObserver
notifications(
6877 content::NotificationService::AllSources(), id_set
);
6879 // Installation should be allowed but the extension should never have been
6880 // loaded and it should be blacklisted in prefs.
6881 service_
->OnExtensionInstalled(
6883 syncer::StringOrdinal(),
6884 false /* has requirement errors */,
6885 extensions::BLACKLISTED_MALWARE
,
6886 false /* wait for idle */);
6887 base::RunLoop().RunUntilIdle();
6889 // Extension was installed but not loaded.
6890 EXPECT_TRUE(notifications
.CheckNotifications(
6891 chrome::NOTIFICATION_EXTENSION_INSTALLED
));
6892 EXPECT_TRUE(service_
->GetInstalledExtension(id
));
6894 EXPECT_FALSE(registry_
->enabled_extensions().Contains(id
));
6895 EXPECT_TRUE(registry_
->blacklisted_extensions().Contains(id
));
6897 EXPECT_TRUE(service_
->extension_prefs()->IsExtensionBlacklisted(id
));
6899 service_
->extension_prefs()->IsBlacklistedExtensionAcknowledged(id
));
6902 TEST_F(ExtensionServiceTest
, ReconcileKnownDisabledNoneDisabled
) {
6903 // A profile with 3 extensions installed: good0, good1, and good2.
6904 InitializeGoodInstalledExtensionService();
6906 // Initializing shouldn't disable any extensions if none are known to be
6910 extensions::ExtensionIdSet expected_extensions
;
6911 expected_extensions
.insert(good0
);
6912 expected_extensions
.insert(good1
);
6913 expected_extensions
.insert(good2
);
6915 extensions::ExtensionIdSet expected_disabled_extensions
;
6917 EXPECT_EQ(expected_extensions
, registry_
->enabled_extensions().GetIDs());
6918 EXPECT_EQ(expected_disabled_extensions
,
6919 registry_
->disabled_extensions().GetIDs());
6922 TEST_F(ExtensionServiceTest
, ReconcileKnownDisabledWithSideEnable
) {
6923 // A profile with 3 extensions installed: good0, good1, and good2.
6924 InitializeGoodInstalledExtensionService();
6926 ExtensionPrefs
* extension_prefs
= service_
->extension_prefs();
6929 extension_prefs
->SetExtensionState(good1
, Extension::DISABLED
);
6931 // Mark both good1 and good2 as "known_disabled" (effectively making good2
6932 // look as if it had been side-enabled).
6933 extensions::ExtensionIdSet known_disabled
;
6934 known_disabled
.insert(good1
);
6935 known_disabled
.insert(good2
);
6936 extension_prefs
->SetKnownDisabled(known_disabled
);
6938 // Initialize the service (which should disable good2 since it's known to be
6942 extensions::ExtensionIdSet expected_extensions
;
6943 expected_extensions
.insert(good0
);
6945 extensions::ExtensionIdSet expected_disabled_extensions
;
6946 expected_disabled_extensions
.insert(good1
);
6947 expected_disabled_extensions
.insert(good2
);
6949 EXPECT_EQ(expected_extensions
, registry_
->enabled_extensions().GetIDs());
6950 EXPECT_EQ(expected_disabled_extensions
,
6951 registry_
->disabled_extensions().GetIDs());
6953 // Make sure that re-enabling an extension sticks across calls to
6954 // ReconcileKnownDisabled().
6955 service_
->EnableExtension(good2
);
6956 service_
->ReconcileKnownDisabled();
6957 expected_extensions
.insert(good2
);
6958 expected_disabled_extensions
.erase(good2
);
6960 EXPECT_EQ(expected_extensions
, registry_
->enabled_extensions().GetIDs());
6961 EXPECT_EQ(expected_disabled_extensions
,
6962 registry_
->disabled_extensions().GetIDs());