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.
4
5 #include "chrome/browser/extensions/extension_service_unittest.h"
6
7 #include <algorithm>
8 #include <set>
9 #include <vector>
10
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_system.h"
48 #include "chrome/browser/extensions/extension_util.h"
49 #include "chrome/browser/extensions/external_install_ui.h"
50 #include "chrome/browser/extensions/external_policy_loader.h"
51 #include "chrome/browser/extensions/external_pref_loader.h"
52 #include "chrome/browser/extensions/external_provider_impl.h"
53 #include "chrome/browser/extensions/fake_safe_browsing_database_manager.h"
54 #include "chrome/browser/extensions/install_observer.h"
55 #include "chrome/browser/extensions/install_tracker.h"
56 #include "chrome/browser/extensions/install_tracker_factory.h"
57 #include "chrome/browser/extensions/installed_loader.h"
58 #include "chrome/browser/extensions/pack_extension_job.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/external_provider_interface.h"
91 #include "extensions/browser/management_policy.h"
92 #include "extensions/browser/pending_extension_info.h"
93 #include "extensions/browser/pending_extension_manager.h"
94 #include "extensions/browser/test_management_policy.h"
95 #include "extensions/common/constants.h"
96 #include "extensions/common/extension.h"
97 #include "extensions/common/extension_builder.h"
98 #include "extensions/common/extension_resource.h"
99 #include "extensions/common/manifest_constants.h"
100 #include "extensions/common/manifest_handlers/background_info.h"
101 #include "extensions/common/permissions/permission_set.h"
102 #include "extensions/common/url_pattern.h"
103 #include "extensions/common/value_builder.h"
104 #include "gpu/config/gpu_info.h"
105 #include "grit/browser_resources.h"
106 #include "net/cookies/canonical_cookie.h"
107 #include "net/cookies/cookie_monster.h"
108 #include "net/cookies/cookie_options.h"
109 #include "net/url_request/url_request_context.h"
110 #include "net/url_request/url_request_context_getter.h"
111 #include "sync/api/string_ordinal.h"
112 #include "sync/api/sync_data.h"
113 #include "sync/api/sync_error_factory.h"
114 #include "sync/api/sync_error_factory_mock.h"
115 #include "sync/api/syncable_service.h"
116 #include "sync/protocol/app_specifics.pb.h"
117 #include "sync/protocol/extension_specifics.pb.h"
118 #include "sync/protocol/sync.pb.h"
119 #include "testing/gtest/include/gtest/gtest.h"
120 #include "testing/platform_test.h"
121 #include "url/gurl.h"
122 #include "webkit/browser/database/database_tracker.h"
123 #include "webkit/browser/quota/quota_manager.h"
124 #include "webkit/common/database/database_identifier.h"
125
126 #if defined(OS_CHROMEOS)
127 #include "chrome/browser/chromeos/extensions/install_limiter.h"
128 #include "chrome/browser/chromeos/login/user_manager.h"
129 #include "chrome/browser/chromeos/settings/cros_settings.h"
130 #include "chrome/browser/chromeos/settings/device_settings_service.h"
131 #endif
132
133 // The blacklist tests rely on safe browsing.
134 #if defined(FULL_SAFE_BROWSING) || defined(MOBILE_SAFE_BROWSING)
135 #define ENABLE_BLACKLIST_TESTS
136 #endif
137
138 using base::DictionaryValue;
139 using base::ListValue;
140 using base::Value;
141 using content::BrowserContext;
142 using content::BrowserThread;
143 using content::DOMStorageContext;
144 using content::IndexedDBContext;
145 using content::PluginService;
146 using extensions::APIPermission;
147 using extensions::APIPermissionSet;
148 using extensions::AppSorting;
149 using extensions::Blacklist;
150 using extensions::CrxInstaller;
151 using extensions::Extension;
152 using extensions::ExtensionCreator;
153 using extensions::ExtensionPrefs;
154 using extensions::ExtensionResource;
155 using extensions::ExtensionSystem;
156 using extensions::FakeSafeBrowsingDatabaseManager;
157 using extensions::FeatureSwitch;
158 using extensions::Manifest;
159 using extensions::PermissionSet;
160 using extensions::TestExtensionSystem;
161 using extensions::URLPatternSet;
162
163 namespace keys = extensions::manifest_keys;
164
165 namespace {
166
167 // Extension ids used during testing.
168 const char good0[] = "behllobkkfkfnphdnhnkndlbkcpglgmj";
169 const char good1[] = "hpiknbiabeeppbpihjehijgoemciehgk";
170 const char good2[] = "bjafgdebaacbbbecmhlhpofkepfkgcpa";
171 const char all_zero[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
172 const char good2048[] = "nmgjhmhbleinmjpbdhgajfjkbijcmgbh";
173 const char good_crx[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
174 const char hosted_app[] = "kbmnembihfiondgfjekmnmcbddelicoi";
175 const char page_action[] = "obcimlgaoabeegjmmpldobjndiealpln";
176 const char theme_crx[] = "iamefpfkojoapidjnbafmgkgncegbkad";
177 const char theme2_crx[] = "pjpgmfcmabopnnfonnhmdjglfpjjfkbf";
178 const char permissions_crx[] = "eagpmdpfmaekmmcejjbmjoecnejeiiin";
179 const char unpacked[] = "cbcdidchbppangcjoddlpdjlenngjldk";
180 const char updates_from_webstore[] = "akjooamlhcgeopfifcmlggaebeocgokj";
181
182 struct ExtensionsOrder {
operator ()__anon72a5a2940111::ExtensionsOrder183 bool operator()(const scoped_refptr<const Extension>& a,
184 const scoped_refptr<const Extension>& b) {
185 return a->name() < b->name();
186 }
187 };
188
GetErrors()189 static std::vector<base::string16> GetErrors() {
190 const std::vector<base::string16>* errors =
191 ExtensionErrorReporter::GetInstance()->GetErrors();
192 std::vector<base::string16> ret_val;
193
194 for (std::vector<base::string16>::const_iterator iter = errors->begin();
195 iter != errors->end(); ++iter) {
196 std::string utf8_error = UTF16ToUTF8(*iter);
197 if (utf8_error.find(".svn") == std::string::npos) {
198 ret_val.push_back(*iter);
199 }
200 }
201
202 // The tests rely on the errors being in a certain order, which can vary
203 // depending on how filesystem iteration works.
204 std::stable_sort(ret_val.begin(), ret_val.end());
205
206 return ret_val;
207 }
208
AddPattern(URLPatternSet * extent,const std::string & pattern)209 static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
210 int schemes = URLPattern::SCHEME_ALL;
211 extent->AddPattern(URLPattern(schemes, pattern));
212 }
213
GetTemporaryFile()214 base::FilePath GetTemporaryFile() {
215 base::FilePath temp_file;
216 CHECK(base::CreateTemporaryFile(&temp_file));
217 return temp_file;
218 }
219
WaitForCountNotificationsCallback(int * count)220 bool WaitForCountNotificationsCallback(int *count) {
221 return --(*count) == 0;
222 }
223
224 } // namespace
225
226 class MockExtensionProvider : public extensions::ExternalProviderInterface {
227 public:
MockExtensionProvider(VisitorInterface * visitor,Manifest::Location location)228 MockExtensionProvider(
229 VisitorInterface* visitor,
230 Manifest::Location location)
231 : location_(location), visitor_(visitor), visit_count_(0) {
232 }
233
~MockExtensionProvider()234 virtual ~MockExtensionProvider() {}
235
UpdateOrAddExtension(const std::string & id,const std::string & version,const base::FilePath & path)236 void UpdateOrAddExtension(const std::string& id,
237 const std::string& version,
238 const base::FilePath& path) {
239 extension_map_[id] = std::make_pair(version, path);
240 }
241
RemoveExtension(const std::string & id)242 void RemoveExtension(const std::string& id) {
243 extension_map_.erase(id);
244 }
245
246 // ExternalProvider implementation:
VisitRegisteredExtension()247 virtual void VisitRegisteredExtension() OVERRIDE {
248 visit_count_++;
249 for (DataMap::const_iterator i = extension_map_.begin();
250 i != extension_map_.end(); ++i) {
251 Version version(i->second.first);
252
253 visitor_->OnExternalExtensionFileFound(
254 i->first, &version, i->second.second, location_,
255 Extension::NO_FLAGS, false);
256 }
257 visitor_->OnExternalProviderReady(this);
258 }
259
HasExtension(const std::string & id) const260 virtual bool HasExtension(const std::string& id) const OVERRIDE {
261 return extension_map_.find(id) != extension_map_.end();
262 }
263
GetExtensionDetails(const std::string & id,Manifest::Location * location,scoped_ptr<Version> * version) const264 virtual bool GetExtensionDetails(
265 const std::string& id,
266 Manifest::Location* location,
267 scoped_ptr<Version>* version) const OVERRIDE {
268 DataMap::const_iterator it = extension_map_.find(id);
269 if (it == extension_map_.end())
270 return false;
271
272 if (version)
273 version->reset(new Version(it->second.first));
274
275 if (location)
276 *location = location_;
277
278 return true;
279 }
280
IsReady() const281 virtual bool IsReady() const OVERRIDE {
282 return true;
283 }
284
ServiceShutdown()285 virtual void ServiceShutdown() OVERRIDE {
286 }
287
visit_count() const288 int visit_count() const { return visit_count_; }
set_visit_count(int visit_count)289 void set_visit_count(int visit_count) {
290 visit_count_ = visit_count;
291 }
292
293 private:
294 typedef std::map< std::string, std::pair<std::string, base::FilePath> >
295 DataMap;
296 DataMap extension_map_;
297 Manifest::Location location_;
298 VisitorInterface* visitor_;
299
300 // visit_count_ tracks the number of calls to VisitRegisteredExtension().
301 // Mutable because it must be incremented on each call to
302 // VisitRegisteredExtension(), which must be a const method to inherit
303 // from the class being mocked.
304 mutable int visit_count_;
305
306 DISALLOW_COPY_AND_ASSIGN(MockExtensionProvider);
307 };
308
309 class MockProviderVisitor
310 : public extensions::ExternalProviderInterface::VisitorInterface {
311 public:
312 // The provider will return |fake_base_path| from
313 // GetBaseCrxFilePath(). User can test the behavior with
314 // and without an empty path using this parameter.
MockProviderVisitor(base::FilePath fake_base_path)315 explicit MockProviderVisitor(base::FilePath fake_base_path)
316 : ids_found_(0),
317 fake_base_path_(fake_base_path),
318 expected_creation_flags_(Extension::NO_FLAGS) {
319 profile_.reset(new TestingProfile);
320 }
321
MockProviderVisitor(base::FilePath fake_base_path,int expected_creation_flags)322 MockProviderVisitor(base::FilePath fake_base_path,
323 int expected_creation_flags)
324 : ids_found_(0),
325 fake_base_path_(fake_base_path),
326 expected_creation_flags_(expected_creation_flags) {
327 }
328
Visit(const std::string & json_data)329 int Visit(const std::string& json_data) {
330 // Give the test json file to the provider for parsing.
331 provider_.reset(new extensions::ExternalProviderImpl(
332 this,
333 new extensions::ExternalTestingLoader(json_data, fake_base_path_),
334 profile_.get(),
335 Manifest::EXTERNAL_PREF,
336 Manifest::EXTERNAL_PREF_DOWNLOAD,
337 Extension::NO_FLAGS));
338
339 // We also parse the file into a dictionary to compare what we get back
340 // from the provider.
341 JSONStringValueSerializer serializer(json_data);
342 Value* json_value = serializer.Deserialize(NULL, NULL);
343
344 if (!json_value || !json_value->IsType(Value::TYPE_DICTIONARY)) {
345 NOTREACHED() << "Unable to deserialize json data";
346 return -1;
347 } else {
348 DictionaryValue* external_extensions =
349 static_cast<DictionaryValue*>(json_value);
350 prefs_.reset(external_extensions);
351 }
352
353 // Reset our counter.
354 ids_found_ = 0;
355 // Ask the provider to look up all extensions and return them.
356 provider_->VisitRegisteredExtension();
357
358 return ids_found_;
359 }
360
OnExternalExtensionFileFound(const std::string & id,const Version * version,const base::FilePath & path,Manifest::Location unused,int creation_flags,bool mark_acknowledged)361 virtual bool OnExternalExtensionFileFound(const std::string& id,
362 const Version* version,
363 const base::FilePath& path,
364 Manifest::Location unused,
365 int creation_flags,
366 bool mark_acknowledged) OVERRIDE {
367 EXPECT_EQ(expected_creation_flags_, creation_flags);
368
369 ++ids_found_;
370 DictionaryValue* pref;
371 // This tests is to make sure that the provider only notifies us of the
372 // values we gave it. So if the id we doesn't exist in our internal
373 // dictionary then something is wrong.
374 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
375 << "Got back ID (" << id.c_str() << ") we weren't expecting";
376
377 EXPECT_TRUE(path.IsAbsolute());
378 if (!fake_base_path_.empty())
379 EXPECT_TRUE(fake_base_path_.IsParent(path));
380
381 if (pref) {
382 EXPECT_TRUE(provider_->HasExtension(id));
383
384 // Ask provider if the extension we got back is registered.
385 Manifest::Location location = Manifest::INVALID_LOCATION;
386 scoped_ptr<Version> v1;
387 base::FilePath crx_path;
388
389 EXPECT_TRUE(provider_->GetExtensionDetails(id, NULL, &v1));
390 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
391
392 scoped_ptr<Version> v2;
393 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location, &v2));
394 EXPECT_STREQ(version->GetString().c_str(), v1->GetString().c_str());
395 EXPECT_STREQ(version->GetString().c_str(), v2->GetString().c_str());
396 EXPECT_EQ(Manifest::EXTERNAL_PREF, location);
397
398 // Remove it so we won't count it ever again.
399 prefs_->Remove(id, NULL);
400 }
401 return true;
402 }
403
OnExternalExtensionUpdateUrlFound(const std::string & id,const GURL & update_url,Manifest::Location location,int creation_flags,bool mark_acknowledged)404 virtual bool OnExternalExtensionUpdateUrlFound(
405 const std::string& id, const GURL& update_url,
406 Manifest::Location location,
407 int creation_flags,
408 bool mark_acknowledged) OVERRIDE {
409 ++ids_found_;
410 DictionaryValue* pref;
411 // This tests is to make sure that the provider only notifies us of the
412 // values we gave it. So if the id we doesn't exist in our internal
413 // dictionary then something is wrong.
414 EXPECT_TRUE(prefs_->GetDictionary(id, &pref))
415 << L"Got back ID (" << id.c_str() << ") we weren't expecting";
416 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location);
417
418 if (pref) {
419 EXPECT_TRUE(provider_->HasExtension(id));
420
421 // External extensions with update URLs do not have versions.
422 scoped_ptr<Version> v1;
423 Manifest::Location location1 = Manifest::INVALID_LOCATION;
424 EXPECT_TRUE(provider_->GetExtensionDetails(id, &location1, &v1));
425 EXPECT_FALSE(v1.get());
426 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, location1);
427
428 // Remove it so we won't count it again.
429 prefs_->Remove(id, NULL);
430 }
431 return true;
432 }
433
OnExternalProviderReady(const extensions::ExternalProviderInterface * provider)434 virtual void OnExternalProviderReady(
435 const extensions::ExternalProviderInterface* provider) OVERRIDE {
436 EXPECT_EQ(provider, provider_.get());
437 EXPECT_TRUE(provider->IsReady());
438 }
439
440 private:
441 int ids_found_;
442 base::FilePath fake_base_path_;
443 int expected_creation_flags_;
444 scoped_ptr<extensions::ExternalProviderImpl> provider_;
445 scoped_ptr<DictionaryValue> prefs_;
446 scoped_ptr<TestingProfile> profile_;
447
448 DISALLOW_COPY_AND_ASSIGN(MockProviderVisitor);
449 };
450
451 ExtensionServiceTestBase::ExtensionServiceInitParams::
ExtensionServiceInitParams()452 ExtensionServiceInitParams()
453 : autoupdate_enabled(false), is_first_run(true), profile_is_managed(false) {
454 }
455
456 // Our message loop may be used in tests which require it to be an IO loop.
ExtensionServiceTestBase()457 ExtensionServiceTestBase::ExtensionServiceTestBase()
458 : thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
459 service_(NULL),
460 management_policy_(NULL),
461 expected_extensions_count_(0) {
462 base::FilePath test_data_dir;
463 if (!PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir)) {
464 ADD_FAILURE();
465 return;
466 }
467 data_dir_ = test_data_dir.AppendASCII("extensions");
468 }
469
~ExtensionServiceTestBase()470 ExtensionServiceTestBase::~ExtensionServiceTestBase() {
471 service_ = NULL;
472 }
473
InitializeExtensionService(const ExtensionServiceTestBase::ExtensionServiceInitParams & params)474 void ExtensionServiceTestBase::InitializeExtensionService(
475 const ExtensionServiceTestBase::ExtensionServiceInitParams& params) {
476 profile_ = CreateTestingProfile(params);
477 service_ = InitializeExtensionServiceForProfile(params, profile_.get());
478 management_policy_ =
479 ExtensionSystem::Get(profile_.get())->management_policy();
480 extensions_install_dir_ = params.extensions_install_dir;
481 expected_extensions_count_ = 0;
482 }
483
484 // static
CreateTestingProfile(const ExtensionServiceInitParams & params)485 scoped_ptr<TestingProfile> ExtensionServiceTestBase::CreateTestingProfile(
486 const ExtensionServiceInitParams& params) {
487 TestingProfile::Builder profile_builder;
488 // Create a PrefService that only contains user defined preference values.
489 PrefServiceMockFactory factory;
490 // If pref_file is empty, TestingProfile automatically creates
491 // TestingPrefServiceSyncable instance.
492 if (!params.pref_file.empty()) {
493 factory.SetUserPrefsFile(params.pref_file,
494 base::MessageLoopProxy::current().get());
495 scoped_refptr<user_prefs::PrefRegistrySyncable> registry(
496 new user_prefs::PrefRegistrySyncable);
497 scoped_ptr<PrefServiceSyncable> prefs(
498 factory.CreateSyncable(registry.get()));
499 chrome::RegisterUserProfilePrefs(registry.get());
500 profile_builder.SetPrefService(prefs.Pass());
501 }
502
503 if (params.profile_is_managed)
504 profile_builder.SetManagedUserId("asdf");
505
506 profile_builder.SetPath(params.profile_path);
507 return profile_builder.Build();
508 }
509
510 // static
511 ExtensionService*
InitializeExtensionServiceForProfile(const ExtensionServiceInitParams & params,Profile * profile)512 ExtensionServiceTestBase::InitializeExtensionServiceForProfile(
513 const ExtensionServiceInitParams& params,
514 Profile* profile) {
515 TestExtensionSystem* system = static_cast<TestExtensionSystem*>(
516 ExtensionSystem::Get(profile));
517 if (!params.is_first_run) {
518 ExtensionPrefs* prefs = system->CreateExtensionPrefs(
519 CommandLine::ForCurrentProcess(),
520 params.extensions_install_dir);
521 prefs->SetAlertSystemFirstRun();
522 }
523
524 ExtensionService* service = system->CreateExtensionService(
525 CommandLine::ForCurrentProcess(),
526 params.extensions_install_dir,
527 params.autoupdate_enabled);
528
529 service->SetFileTaskRunnerForTesting(
530 base::MessageLoopProxy::current().get());
531 service->set_extensions_enabled(true);
532 service->set_show_extensions_prompts(false);
533 service->set_install_updates_when_idle_for_test(false);
534
535 // When we start up, we want to make sure there is no external provider,
536 // since the ExtensionService on Windows will use the Registry as a default
537 // provider and if there is something already registered there then it will
538 // interfere with the tests. Those tests that need an external provider
539 // will register one specifically.
540 service->ClearProvidersForTesting();
541
542 #if defined(OS_CHROMEOS)
543 extensions::InstallLimiter::Get(profile)->DisableForTest();
544 #endif
545 return service;
546 }
547
InitializeInstalledExtensionService(const base::FilePath & prefs_file,const base::FilePath & source_install_dir)548 void ExtensionServiceTestBase::InitializeInstalledExtensionService(
549 const base::FilePath& prefs_file,
550 const base::FilePath& source_install_dir) {
551 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
552 base::FilePath path = temp_dir_.path();
553 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
554 EXPECT_TRUE(base::DeleteFile(path, true));
555 base::PlatformFileError error = base::PLATFORM_FILE_OK;
556 EXPECT_TRUE(base::CreateDirectoryAndGetError(path, &error)) << error;
557 base::FilePath temp_prefs = path.Append(FILE_PATH_LITERAL("Preferences"));
558 EXPECT_TRUE(base::CopyFile(prefs_file, temp_prefs));
559
560 base::FilePath extensions_install_dir =
561 path.Append(FILE_PATH_LITERAL("Extensions"));
562 EXPECT_TRUE(base::DeleteFile(extensions_install_dir, true));
563 EXPECT_TRUE(
564 base::CopyDirectory(source_install_dir, extensions_install_dir, true));
565
566 ExtensionServiceInitParams params;
567 params.profile_path = path;
568 params.pref_file = temp_prefs;
569 params.extensions_install_dir = extensions_install_dir;
570 InitializeExtensionService(params);
571 }
572
InitializeGoodInstalledExtensionService()573 void ExtensionServiceTestBase::InitializeGoodInstalledExtensionService() {
574 base::FilePath source_install_dir = data_dir_
575 .AppendASCII("good")
576 .AppendASCII("Extensions");
577 base::FilePath pref_path = source_install_dir
578 .DirName()
579 .AppendASCII("Preferences");
580 InitializeInstalledExtensionService(pref_path, source_install_dir);
581 }
582
InitializeEmptyExtensionService()583 void ExtensionServiceTestBase::InitializeEmptyExtensionService() {
584 InitializeExtensionService(CreateDefaultInitParams());
585 }
586
InitializeProcessManager()587 void ExtensionServiceTestBase::InitializeProcessManager() {
588 static_cast<extensions::TestExtensionSystem*>(
589 ExtensionSystem::Get(profile_.get()))->
590 CreateProcessManager();
591 }
592
InitializeExtensionServiceWithUpdater()593 void ExtensionServiceTestBase::InitializeExtensionServiceWithUpdater() {
594 ExtensionServiceInitParams params = CreateDefaultInitParams();
595 params.autoupdate_enabled = true;
596 InitializeExtensionService(params);
597 service_->updater()->Start();
598 }
599
InitializeExtensionSyncService()600 void ExtensionServiceTestBase::InitializeExtensionSyncService() {
601 extension_sync_service_.reset(new ExtensionSyncService(
602 profile_.get(), service_->extension_prefs(), service_));
603 }
604
605 // static
SetUpTestCase()606 void ExtensionServiceTestBase::SetUpTestCase() {
607 ExtensionErrorReporter::Init(false); // no noisy errors
608 }
609
SetUp()610 void ExtensionServiceTestBase::SetUp() {
611 ExtensionErrorReporter::GetInstance()->ClearErrors();
612 content::RenderProcessHost::SetRunRendererInProcess(true);
613 }
614
TearDown()615 void ExtensionServiceTestBase::TearDown() {
616 content::RenderProcessHost::SetRunRendererInProcess(false);
617 }
618
619 ExtensionServiceTestBase::ExtensionServiceInitParams
CreateDefaultInitParams()620 ExtensionServiceTestBase::CreateDefaultInitParams() {
621 return CreateDefaultInitParamsInTempDir(&temp_dir_);
622 }
623
624 // static
625 ExtensionServiceTestBase::ExtensionServiceInitParams
CreateDefaultInitParamsInTempDir(base::ScopedTempDir * temp_dir)626 ExtensionServiceTestBase::CreateDefaultInitParamsInTempDir(
627 base::ScopedTempDir* temp_dir) {
628 ExtensionServiceInitParams params;
629 EXPECT_TRUE(temp_dir->CreateUniqueTempDir());
630 base::FilePath path = temp_dir->path();
631 path = path.Append(FILE_PATH_LITERAL("TestingExtensionsPath"));
632 EXPECT_TRUE(base::DeleteFile(path, true));
633 base::PlatformFileError error = base::PLATFORM_FILE_OK;
634 EXPECT_TRUE(base::CreateDirectoryAndGetError(path, &error)) << error;
635 base::FilePath prefs_filename =
636 path.Append(FILE_PATH_LITERAL("TestPreferences"));
637 base::FilePath extensions_install_dir =
638 path.Append(FILE_PATH_LITERAL("Extensions"));
639 EXPECT_TRUE(base::DeleteFile(extensions_install_dir, true));
640 EXPECT_TRUE(base::CreateDirectoryAndGetError(extensions_install_dir,
641 &error)) << error;
642
643 params.profile_path = path;
644 params.pref_file = prefs_filename;
645 params.extensions_install_dir = extensions_install_dir;
646 return params;
647 }
648
649 class ExtensionServiceTest
650 : public ExtensionServiceTestBase, public content::NotificationObserver {
651 public:
ExtensionServiceTest()652 ExtensionServiceTest()
653 : installed_(NULL),
654 was_update_(false),
655 override_external_install_prompt_(
656 FeatureSwitch::prompt_for_external_extensions(), false) {
657 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_LOADED,
658 content::NotificationService::AllSources());
659 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_UNLOADED,
660 content::NotificationService::AllSources());
661 registrar_.Add(this, chrome::NOTIFICATION_EXTENSION_INSTALLED,
662 content::NotificationService::AllSources());
663 }
664
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)665 virtual void Observe(int type,
666 const content::NotificationSource& source,
667 const content::NotificationDetails& details) OVERRIDE {
668 switch (type) {
669 case chrome::NOTIFICATION_EXTENSION_LOADED: {
670 const Extension* extension =
671 content::Details<const Extension>(details).ptr();
672 loaded_.push_back(make_scoped_refptr(extension));
673 // The tests rely on the errors being in a certain order, which can vary
674 // depending on how filesystem iteration works.
675 std::stable_sort(loaded_.begin(), loaded_.end(), ExtensionsOrder());
676 break;
677 }
678
679 case chrome::NOTIFICATION_EXTENSION_UNLOADED: {
680 const Extension* e =
681 content::Details<extensions::UnloadedExtensionInfo>(
682 details)->extension;
683 unloaded_id_ = e->id();
684 extensions::ExtensionList::iterator i =
685 std::find(loaded_.begin(), loaded_.end(), e);
686 // TODO(erikkay) fix so this can be an assert. Right now the tests
687 // are manually calling clear() on loaded_, so this isn't doable.
688 if (i == loaded_.end())
689 return;
690 loaded_.erase(i);
691 break;
692 }
693 case chrome::NOTIFICATION_EXTENSION_INSTALLED: {
694 const extensions::InstalledExtensionInfo* installed_info =
695 content::Details<const extensions::InstalledExtensionInfo>(details)
696 .ptr();
697 installed_ = installed_info->extension;
698 was_update_ = installed_info->is_update;
699 old_name_ = installed_info->old_name;
700 break;
701 }
702
703 default:
704 DCHECK(false);
705 }
706 }
707
AddMockExternalProvider(extensions::ExternalProviderInterface * provider)708 void AddMockExternalProvider(
709 extensions::ExternalProviderInterface* provider) {
710 service_->AddProviderForTesting(provider);
711 }
712
MockSyncStartFlare(bool * was_called,syncer::ModelType * model_type_passed_in,syncer::ModelType model_type)713 void MockSyncStartFlare(bool* was_called,
714 syncer::ModelType* model_type_passed_in,
715 syncer::ModelType model_type) {
716 *was_called = true;
717 *model_type_passed_in = model_type;
718 }
719
720 protected:
721 // Paths to some of the fake extensions.
good0_path()722 base::FilePath good0_path() {
723 return data_dir_.AppendASCII("good").AppendASCII("Extensions")
724 .AppendASCII(good0).AppendASCII("1.0.0.0");
725 }
726
good1_path()727 base::FilePath good1_path() {
728 return data_dir_.AppendASCII("good").AppendASCII("Extensions")
729 .AppendASCII(good1).AppendASCII("2");
730 }
731
good2_path()732 base::FilePath good2_path() {
733 return data_dir_.AppendASCII("good").AppendASCII("Extensions")
734 .AppendASCII(good2).AppendASCII("1.0");
735 }
736
737 void TestExternalProvider(MockExtensionProvider* provider,
738 Manifest::Location location);
739
PackCRX(const base::FilePath & dir_path,const base::FilePath & pem_path,const base::FilePath & crx_path)740 void PackCRX(const base::FilePath& dir_path,
741 const base::FilePath& pem_path,
742 const base::FilePath& crx_path) {
743 // Use the existing pem key, if provided.
744 base::FilePath pem_output_path;
745 if (pem_path.value().empty()) {
746 pem_output_path = crx_path.DirName().AppendASCII("temp.pem");
747 } else {
748 ASSERT_TRUE(base::PathExists(pem_path));
749 }
750
751 ASSERT_TRUE(base::DeleteFile(crx_path, false));
752
753 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
754 ASSERT_TRUE(creator->Run(dir_path,
755 crx_path,
756 pem_path,
757 pem_output_path,
758 ExtensionCreator::kOverwriteCRX));
759
760 ASSERT_TRUE(base::PathExists(crx_path));
761 }
762
763 enum InstallState {
764 INSTALL_FAILED,
765 INSTALL_UPDATED,
766 INSTALL_NEW,
767 INSTALL_WITHOUT_LOAD,
768 };
769
PackAndInstallCRX(const base::FilePath & dir_path,const base::FilePath & pem_path,InstallState install_state,int creation_flags)770 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
771 const base::FilePath& pem_path,
772 InstallState install_state,
773 int creation_flags) {
774 base::FilePath crx_path;
775 base::ScopedTempDir temp_dir;
776 EXPECT_TRUE(temp_dir.CreateUniqueTempDir());
777 crx_path = temp_dir.path().AppendASCII("temp.crx");
778
779 PackCRX(dir_path, pem_path, crx_path);
780 return InstallCRX(crx_path, install_state, creation_flags);
781 }
782
PackAndInstallCRX(const base::FilePath & dir_path,const base::FilePath & pem_path,InstallState install_state)783 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
784 const base::FilePath& pem_path,
785 InstallState install_state) {
786 return PackAndInstallCRX(dir_path, pem_path, install_state,
787 Extension::NO_FLAGS);
788 }
789
PackAndInstallCRX(const base::FilePath & dir_path,InstallState install_state)790 const Extension* PackAndInstallCRX(const base::FilePath& dir_path,
791 InstallState install_state) {
792 return PackAndInstallCRX(dir_path, base::FilePath(), install_state,
793 Extension::NO_FLAGS);
794 }
795
796 // Attempts to install an extension. Use INSTALL_FAILED if the installation
797 // is expected to fail.
798 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
799 // non-empty, expects that the existing extension's title was
800 // |expected_old_name|.
InstallCRX(const base::FilePath & path,InstallState install_state,int creation_flags,const std::string & expected_old_name)801 const Extension* InstallCRX(const base::FilePath& path,
802 InstallState install_state,
803 int creation_flags,
804 const std::string& expected_old_name) {
805 InstallCRXInternal(path, creation_flags);
806 return VerifyCrxInstall(path, install_state, expected_old_name);
807 }
808
809 // Attempts to install an extension. Use INSTALL_FAILED if the installation
810 // is expected to fail.
InstallCRX(const base::FilePath & path,InstallState install_state,int creation_flags)811 const Extension* InstallCRX(const base::FilePath& path,
812 InstallState install_state,
813 int creation_flags) {
814 return InstallCRX(path, install_state, creation_flags, std::string());
815 }
816
817 // Attempts to install an extension. Use INSTALL_FAILED if the installation
818 // is expected to fail.
InstallCRX(const base::FilePath & path,InstallState install_state)819 const Extension* InstallCRX(const base::FilePath& path,
820 InstallState install_state) {
821 return InstallCRX(path, install_state, Extension::NO_FLAGS);
822 }
823
InstallCRXFromWebStore(const base::FilePath & path,InstallState install_state)824 const Extension* InstallCRXFromWebStore(const base::FilePath& path,
825 InstallState install_state) {
826 InstallCRXInternal(path, Extension::FROM_WEBSTORE);
827 return VerifyCrxInstall(path, install_state);
828 }
829
InstallCRXWithLocation(const base::FilePath & crx_path,Manifest::Location install_location,InstallState install_state)830 const Extension* InstallCRXWithLocation(const base::FilePath& crx_path,
831 Manifest::Location install_location,
832 InstallState install_state) {
833 EXPECT_TRUE(base::PathExists(crx_path))
834 << "Path does not exist: "<< crx_path.value().c_str();
835 // no client (silent install)
836 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
837 installer->set_install_source(install_location);
838
839 content::WindowedNotificationObserver observer(
840 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
841 content::NotificationService::AllSources());
842 installer->InstallCrx(crx_path);
843 observer.Wait();
844
845 return VerifyCrxInstall(crx_path, install_state);
846 }
847
848 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
849 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
850 // Returns an Extension pointer if the install succeeded, NULL otherwise.
VerifyCrxInstall(const base::FilePath & path,InstallState install_state)851 const Extension* VerifyCrxInstall(const base::FilePath& path,
852 InstallState install_state) {
853 return VerifyCrxInstall(path, install_state, std::string());
854 }
855
856 // Verifies the result of a CRX installation. Used by InstallCRX. Set the
857 // |install_state| to INSTALL_FAILED if the installation is expected to fail.
858 // If |install_state| is INSTALL_UPDATED, and |expected_old_name| is
859 // non-empty, expects that the existing extension's title was
860 // |expected_old_name|.
861 // Returns an Extension pointer if the install succeeded, NULL otherwise.
VerifyCrxInstall(const base::FilePath & path,InstallState install_state,const std::string & expected_old_name)862 const Extension* VerifyCrxInstall(const base::FilePath& path,
863 InstallState install_state,
864 const std::string& expected_old_name) {
865 std::vector<base::string16> errors = GetErrors();
866 const Extension* extension = NULL;
867 if (install_state != INSTALL_FAILED) {
868 if (install_state == INSTALL_NEW)
869 ++expected_extensions_count_;
870
871 EXPECT_TRUE(installed_) << path.value();
872 // If and only if INSTALL_UPDATED, it should have the is_update flag.
873 EXPECT_EQ(install_state == INSTALL_UPDATED, was_update_)
874 << path.value();
875 // If INSTALL_UPDATED, old_name_ should match the given string.
876 if (install_state == INSTALL_UPDATED && !expected_old_name.empty())
877 EXPECT_EQ(expected_old_name, old_name_);
878 EXPECT_EQ(0u, errors.size()) << path.value();
879
880 if (install_state == INSTALL_WITHOUT_LOAD) {
881 EXPECT_EQ(0u, loaded_.size()) << path.value();
882 } else {
883 EXPECT_EQ(1u, loaded_.size()) << path.value();
884 size_t actual_extension_count = service_->extensions()->size() +
885 service_->disabled_extensions()->size();
886 EXPECT_EQ(expected_extensions_count_, actual_extension_count) <<
887 path.value();
888 extension = loaded_[0].get();
889 EXPECT_TRUE(service_->GetExtensionById(extension->id(), false))
890 << path.value();
891 }
892
893 for (std::vector<base::string16>::iterator err = errors.begin();
894 err != errors.end(); ++err) {
895 LOG(ERROR) << *err;
896 }
897 } else {
898 EXPECT_FALSE(installed_) << path.value();
899 EXPECT_EQ(0u, loaded_.size()) << path.value();
900 EXPECT_EQ(1u, errors.size()) << path.value();
901 }
902
903 installed_ = NULL;
904 was_update_ = false;
905 old_name_ = "";
906 loaded_.clear();
907 ExtensionErrorReporter::GetInstance()->ClearErrors();
908 return extension;
909 }
910
911 enum UpdateState {
912 FAILED_SILENTLY,
913 FAILED,
914 UPDATED,
915 INSTALLED,
916 ENABLED
917 };
918
BlackListWebGL()919 void BlackListWebGL() {
920 static const std::string json_blacklist =
921 "{\n"
922 " \"name\": \"gpu blacklist\",\n"
923 " \"version\": \"1.0\",\n"
924 " \"entries\": [\n"
925 " {\n"
926 " \"id\": 1,\n"
927 " \"features\": [\"webgl\"]\n"
928 " }\n"
929 " ]\n"
930 "}";
931 gpu::GPUInfo gpu_info;
932 content::GpuDataManager::GetInstance()->InitializeForTesting(
933 json_blacklist, gpu_info);
934 }
935
936 // Helper method to set up a WindowedNotificationObserver to wait for a
937 // specific CrxInstaller to finish if we don't know the value of the
938 // |installer| yet.
IsCrxInstallerDone(extensions::CrxInstaller ** installer,const content::NotificationSource & source,const content::NotificationDetails & details)939 static bool IsCrxInstallerDone(extensions::CrxInstaller** installer,
940 const content::NotificationSource& source,
941 const content::NotificationDetails& details) {
942 return content::Source<extensions::CrxInstaller>(source).ptr() ==
943 *installer;
944 }
945
UpdateExtension(const std::string & id,const base::FilePath & in_path,UpdateState expected_state)946 void UpdateExtension(const std::string& id,
947 const base::FilePath& in_path,
948 UpdateState expected_state) {
949 ASSERT_TRUE(base::PathExists(in_path));
950
951 // We need to copy this to a temporary location because Update() will delete
952 // it.
953 base::FilePath path = temp_dir_.path();
954 path = path.Append(in_path.BaseName());
955 ASSERT_TRUE(base::CopyFile(in_path, path));
956
957 int previous_enabled_extension_count =
958 service_->extensions()->size();
959 int previous_installed_extension_count =
960 previous_enabled_extension_count +
961 service_->disabled_extensions()->size();
962
963 extensions::CrxInstaller* installer = NULL;
964 content::WindowedNotificationObserver observer(
965 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
966 base::Bind(&IsCrxInstallerDone, &installer));
967 service_->UpdateExtension(id, path, GURL(), &installer);
968
969 if (installer)
970 observer.Wait();
971 else
972 base::RunLoop().RunUntilIdle();
973
974 std::vector<base::string16> errors = GetErrors();
975 int error_count = errors.size();
976 int enabled_extension_count =
977 service_->extensions()->size();
978 int installed_extension_count =
979 enabled_extension_count + service_->disabled_extensions()->size();
980
981 int expected_error_count = (expected_state == FAILED) ? 1 : 0;
982 EXPECT_EQ(expected_error_count, error_count) << path.value();
983
984 if (expected_state <= FAILED) {
985 EXPECT_EQ(previous_enabled_extension_count,
986 enabled_extension_count);
987 EXPECT_EQ(previous_installed_extension_count,
988 installed_extension_count);
989 } else {
990 int expected_installed_extension_count =
991 (expected_state >= INSTALLED) ? 1 : 0;
992 int expected_enabled_extension_count =
993 (expected_state >= ENABLED) ? 1 : 0;
994 EXPECT_EQ(expected_installed_extension_count,
995 installed_extension_count);
996 EXPECT_EQ(expected_enabled_extension_count,
997 enabled_extension_count);
998 }
999
1000 // Update() should the temporary input file.
1001 EXPECT_FALSE(base::PathExists(path));
1002 }
1003
TerminateExtension(const std::string & id)1004 void TerminateExtension(const std::string& id) {
1005 const Extension* extension = service_->GetInstalledExtension(id);
1006 if (!extension) {
1007 ADD_FAILURE();
1008 return;
1009 }
1010 service_->TrackTerminatedExtensionForTest(extension);
1011 }
1012
GetPrefKeyCount()1013 size_t GetPrefKeyCount() {
1014 const DictionaryValue* dict =
1015 profile_->GetPrefs()->GetDictionary("extensions.settings");
1016 if (!dict) {
1017 ADD_FAILURE();
1018 return 0;
1019 }
1020 return dict->size();
1021 }
1022
UninstallExtension(const std::string & id,bool use_helper)1023 void UninstallExtension(const std::string& id, bool use_helper) {
1024 // Verify that the extension is installed.
1025 base::FilePath extension_path = extensions_install_dir_.AppendASCII(id);
1026 EXPECT_TRUE(base::PathExists(extension_path));
1027 size_t pref_key_count = GetPrefKeyCount();
1028 EXPECT_GT(pref_key_count, 0u);
1029 ValidateIntegerPref(id, "state", Extension::ENABLED);
1030
1031 // Uninstall it.
1032 if (use_helper) {
1033 EXPECT_TRUE(ExtensionService::UninstallExtensionHelper(service_, id));
1034 } else {
1035 EXPECT_TRUE(service_->UninstallExtension(id, false, NULL));
1036 }
1037 --expected_extensions_count_;
1038
1039 // We should get an unload notification.
1040 EXPECT_FALSE(unloaded_id_.empty());
1041 EXPECT_EQ(id, unloaded_id_);
1042
1043 // Verify uninstalled state.
1044 size_t new_pref_key_count = GetPrefKeyCount();
1045 if (new_pref_key_count == pref_key_count) {
1046 ValidateIntegerPref(id, "location",
1047 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1048 } else {
1049 EXPECT_EQ(new_pref_key_count, pref_key_count - 1);
1050 }
1051
1052 // The extension should not be in the service anymore.
1053 EXPECT_FALSE(service_->GetInstalledExtension(id));
1054 base::RunLoop().RunUntilIdle();
1055
1056 // The directory should be gone.
1057 EXPECT_FALSE(base::PathExists(extension_path));
1058 }
1059
ValidatePrefKeyCount(size_t count)1060 void ValidatePrefKeyCount(size_t count) {
1061 EXPECT_EQ(count, GetPrefKeyCount());
1062 }
1063
ValidateBooleanPref(const std::string & extension_id,const std::string & pref_path,bool expected_val)1064 testing::AssertionResult ValidateBooleanPref(
1065 const std::string& extension_id,
1066 const std::string& pref_path,
1067 bool expected_val) {
1068 std::string msg = "while checking: ";
1069 msg += extension_id;
1070 msg += " ";
1071 msg += pref_path;
1072 msg += " == ";
1073 msg += expected_val ? "true" : "false";
1074
1075 PrefService* prefs = profile_->GetPrefs();
1076 const DictionaryValue* dict =
1077 prefs->GetDictionary("extensions.settings");
1078 if (!dict) {
1079 return testing::AssertionFailure()
1080 << "extension.settings does not exist " << msg;
1081 }
1082
1083 const DictionaryValue* pref = NULL;
1084 if (!dict->GetDictionary(extension_id, &pref)) {
1085 return testing::AssertionFailure()
1086 << "extension pref does not exist " << msg;
1087 }
1088
1089 bool val;
1090 if (!pref->GetBoolean(pref_path, &val)) {
1091 return testing::AssertionFailure()
1092 << pref_path << " pref not found " << msg;
1093 }
1094
1095 return expected_val == val
1096 ? testing::AssertionSuccess()
1097 : testing::AssertionFailure() << "Value is incorrect " << msg;
1098 }
1099
IsPrefExist(const std::string & extension_id,const std::string & pref_path)1100 bool IsPrefExist(const std::string& extension_id,
1101 const std::string& pref_path) {
1102 const DictionaryValue* dict =
1103 profile_->GetPrefs()->GetDictionary("extensions.settings");
1104 if (dict == NULL) return false;
1105 const DictionaryValue* pref = NULL;
1106 if (!dict->GetDictionary(extension_id, &pref)) {
1107 return false;
1108 }
1109 if (pref == NULL) {
1110 return false;
1111 }
1112 bool val;
1113 if (!pref->GetBoolean(pref_path, &val)) {
1114 return false;
1115 }
1116 return true;
1117 }
1118
ValidateIntegerPref(const std::string & extension_id,const std::string & pref_path,int expected_val)1119 void ValidateIntegerPref(const std::string& extension_id,
1120 const std::string& pref_path,
1121 int expected_val) {
1122 std::string msg = " while checking: ";
1123 msg += extension_id;
1124 msg += " ";
1125 msg += pref_path;
1126 msg += " == ";
1127 msg += base::IntToString(expected_val);
1128
1129 PrefService* prefs = profile_->GetPrefs();
1130 const DictionaryValue* dict =
1131 prefs->GetDictionary("extensions.settings");
1132 ASSERT_TRUE(dict != NULL) << msg;
1133 const DictionaryValue* pref = NULL;
1134 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1135 EXPECT_TRUE(pref != NULL) << msg;
1136 int val;
1137 ASSERT_TRUE(pref->GetInteger(pref_path, &val)) << msg;
1138 EXPECT_EQ(expected_val, val) << msg;
1139 }
1140
ValidateStringPref(const std::string & extension_id,const std::string & pref_path,const std::string & expected_val)1141 void ValidateStringPref(const std::string& extension_id,
1142 const std::string& pref_path,
1143 const std::string& expected_val) {
1144 std::string msg = " while checking: ";
1145 msg += extension_id;
1146 msg += ".manifest.";
1147 msg += pref_path;
1148 msg += " == ";
1149 msg += expected_val;
1150
1151 const DictionaryValue* dict =
1152 profile_->GetPrefs()->GetDictionary("extensions.settings");
1153 ASSERT_TRUE(dict != NULL) << msg;
1154 const DictionaryValue* pref = NULL;
1155 std::string manifest_path = extension_id + ".manifest";
1156 ASSERT_TRUE(dict->GetDictionary(manifest_path, &pref)) << msg;
1157 EXPECT_TRUE(pref != NULL) << msg;
1158 std::string val;
1159 ASSERT_TRUE(pref->GetString(pref_path, &val)) << msg;
1160 EXPECT_EQ(expected_val, val) << msg;
1161 }
1162
SetPref(const std::string & extension_id,const std::string & pref_path,Value * value,const std::string & msg)1163 void SetPref(const std::string& extension_id,
1164 const std::string& pref_path,
1165 Value* value,
1166 const std::string& msg) {
1167 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1168 DictionaryValue* dict = update.Get();
1169 ASSERT_TRUE(dict != NULL) << msg;
1170 DictionaryValue* pref = NULL;
1171 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1172 EXPECT_TRUE(pref != NULL) << msg;
1173 pref->Set(pref_path, value);
1174 }
1175
SetPrefInteg(const std::string & extension_id,const std::string & pref_path,int value)1176 void SetPrefInteg(const std::string& extension_id,
1177 const std::string& pref_path,
1178 int value) {
1179 std::string msg = " while setting: ";
1180 msg += extension_id;
1181 msg += " ";
1182 msg += pref_path;
1183 msg += " = ";
1184 msg += base::IntToString(value);
1185
1186 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1187 }
1188
SetPrefBool(const std::string & extension_id,const std::string & pref_path,bool value)1189 void SetPrefBool(const std::string& extension_id,
1190 const std::string& pref_path,
1191 bool value) {
1192 std::string msg = " while setting: ";
1193 msg += extension_id + " " + pref_path;
1194 msg += " = ";
1195 msg += (value ? "true" : "false");
1196
1197 SetPref(extension_id, pref_path, new base::FundamentalValue(value), msg);
1198 }
1199
ClearPref(const std::string & extension_id,const std::string & pref_path)1200 void ClearPref(const std::string& extension_id,
1201 const std::string& pref_path) {
1202 std::string msg = " while clearing: ";
1203 msg += extension_id + " " + pref_path;
1204
1205 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1206 DictionaryValue* dict = update.Get();
1207 ASSERT_TRUE(dict != NULL) << msg;
1208 DictionaryValue* pref = NULL;
1209 ASSERT_TRUE(dict->GetDictionary(extension_id, &pref)) << msg;
1210 EXPECT_TRUE(pref != NULL) << msg;
1211 pref->Remove(pref_path, NULL);
1212 }
1213
SetPrefStringSet(const std::string & extension_id,const std::string & pref_path,const std::set<std::string> & value)1214 void SetPrefStringSet(const std::string& extension_id,
1215 const std::string& pref_path,
1216 const std::set<std::string>& value) {
1217 std::string msg = " while setting: ";
1218 msg += extension_id + " " + pref_path;
1219
1220 ListValue* list_value = new ListValue();
1221 for (std::set<std::string>::const_iterator iter = value.begin();
1222 iter != value.end(); ++iter)
1223 list_value->Append(new base::StringValue(*iter));
1224
1225 SetPref(extension_id, pref_path, list_value, msg);
1226 }
1227
InitPluginService()1228 void InitPluginService() {
1229 #if defined(ENABLE_PLUGINS)
1230 PluginService::GetInstance()->Init();
1231 #endif
1232 }
1233
1234 protected:
1235 extensions::ExtensionList loaded_;
1236 std::string unloaded_id_;
1237 const Extension* installed_;
1238 bool was_update_;
1239 std::string old_name_;
1240 FeatureSwitch::ScopedOverride override_external_install_prompt_;
1241
1242 private:
1243 // Create a CrxInstaller and install the CRX file.
1244 // Instead of calling this method yourself, use InstallCRX(), which does extra
1245 // error checking.
InstallCRXInternal(const base::FilePath & crx_path)1246 void InstallCRXInternal(const base::FilePath& crx_path) {
1247 InstallCRXInternal(crx_path, Extension::NO_FLAGS);
1248 }
1249
InstallCRXInternal(const base::FilePath & crx_path,int creation_flags)1250 void InstallCRXInternal(const base::FilePath& crx_path, int creation_flags) {
1251 ASSERT_TRUE(base::PathExists(crx_path))
1252 << "Path does not exist: "<< crx_path.value().c_str();
1253 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
1254 installer->set_creation_flags(creation_flags);
1255 if (!(creation_flags & Extension::WAS_INSTALLED_BY_DEFAULT))
1256 installer->set_allow_silent_install(true);
1257
1258 content::WindowedNotificationObserver observer(
1259 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1260 content::Source<extensions::CrxInstaller>(installer));
1261
1262 installer->InstallCrx(crx_path);
1263
1264 observer.Wait();
1265 }
1266
1267 content::NotificationRegistrar registrar_;
1268 };
1269
1270 // Receives notifications from a PackExtensionJob, indicating either that
1271 // packing succeeded or that there was some error.
1272 class PackExtensionTestClient : public extensions::PackExtensionJob::Client {
1273 public:
1274 PackExtensionTestClient(const base::FilePath& expected_crx_path,
1275 const base::FilePath& expected_private_key_path);
1276 virtual void OnPackSuccess(const base::FilePath& crx_path,
1277 const base::FilePath& private_key_path) OVERRIDE;
1278 virtual void OnPackFailure(const std::string& error_message,
1279 ExtensionCreator::ErrorType type) OVERRIDE;
1280
1281 private:
1282 const base::FilePath expected_crx_path_;
1283 const base::FilePath expected_private_key_path_;
1284 DISALLOW_COPY_AND_ASSIGN(PackExtensionTestClient);
1285 };
1286
PackExtensionTestClient(const base::FilePath & expected_crx_path,const base::FilePath & expected_private_key_path)1287 PackExtensionTestClient::PackExtensionTestClient(
1288 const base::FilePath& expected_crx_path,
1289 const base::FilePath& expected_private_key_path)
1290 : expected_crx_path_(expected_crx_path),
1291 expected_private_key_path_(expected_private_key_path) {}
1292
1293 // If packing succeeded, we make sure that the package names match our
1294 // expectations.
OnPackSuccess(const base::FilePath & crx_path,const base::FilePath & private_key_path)1295 void PackExtensionTestClient::OnPackSuccess(
1296 const base::FilePath& crx_path,
1297 const base::FilePath& private_key_path) {
1298 // We got the notification and processed it; we don't expect any further tasks
1299 // to be posted to the current thread, so we should stop blocking and continue
1300 // on with the rest of the test.
1301 // This call to |Quit()| matches the call to |Run()| in the
1302 // |PackPunctuatedExtension| test.
1303 base::MessageLoop::current()->Quit();
1304 EXPECT_EQ(expected_crx_path_.value(), crx_path.value());
1305 EXPECT_EQ(expected_private_key_path_.value(), private_key_path.value());
1306 ASSERT_TRUE(base::PathExists(private_key_path));
1307 }
1308
1309 // The tests are designed so that we never expect to see a packing error.
OnPackFailure(const std::string & error_message,ExtensionCreator::ErrorType type)1310 void PackExtensionTestClient::OnPackFailure(const std::string& error_message,
1311 ExtensionCreator::ErrorType type) {
1312 if (type == ExtensionCreator::kCRXExists)
1313 FAIL() << "Packing should not fail.";
1314 else
1315 FAIL() << "Existing CRX should have been overwritten.";
1316 }
1317
1318 // Test loading good extensions from the profile directory.
TEST_F(ExtensionServiceTest,LoadAllExtensionsFromDirectorySuccess)1319 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectorySuccess) {
1320 InitPluginService();
1321 InitializeGoodInstalledExtensionService();
1322 service_->Init();
1323
1324 uint32 expected_num_extensions = 3u;
1325 ASSERT_EQ(expected_num_extensions, loaded_.size());
1326
1327 EXPECT_EQ(std::string(good0), loaded_[0]->id());
1328 EXPECT_EQ(std::string("My extension 1"),
1329 loaded_[0]->name());
1330 EXPECT_EQ(std::string("The first extension that I made."),
1331 loaded_[0]->description());
1332 EXPECT_EQ(Manifest::INTERNAL, loaded_[0]->location());
1333 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false));
1334 EXPECT_EQ(expected_num_extensions, service_->extensions()->size());
1335
1336 ValidatePrefKeyCount(3);
1337 ValidateIntegerPref(good0, "state", Extension::ENABLED);
1338 ValidateIntegerPref(good0, "location", Manifest::INTERNAL);
1339 ValidateIntegerPref(good1, "state", Extension::ENABLED);
1340 ValidateIntegerPref(good1, "location", Manifest::INTERNAL);
1341 ValidateIntegerPref(good2, "state", Extension::ENABLED);
1342 ValidateIntegerPref(good2, "location", Manifest::INTERNAL);
1343
1344 URLPatternSet expected_patterns;
1345 AddPattern(&expected_patterns, "file:///*");
1346 AddPattern(&expected_patterns, "http://*.google.com/*");
1347 AddPattern(&expected_patterns, "https://*.google.com/*");
1348 const Extension* extension = loaded_[0].get();
1349 const extensions::UserScriptList& scripts =
1350 extensions::ContentScriptsInfo::GetContentScripts(extension);
1351 ASSERT_EQ(2u, scripts.size());
1352 EXPECT_EQ(expected_patterns, scripts[0].url_patterns());
1353 EXPECT_EQ(2u, scripts[0].js_scripts().size());
1354 ExtensionResource resource00(extension->id(),
1355 scripts[0].js_scripts()[0].extension_root(),
1356 scripts[0].js_scripts()[0].relative_path());
1357 base::FilePath expected_path =
1358 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script1.js"));
1359 EXPECT_TRUE(resource00.ComparePathWithDefault(expected_path));
1360 ExtensionResource resource01(extension->id(),
1361 scripts[0].js_scripts()[1].extension_root(),
1362 scripts[0].js_scripts()[1].relative_path());
1363 expected_path =
1364 base::MakeAbsoluteFilePath(extension->path().AppendASCII("script2.js"));
1365 EXPECT_TRUE(resource01.ComparePathWithDefault(expected_path));
1366 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(extension));
1367 EXPECT_EQ(1u, scripts[1].url_patterns().patterns().size());
1368 EXPECT_EQ("http://*.news.com/*",
1369 scripts[1].url_patterns().begin()->GetAsString());
1370 ExtensionResource resource10(extension->id(),
1371 scripts[1].js_scripts()[0].extension_root(),
1372 scripts[1].js_scripts()[0].relative_path());
1373 expected_path =
1374 extension->path().AppendASCII("js_files").AppendASCII("script3.js");
1375 expected_path = base::MakeAbsoluteFilePath(expected_path);
1376 EXPECT_TRUE(resource10.ComparePathWithDefault(expected_path));
1377
1378 expected_patterns.ClearPatterns();
1379 AddPattern(&expected_patterns, "http://*.google.com/*");
1380 AddPattern(&expected_patterns, "https://*.google.com/*");
1381 EXPECT_EQ(expected_patterns,
1382 extension->GetActivePermissions()->explicit_hosts());
1383
1384 EXPECT_EQ(std::string(good1), loaded_[1]->id());
1385 EXPECT_EQ(std::string("My extension 2"), loaded_[1]->name());
1386 EXPECT_EQ(std::string(), loaded_[1]->description());
1387 EXPECT_EQ(loaded_[1]->GetResourceURL("background.html"),
1388 extensions::BackgroundInfo::GetBackgroundURL(loaded_[1].get()));
1389 EXPECT_EQ(0u,
1390 extensions::ContentScriptsInfo::GetContentScripts(loaded_[1].get())
1391 .size());
1392
1393 // We don't parse the plugins section on Chrome OS.
1394 #if defined(OS_CHROMEOS)
1395 EXPECT_TRUE(!extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1396 #else
1397 ASSERT_TRUE(extensions::PluginInfo::HasPlugins(loaded_[1].get()));
1398 const std::vector<extensions::PluginInfo>* plugins =
1399 extensions::PluginInfo::GetPlugins(loaded_[1].get());
1400 ASSERT_TRUE(plugins);
1401 ASSERT_EQ(2u, plugins->size());
1402 EXPECT_EQ(loaded_[1]->path().AppendASCII("content_plugin.dll").value(),
1403 plugins->at(0).path.value());
1404 EXPECT_TRUE(plugins->at(0).is_public);
1405 EXPECT_EQ(loaded_[1]->path().AppendASCII("extension_plugin.dll").value(),
1406 plugins->at(1).path.value());
1407 EXPECT_FALSE(plugins->at(1).is_public);
1408 #endif
1409
1410 EXPECT_EQ(Manifest::INTERNAL, loaded_[1]->location());
1411
1412 int index = expected_num_extensions - 1;
1413 EXPECT_EQ(std::string(good2), loaded_[index]->id());
1414 EXPECT_EQ(std::string("My extension 3"), loaded_[index]->name());
1415 EXPECT_EQ(std::string(), loaded_[index]->description());
1416 EXPECT_EQ(0u,
1417 extensions::ContentScriptsInfo::GetContentScripts(
1418 loaded_[index].get()).size());
1419 EXPECT_EQ(Manifest::INTERNAL, loaded_[index]->location());
1420 };
1421
1422 // Test loading bad extensions from the profile directory.
TEST_F(ExtensionServiceTest,LoadAllExtensionsFromDirectoryFail)1423 TEST_F(ExtensionServiceTest, LoadAllExtensionsFromDirectoryFail) {
1424 // Initialize the test dir with a bad Preferences/extensions.
1425 base::FilePath source_install_dir = data_dir_
1426 .AppendASCII("bad")
1427 .AppendASCII("Extensions");
1428 base::FilePath pref_path = source_install_dir
1429 .DirName()
1430 .AppendASCII("Preferences");
1431
1432 InitializeInstalledExtensionService(pref_path, source_install_dir);
1433
1434 service_->Init();
1435
1436 ASSERT_EQ(4u, GetErrors().size());
1437 ASSERT_EQ(0u, loaded_.size());
1438
1439 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[0]),
1440 std::string("Could not load extension from '*'. ") +
1441 extensions::manifest_errors::kManifestUnreadable)) <<
1442 UTF16ToUTF8(GetErrors()[0]);
1443
1444 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[1]),
1445 std::string("Could not load extension from '*'. ") +
1446 extensions::manifest_errors::kManifestUnreadable)) <<
1447 UTF16ToUTF8(GetErrors()[1]);
1448
1449 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[2]),
1450 std::string("Could not load extension from '*'. ") +
1451 extensions::manifest_errors::kMissingFile)) <<
1452 UTF16ToUTF8(GetErrors()[2]);
1453
1454 EXPECT_TRUE(MatchPattern(UTF16ToUTF8(GetErrors()[3]),
1455 std::string("Could not load extension from '*'. ") +
1456 extensions::manifest_errors::kManifestUnreadable)) <<
1457 UTF16ToUTF8(GetErrors()[3]);
1458 };
1459
1460 // Test that partially deleted extensions are cleaned up during startup
1461 // Test loading bad extensions from the profile directory.
TEST_F(ExtensionServiceTest,CleanupOnStartup)1462 TEST_F(ExtensionServiceTest, CleanupOnStartup) {
1463 InitPluginService();
1464 InitializeGoodInstalledExtensionService();
1465
1466 // Simulate that one of them got partially deleted by clearing its pref.
1467 {
1468 DictionaryPrefUpdate update(profile_->GetPrefs(), "extensions.settings");
1469 DictionaryValue* dict = update.Get();
1470 ASSERT_TRUE(dict != NULL);
1471 dict->Remove("behllobkkfkfnphdnhnkndlbkcpglgmj", NULL);
1472 }
1473
1474 service_->Init();
1475 // A delayed task to call GarbageCollectExtensions is posted by
1476 // ExtensionService::Init. As the test won't wait for the delayed task to
1477 // be called, call it manually instead.
1478 service_->GarbageCollectExtensions();
1479 // Wait for GarbageCollectExtensions task to complete.
1480 base::RunLoop().RunUntilIdle();
1481
1482 base::FileEnumerator dirs(extensions_install_dir_, false,
1483 base::FileEnumerator::DIRECTORIES);
1484 size_t count = 0;
1485 while (!dirs.Next().empty())
1486 count++;
1487
1488 // We should have only gotten two extensions now.
1489 EXPECT_EQ(2u, count);
1490
1491 // And extension1 dir should now be toast.
1492 base::FilePath extension_dir = extensions_install_dir_
1493 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj");
1494 ASSERT_FALSE(base::PathExists(extension_dir));
1495 }
1496
1497 // Test that GarbageCollectExtensions deletes the right versions of an
1498 // extension.
TEST_F(ExtensionServiceTest,GarbageCollectWithPendingUpdates)1499 TEST_F(ExtensionServiceTest, GarbageCollectWithPendingUpdates) {
1500 InitPluginService();
1501
1502 base::FilePath source_install_dir = data_dir_
1503 .AppendASCII("pending_updates")
1504 .AppendASCII("Extensions");
1505 base::FilePath pref_path = source_install_dir
1506 .DirName()
1507 .AppendASCII("Preferences");
1508
1509 InitializeInstalledExtensionService(pref_path, source_install_dir);
1510
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")));
1515
1516 service_->GarbageCollectExtensions();
1517 // Wait for GarbageCollectExtensions task to complete.
1518 base::RunLoop().RunUntilIdle();
1519
1520 // Verify that the pending update for the first extension didn't get
1521 // deleted.
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")));
1530 }
1531
1532 // Test that pending updates are properly handled on startup.
TEST_F(ExtensionServiceTest,UpdateOnStartup)1533 TEST_F(ExtensionServiceTest, UpdateOnStartup) {
1534 InitPluginService();
1535
1536 base::FilePath source_install_dir = data_dir_
1537 .AppendASCII("pending_updates")
1538 .AppendASCII("Extensions");
1539 base::FilePath pref_path = source_install_dir
1540 .DirName()
1541 .AppendASCII("Preferences");
1542
1543 InitializeInstalledExtensionService(pref_path, source_install_dir);
1544
1545 // This is the directory that is going to be deleted, so make sure it actually
1546 // is there before the garbage collection.
1547 ASSERT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1548 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1549
1550 service_->Init();
1551 // A delayed task to call GarbageCollectExtensions is posted by
1552 // ExtensionService::Init. As the test won't wait for the delayed task to
1553 // be called, call it manually instead.
1554 service_->GarbageCollectExtensions();
1555 // Wait for GarbageCollectExtensions task to complete.
1556 base::RunLoop().RunUntilIdle();
1557
1558 // Verify that the pending update for the first extension got installed.
1559 EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
1560 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1561 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1562 "bjafgdebaacbbbecmhlhpofkepfkgcpa/2.0")));
1563 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1564 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1565 EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
1566 "hpiknbiabeeppbpihjehijgoemciehgk/3")));
1567
1568 // Make sure update information got deleted.
1569 ExtensionPrefs* prefs = service_->extension_prefs();
1570 EXPECT_FALSE(
1571 prefs->GetDelayedInstallInfo("bjafgdebaacbbbecmhlhpofkepfkgcpa"));
1572 }
1573
1574 // Test various cases for delayed install because of missing imports.
TEST_F(ExtensionServiceTest,PendingImports)1575 TEST_F(ExtensionServiceTest, PendingImports) {
1576 InitPluginService();
1577
1578 base::FilePath source_install_dir = data_dir_
1579 .AppendASCII("pending_updates_with_imports")
1580 .AppendASCII("Extensions");
1581 base::FilePath pref_path = source_install_dir
1582 .DirName()
1583 .AppendASCII("Preferences");
1584
1585 InitializeInstalledExtensionService(pref_path, source_install_dir);
1586
1587 // Verify there are no pending extensions initially.
1588 EXPECT_FALSE(service_->pending_extension_manager()->HasPendingExtensions());
1589
1590 service_->Init();
1591 // Wait for GarbageCollectExtensions task to complete.
1592 base::RunLoop().RunUntilIdle();
1593
1594 // These extensions are used by the extensions we test below, they must be
1595 // installed.
1596 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1597 "bjafgdebaacbbbecmhlhpofkepfkgcpa/1.0")));
1598 EXPECT_TRUE(base::PathExists(extensions_install_dir_.AppendASCII(
1599 "hpiknbiabeeppbpihjehijgoemciehgk/2")));
1600
1601 // Each of these extensions should have been rejected because of dependencies
1602 // that cannot be satisfied.
1603 ExtensionPrefs* prefs = service_->extension_prefs();
1604 EXPECT_FALSE(
1605 prefs->GetDelayedInstallInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1606 EXPECT_FALSE(
1607 prefs->GetInstalledExtensionInfo("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));
1608 EXPECT_FALSE(
1609 prefs->GetDelayedInstallInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1610 EXPECT_FALSE(
1611 prefs->GetInstalledExtensionInfo("bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));
1612 EXPECT_FALSE(
1613 prefs->GetDelayedInstallInfo("cccccccccccccccccccccccccccccccc"));
1614 EXPECT_FALSE(
1615 prefs->GetInstalledExtensionInfo("cccccccccccccccccccccccccccccccc"));
1616
1617 // Make sure the import started for the extension with a dependency.
1618 EXPECT_TRUE(
1619 prefs->GetDelayedInstallInfo("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1620 EXPECT_EQ(ExtensionPrefs::DELAY_REASON_WAIT_FOR_IMPORTS,
1621 prefs->GetDelayedInstallReason("behllobkkfkfnphdnhnkndlbkcpglgmj"));
1622
1623 EXPECT_FALSE(base::PathExists(extensions_install_dir_.AppendASCII(
1624 "behllobkkfkfnphdnhnkndlbkcpglgmj/1.0.0.0")));
1625
1626 EXPECT_TRUE(service_->pending_extension_manager()->HasPendingExtensions());
1627 std::string pending_id("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
1628 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(pending_id));
1629 // Remove it because we are not testing the pending extension manager's
1630 // ability to download and install extensions.
1631 EXPECT_TRUE(service_->pending_extension_manager()->Remove(pending_id));
1632 }
1633
1634 // Test installing extensions. This test tries to install few extensions using
1635 // crx files. If you need to change those crx files, feel free to repackage
1636 // them, throw away the key used and change the id's above.
TEST_F(ExtensionServiceTest,InstallExtension)1637 TEST_F(ExtensionServiceTest, InstallExtension) {
1638 InitializeEmptyExtensionService();
1639
1640 // Extensions not enabled.
1641 set_extensions_enabled(false);
1642 base::FilePath path = data_dir_.AppendASCII("good.crx");
1643 InstallCRX(path, INSTALL_FAILED);
1644 set_extensions_enabled(true);
1645
1646 ValidatePrefKeyCount(0);
1647
1648 // A simple extension that should install without error.
1649 path = data_dir_.AppendASCII("good.crx");
1650 InstallCRX(path, INSTALL_NEW);
1651 // TODO(erikkay): verify the contents of the installed extension.
1652
1653 int pref_count = 0;
1654 ValidatePrefKeyCount(++pref_count);
1655 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
1656 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
1657
1658 // An extension with page actions.
1659 path = data_dir_.AppendASCII("page_action.crx");
1660 InstallCRX(path, INSTALL_NEW);
1661 ValidatePrefKeyCount(++pref_count);
1662 ValidateIntegerPref(page_action, "state", Extension::ENABLED);
1663 ValidateIntegerPref(page_action, "location", Manifest::INTERNAL);
1664
1665 // Bad signature.
1666 path = data_dir_.AppendASCII("bad_signature.crx");
1667 InstallCRX(path, INSTALL_FAILED);
1668 ValidatePrefKeyCount(pref_count);
1669
1670 // 0-length extension file.
1671 path = data_dir_.AppendASCII("not_an_extension.crx");
1672 InstallCRX(path, INSTALL_FAILED);
1673 ValidatePrefKeyCount(pref_count);
1674
1675 // Bad magic number.
1676 path = data_dir_.AppendASCII("bad_magic.crx");
1677 InstallCRX(path, INSTALL_FAILED);
1678 ValidatePrefKeyCount(pref_count);
1679
1680 // Packed extensions may have folders or files that have underscores.
1681 // This will only cause a warning, rather than a fatal error.
1682 path = data_dir_.AppendASCII("bad_underscore.crx");
1683 InstallCRX(path, INSTALL_NEW);
1684 ValidatePrefKeyCount(++pref_count);
1685
1686 // A test for an extension with a 2048-bit public key.
1687 path = data_dir_.AppendASCII("good2048.crx");
1688 InstallCRX(path, INSTALL_NEW);
1689 ValidatePrefKeyCount(++pref_count);
1690 ValidateIntegerPref(good2048, "state", Extension::ENABLED);
1691 ValidateIntegerPref(good2048, "location", Manifest::INTERNAL);
1692
1693 // TODO(erikkay): add more tests for many of the failure cases.
1694 // TODO(erikkay): add tests for upgrade cases.
1695 }
1696
1697 struct MockInstallObserver : public extensions::InstallObserver {
MockInstallObserverMockInstallObserver1698 MockInstallObserver() {
1699 }
1700
~MockInstallObserverMockInstallObserver1701 virtual ~MockInstallObserver() {
1702 }
1703
OnBeginExtensionInstallMockInstallObserver1704 virtual void OnBeginExtensionInstall(
1705 const ExtensionInstallParams& params) OVERRIDE {
1706 }
1707
OnDownloadProgressMockInstallObserver1708 virtual void OnDownloadProgress(const std::string& extension_id,
1709 int percent_downloaded) OVERRIDE {
1710 }
1711
OnExtensionInstalledMockInstallObserver1712 virtual void OnExtensionInstalled(const Extension* extension) OVERRIDE {
1713 last_extension_installed = extension->id();
1714 }
1715
OnInstallFailureMockInstallObserver1716 virtual void OnInstallFailure(const std::string& extension_id) OVERRIDE {
1717 }
1718
OnExtensionLoadedMockInstallObserver1719 virtual void OnExtensionLoaded(const Extension* extension) OVERRIDE {
1720 }
1721
OnExtensionUnloadedMockInstallObserver1722 virtual void OnExtensionUnloaded(const Extension* extension) OVERRIDE {
1723 }
1724
OnExtensionUninstalledMockInstallObserver1725 virtual void OnExtensionUninstalled(const Extension* extension) OVERRIDE {
1726 last_extension_uninstalled = extension->id();
1727 }
1728
OnAppsReorderedMockInstallObserver1729 virtual void OnAppsReordered() OVERRIDE {
1730 }
1731
OnAppInstalledToAppListMockInstallObserver1732 virtual void OnAppInstalledToAppList(
1733 const std::string& extension_id) OVERRIDE {
1734 }
1735
OnShutdownMockInstallObserver1736 virtual void OnShutdown() OVERRIDE {
1737 }
1738
1739 std::string last_extension_installed;
1740 std::string last_extension_uninstalled;
1741 };
1742
1743 // Test that correct notifications are sent to InstallTracker observers on
1744 // extension install and uninstall.
TEST_F(ExtensionServiceTest,InstallObserverNotified)1745 TEST_F(ExtensionServiceTest, InstallObserverNotified) {
1746 InitializeEmptyExtensionService();
1747
1748 extensions::InstallTracker* tracker(
1749 extensions::InstallTrackerFactory::GetForProfile(profile_.get()));
1750 MockInstallObserver observer;
1751 tracker->AddObserver(&observer);
1752
1753 // A simple extension that should install without error.
1754 ASSERT_TRUE(observer.last_extension_installed.empty());
1755 base::FilePath path = data_dir_.AppendASCII("good.crx");
1756 InstallCRX(path, INSTALL_NEW);
1757 ASSERT_EQ(good_crx, observer.last_extension_installed);
1758
1759 // Uninstall the extension.
1760 ASSERT_TRUE(observer.last_extension_uninstalled.empty());
1761 UninstallExtension(good_crx, false);
1762 ASSERT_EQ(good_crx, observer.last_extension_uninstalled);
1763
1764 tracker->RemoveObserver(&observer);
1765 }
1766
1767 // Tests that flags passed to OnExternalExtensionFileFound() make it to the
1768 // extension object.
TEST_F(ExtensionServiceTest,InstallingExternalExtensionWithFlags)1769 TEST_F(ExtensionServiceTest, InstallingExternalExtensionWithFlags) {
1770 const char kPrefFromBookmark[] = "from_bookmark";
1771
1772 InitializeEmptyExtensionService();
1773
1774 base::FilePath path = data_dir_.AppendASCII("good.crx");
1775 set_extensions_enabled(true);
1776
1777 // Register and install an external extension.
1778 Version version("1.0.0.0");
1779 content::WindowedNotificationObserver observer(
1780 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1781 content::NotificationService::AllSources());
1782 if (service_->OnExternalExtensionFileFound(
1783 good_crx,
1784 &version,
1785 path,
1786 Manifest::EXTERNAL_PREF,
1787 Extension::FROM_BOOKMARK,
1788 false /* mark_acknowledged */)) {
1789 observer.Wait();
1790 }
1791
1792 const Extension* extension = service_->GetExtensionById(good_crx, false);
1793 ASSERT_TRUE(extension);
1794 ASSERT_TRUE(extension->from_bookmark());
1795 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1796
1797 // Upgrade to version 2.0, the flag should be preserved.
1798 path = data_dir_.AppendASCII("good2.crx");
1799 UpdateExtension(good_crx, path, ENABLED);
1800 ASSERT_TRUE(ValidateBooleanPref(good_crx, kPrefFromBookmark, true));
1801 extension = service_->GetExtensionById(good_crx, false);
1802 ASSERT_TRUE(extension);
1803 ASSERT_TRUE(extension->from_bookmark());
1804 }
1805
1806 // Test the handling of Extension::EXTERNAL_EXTENSION_UNINSTALLED
TEST_F(ExtensionServiceTest,UninstallingExternalExtensions)1807 TEST_F(ExtensionServiceTest, UninstallingExternalExtensions) {
1808 InitializeEmptyExtensionService();
1809
1810 base::FilePath path = data_dir_.AppendASCII("good.crx");
1811 set_extensions_enabled(true);
1812
1813 // Install an external extension.
1814 Version version("1.0.0.0");
1815 content::WindowedNotificationObserver observer(
1816 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1817 content::NotificationService::AllSources());
1818 if (service_->OnExternalExtensionFileFound(good_crx, &version,
1819 path, Manifest::EXTERNAL_PREF,
1820 Extension::NO_FLAGS, false)) {
1821 observer.Wait();
1822 }
1823
1824 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1825
1826 // Uninstall it and check that its killbit gets set.
1827 UninstallExtension(good_crx, false);
1828 ValidateIntegerPref(good_crx, "location",
1829 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1830
1831 // Try to re-install it externally. This should fail because of the killbit.
1832 service_->OnExternalExtensionFileFound(good_crx, &version,
1833 path, Manifest::EXTERNAL_PREF,
1834 Extension::NO_FLAGS, false);
1835 base::RunLoop().RunUntilIdle();
1836 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
1837 ValidateIntegerPref(good_crx, "location",
1838 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1839
1840 version = Version("1.0.0.1");
1841 // Repeat the same thing with a newer version of the extension.
1842 path = data_dir_.AppendASCII("good2.crx");
1843 service_->OnExternalExtensionFileFound(good_crx, &version,
1844 path, Manifest::EXTERNAL_PREF,
1845 Extension::NO_FLAGS, false);
1846 base::RunLoop().RunUntilIdle();
1847 ASSERT_TRUE(NULL == service_->GetExtensionById(good_crx, false));
1848 ValidateIntegerPref(good_crx, "location",
1849 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
1850
1851 // Try adding the same extension from an external update URL.
1852 ASSERT_FALSE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
1853 good_crx,
1854 GURL("http:://fake.update/url"),
1855 Manifest::EXTERNAL_PREF_DOWNLOAD,
1856 Extension::NO_FLAGS,
1857 false));
1858
1859 ASSERT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
1860 }
1861
1862 // Test that uninstalling an external extension does not crash when
1863 // the extension could not be loaded.
1864 // This extension shown in preferences file requires an experimental permission.
1865 // It could not be loaded without such permission.
TEST_F(ExtensionServiceTest,UninstallingNotLoadedExtension)1866 TEST_F(ExtensionServiceTest, UninstallingNotLoadedExtension) {
1867 base::FilePath source_install_dir = data_dir_
1868 .AppendASCII("good")
1869 .AppendASCII("Extensions");
1870 // The preference contains an external extension
1871 // that requires 'experimental' permission.
1872 base::FilePath pref_path = source_install_dir
1873 .DirName()
1874 .AppendASCII("PreferencesExperimental");
1875
1876 // Aforementioned extension will not be loaded if
1877 // there is no '--enable-experimental-extension-apis' command line flag.
1878 InitializeInstalledExtensionService(pref_path, source_install_dir);
1879
1880 service_->Init();
1881
1882 // Check and try to uninstall it.
1883 // If we don't check whether the extension is loaded before we uninstall it
1884 // in CheckExternalUninstall, a crash will happen here because we will get or
1885 // dereference a NULL pointer (extension) inside UninstallExtension.
1886 MockExtensionProvider provider(NULL, Manifest::EXTERNAL_REGISTRY);
1887 service_->OnExternalProviderReady(&provider);
1888 }
1889
1890 // Test that external extensions with incorrect IDs are not installed.
TEST_F(ExtensionServiceTest,FailOnWrongId)1891 TEST_F(ExtensionServiceTest, FailOnWrongId) {
1892 InitializeEmptyExtensionService();
1893 base::FilePath path = data_dir_.AppendASCII("good.crx");
1894 set_extensions_enabled(true);
1895
1896 Version version("1.0.0.0");
1897
1898 const std::string wrong_id = all_zero;
1899 const std::string correct_id = good_crx;
1900 ASSERT_NE(correct_id, wrong_id);
1901
1902 // Install an external extension with an ID from the external
1903 // source that is not equal to the ID in the extension manifest.
1904 content::WindowedNotificationObserver observer(
1905 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1906 content::NotificationService::AllSources());
1907 service_->OnExternalExtensionFileFound(
1908 wrong_id, &version, path, Manifest::EXTERNAL_PREF,
1909 Extension::NO_FLAGS, false);
1910
1911 observer.Wait();
1912 ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1913
1914 // Try again with the right ID. Expect success.
1915 content::WindowedNotificationObserver observer2(
1916 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1917 content::NotificationService::AllSources());
1918 if (service_->OnExternalExtensionFileFound(
1919 correct_id, &version, path, Manifest::EXTERNAL_PREF,
1920 Extension::NO_FLAGS, false)) {
1921 observer2.Wait();
1922 }
1923 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1924 }
1925
1926 // Test that external extensions with incorrect versions are not installed.
TEST_F(ExtensionServiceTest,FailOnWrongVersion)1927 TEST_F(ExtensionServiceTest, FailOnWrongVersion) {
1928 InitializeEmptyExtensionService();
1929 base::FilePath path = data_dir_.AppendASCII("good.crx");
1930 set_extensions_enabled(true);
1931
1932 // Install an external extension with a version from the external
1933 // source that is not equal to the version in the extension manifest.
1934 Version wrong_version("1.2.3.4");
1935 content::WindowedNotificationObserver observer(
1936 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1937 content::NotificationService::AllSources());
1938 service_->OnExternalExtensionFileFound(
1939 good_crx, &wrong_version, path, Manifest::EXTERNAL_PREF,
1940 Extension::NO_FLAGS, false);
1941
1942 observer.Wait();
1943 ASSERT_FALSE(service_->GetExtensionById(good_crx, false));
1944
1945 // Try again with the right version. Expect success.
1946 service_->pending_extension_manager()->Remove(good_crx);
1947 Version correct_version("1.0.0.0");
1948 content::WindowedNotificationObserver observer2(
1949 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
1950 content::NotificationService::AllSources());
1951 if (service_->OnExternalExtensionFileFound(
1952 good_crx, &correct_version, path, Manifest::EXTERNAL_PREF,
1953 Extension::NO_FLAGS, false)) {
1954 observer2.Wait();
1955 }
1956 ASSERT_TRUE(service_->GetExtensionById(good_crx, false));
1957 }
1958
1959 // Install a user script (they get converted automatically to an extension)
TEST_F(ExtensionServiceTest,InstallUserScript)1960 TEST_F(ExtensionServiceTest, InstallUserScript) {
1961 // The details of script conversion are tested elsewhere, this just tests
1962 // integration with ExtensionService.
1963 InitializeEmptyExtensionService();
1964
1965 base::FilePath path = data_dir_
1966 .AppendASCII("user_script_basic.user.js");
1967
1968 ASSERT_TRUE(base::PathExists(path));
1969 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
1970 installer->set_allow_silent_install(true);
1971 installer->InstallUserScript(
1972 path,
1973 GURL("http://www.aaronboodman.com/scripts/user_script_basic.user.js"));
1974
1975 base::RunLoop().RunUntilIdle();
1976 std::vector<base::string16> errors = GetErrors();
1977 EXPECT_TRUE(installed_) << "Nothing was installed.";
1978 EXPECT_FALSE(was_update_) << path.value();
1979 ASSERT_EQ(1u, loaded_.size()) << "Nothing was loaded.";
1980 EXPECT_EQ(0u, errors.size()) << "There were errors: "
1981 << JoinString(errors, ',');
1982 EXPECT_TRUE(service_->GetExtensionById(loaded_[0]->id(), false)) <<
1983 path.value();
1984
1985 installed_ = NULL;
1986 was_update_ = false;
1987 loaded_.clear();
1988 ExtensionErrorReporter::GetInstance()->ClearErrors();
1989 }
1990
1991 // Extensions don't install during shutdown.
TEST_F(ExtensionServiceTest,InstallExtensionDuringShutdown)1992 TEST_F(ExtensionServiceTest, InstallExtensionDuringShutdown) {
1993 InitializeEmptyExtensionService();
1994
1995 // Simulate shutdown.
1996 service_->set_browser_terminating_for_test(true);
1997
1998 base::FilePath path = data_dir_.AppendASCII("good.crx");
1999 scoped_refptr<CrxInstaller> installer(CrxInstaller::CreateSilent(service_));
2000 installer->set_allow_silent_install(true);
2001 installer->InstallCrx(path);
2002 base::RunLoop().RunUntilIdle();
2003
2004 EXPECT_FALSE(installed_) << "Extension installed during shutdown.";
2005 ASSERT_EQ(0u, loaded_.size()) << "Extension loaded during shutdown.";
2006 }
2007
2008 // This tests that the granted permissions preferences are correctly set when
2009 // installing an extension.
TEST_F(ExtensionServiceTest,GrantedPermissions)2010 TEST_F(ExtensionServiceTest, GrantedPermissions) {
2011 InitializeEmptyExtensionService();
2012 base::FilePath path = data_dir_
2013 .AppendASCII("permissions");
2014
2015 base::FilePath pem_path = path.AppendASCII("unknown.pem");
2016 path = path.AppendASCII("unknown");
2017
2018 ASSERT_TRUE(base::PathExists(pem_path));
2019 ASSERT_TRUE(base::PathExists(path));
2020
2021 ExtensionPrefs* prefs = service_->extension_prefs();
2022
2023 APIPermissionSet expected_api_perms;
2024 URLPatternSet expected_host_perms;
2025
2026 // Make sure there aren't any granted permissions before the
2027 // extension is installed.
2028 scoped_refptr<PermissionSet> known_perms(
2029 prefs->GetGrantedPermissions(permissions_crx));
2030 EXPECT_FALSE(known_perms.get());
2031
2032 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
2033
2034 EXPECT_EQ(0u, GetErrors().size());
2035 ASSERT_EQ(1u, service_->extensions()->size());
2036 EXPECT_EQ(permissions_crx, extension->id());
2037
2038 // Verify that the valid API permissions have been recognized.
2039 expected_api_perms.insert(APIPermission::kTab);
2040
2041 AddPattern(&expected_host_perms, "http://*.google.com/*");
2042 AddPattern(&expected_host_perms, "https://*.google.com/*");
2043 AddPattern(&expected_host_perms, "http://*.google.com.hk/*");
2044 AddPattern(&expected_host_perms, "http://www.example.com/*");
2045
2046 known_perms = prefs->GetGrantedPermissions(extension->id());
2047 EXPECT_TRUE(known_perms.get());
2048 EXPECT_FALSE(known_perms->IsEmpty());
2049 EXPECT_EQ(expected_api_perms, known_perms->apis());
2050 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
2051 EXPECT_EQ(expected_host_perms, known_perms->effective_hosts());
2052 }
2053
2054
2055 #if !defined(OS_CHROMEOS)
2056 // This tests that the granted permissions preferences are correctly set for
2057 // default apps.
TEST_F(ExtensionServiceTest,DefaultAppsGrantedPermissions)2058 TEST_F(ExtensionServiceTest, DefaultAppsGrantedPermissions) {
2059 InitializeEmptyExtensionService();
2060 base::FilePath path = data_dir_
2061 .AppendASCII("permissions");
2062
2063 base::FilePath pem_path = path.AppendASCII("unknown.pem");
2064 path = path.AppendASCII("unknown");
2065
2066 ASSERT_TRUE(base::PathExists(pem_path));
2067 ASSERT_TRUE(base::PathExists(path));
2068
2069 ExtensionPrefs* prefs = service_->extension_prefs();
2070
2071 APIPermissionSet expected_api_perms;
2072 URLPatternSet expected_host_perms;
2073
2074 // Make sure there aren't any granted permissions before the
2075 // extension is installed.
2076 scoped_refptr<PermissionSet> known_perms(
2077 prefs->GetGrantedPermissions(permissions_crx));
2078 EXPECT_FALSE(known_perms.get());
2079
2080 const Extension* extension = PackAndInstallCRX(
2081 path, pem_path, INSTALL_NEW, Extension::WAS_INSTALLED_BY_DEFAULT);
2082
2083 EXPECT_EQ(0u, GetErrors().size());
2084 ASSERT_EQ(1u, service_->extensions()->size());
2085 EXPECT_EQ(permissions_crx, extension->id());
2086
2087 // Verify that the valid API permissions have been recognized.
2088 expected_api_perms.insert(APIPermission::kTab);
2089
2090 known_perms = prefs->GetGrantedPermissions(extension->id());
2091 EXPECT_TRUE(known_perms.get());
2092 EXPECT_FALSE(known_perms->IsEmpty());
2093 EXPECT_EQ(expected_api_perms, known_perms->apis());
2094 EXPECT_FALSE(known_perms->HasEffectiveFullAccess());
2095 }
2096 #endif
2097
2098 #if !defined(OS_CHROMEOS)
2099 // Tests that the granted permissions full_access bit gets set correctly when
2100 // an extension contains an NPAPI plugin. Don't run this test on Chrome OS
2101 // since they don't support plugins.
TEST_F(ExtensionServiceTest,GrantedFullAccessPermissions)2102 TEST_F(ExtensionServiceTest, GrantedFullAccessPermissions) {
2103 InitPluginService();
2104
2105 InitializeEmptyExtensionService();
2106
2107 ASSERT_TRUE(base::PathExists(good1_path()));
2108 const Extension* extension = PackAndInstallCRX(good1_path(), INSTALL_NEW);
2109 EXPECT_EQ(0u, GetErrors().size());
2110 EXPECT_EQ(1u, service_->extensions()->size());
2111 ExtensionPrefs* prefs = service_->extension_prefs();
2112
2113 scoped_refptr<PermissionSet> permissions(
2114 prefs->GetGrantedPermissions(extension->id()));
2115 EXPECT_FALSE(permissions->IsEmpty());
2116 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
2117 EXPECT_FALSE(permissions->apis().empty());
2118 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
2119
2120 // Full access implies full host access too...
2121 EXPECT_TRUE(permissions->HasEffectiveAccessToAllHosts());
2122 }
2123 #endif
2124
2125 // Tests that the extension is disabled when permissions are missing from
2126 // the extension's granted permissions preferences. (This simulates updating
2127 // the browser to a version which recognizes more permissions).
TEST_F(ExtensionServiceTest,GrantedAPIAndHostPermissions)2128 TEST_F(ExtensionServiceTest, GrantedAPIAndHostPermissions) {
2129 InitializeEmptyExtensionService();
2130
2131 base::FilePath path = data_dir_
2132 .AppendASCII("permissions")
2133 .AppendASCII("unknown");
2134
2135 ASSERT_TRUE(base::PathExists(path));
2136
2137 const Extension* extension = PackAndInstallCRX(path, INSTALL_NEW);
2138
2139 EXPECT_EQ(0u, GetErrors().size());
2140 EXPECT_EQ(1u, service_->extensions()->size());
2141 std::string extension_id = extension->id();
2142
2143 ExtensionPrefs* prefs = service_->extension_prefs();
2144
2145 APIPermissionSet expected_api_permissions;
2146 URLPatternSet expected_host_permissions;
2147
2148 expected_api_permissions.insert(APIPermission::kTab);
2149 AddPattern(&expected_host_permissions, "http://*.google.com/*");
2150 AddPattern(&expected_host_permissions, "https://*.google.com/*");
2151 AddPattern(&expected_host_permissions, "http://*.google.com.hk/*");
2152 AddPattern(&expected_host_permissions, "http://www.example.com/*");
2153
2154 std::set<std::string> host_permissions;
2155
2156 // Test that the extension is disabled when an API permission is missing from
2157 // the extension's granted api permissions preference. (This simulates
2158 // updating the browser to a version which recognizes a new API permission).
2159 SetPref(extension_id, "granted_permissions.api",
2160 new ListValue(), "granted_permissions.api");
2161 service_->ReloadExtensions();
2162
2163 EXPECT_EQ(1u, service_->disabled_extensions()->size());
2164 extension = service_->disabled_extensions()->begin()->get();
2165
2166 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2167 ASSERT_FALSE(service_->IsExtensionEnabled(extension_id));
2168 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2169
2170 // Now grant and re-enable the extension, making sure the prefs are updated.
2171 service_->GrantPermissionsAndEnableExtension(extension);
2172
2173 ASSERT_FALSE(prefs->IsExtensionDisabled(extension_id));
2174 ASSERT_TRUE(service_->IsExtensionEnabled(extension_id));
2175 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2176
2177 scoped_refptr<PermissionSet> current_perms(
2178 prefs->GetGrantedPermissions(extension_id));
2179 ASSERT_TRUE(current_perms.get());
2180 ASSERT_FALSE(current_perms->IsEmpty());
2181 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2182 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2183 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2184
2185 // Tests that the extension is disabled when a host permission is missing from
2186 // the extension's granted host permissions preference. (This simulates
2187 // updating the browser to a version which recognizes additional host
2188 // permissions).
2189 host_permissions.clear();
2190 current_perms = NULL;
2191
2192 host_permissions.insert("http://*.google.com/*");
2193 host_permissions.insert("https://*.google.com/*");
2194 host_permissions.insert("http://*.google.com.hk/*");
2195
2196 ListValue* api_permissions = new ListValue();
2197 api_permissions->Append(
2198 new base::StringValue("tabs"));
2199 SetPref(extension_id, "granted_permissions.api",
2200 api_permissions, "granted_permissions.api");
2201 SetPrefStringSet(
2202 extension_id, "granted_permissions.scriptable_host", host_permissions);
2203
2204 service_->ReloadExtensions();
2205
2206 EXPECT_EQ(1u, service_->disabled_extensions()->size());
2207 extension = service_->disabled_extensions()->begin()->get();
2208
2209 ASSERT_TRUE(prefs->IsExtensionDisabled(extension_id));
2210 ASSERT_FALSE(service_->IsExtensionEnabled(extension_id));
2211 ASSERT_TRUE(prefs->DidExtensionEscalatePermissions(extension_id));
2212
2213 // Now grant and re-enable the extension, making sure the prefs are updated.
2214 service_->GrantPermissionsAndEnableExtension(extension);
2215
2216 ASSERT_TRUE(service_->IsExtensionEnabled(extension_id));
2217 ASSERT_FALSE(prefs->DidExtensionEscalatePermissions(extension_id));
2218
2219 current_perms = prefs->GetGrantedPermissions(extension_id);
2220 ASSERT_TRUE(current_perms.get());
2221 ASSERT_FALSE(current_perms->IsEmpty());
2222 ASSERT_FALSE(current_perms->HasEffectiveFullAccess());
2223 ASSERT_EQ(expected_api_permissions, current_perms->apis());
2224 ASSERT_EQ(expected_host_permissions, current_perms->effective_hosts());
2225 }
2226
2227 // Test Packaging and installing an extension.
TEST_F(ExtensionServiceTest,PackExtension)2228 TEST_F(ExtensionServiceTest, PackExtension) {
2229 InitializeEmptyExtensionService();
2230 base::FilePath input_directory = data_dir_
2231 .AppendASCII("good")
2232 .AppendASCII("Extensions")
2233 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2234 .AppendASCII("1.0.0.0");
2235
2236 base::ScopedTempDir temp_dir;
2237 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2238 base::FilePath output_directory = temp_dir.path();
2239
2240 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2241 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2242
2243 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2244 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2245 privkey_path, ExtensionCreator::kNoRunFlags));
2246 ASSERT_TRUE(base::PathExists(crx_path));
2247 ASSERT_TRUE(base::PathExists(privkey_path));
2248
2249 // Repeat the run with the pem file gone, and no special flags
2250 // Should refuse to overwrite the existing crx.
2251 base::DeleteFile(privkey_path, false);
2252 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2253 privkey_path, ExtensionCreator::kNoRunFlags));
2254
2255 // OK, now try it with a flag to overwrite existing crx. Should work.
2256 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2257 privkey_path, ExtensionCreator::kOverwriteCRX));
2258
2259 // Repeat the run allowing existing crx, but the existing pem is still
2260 // an error. Should fail.
2261 ASSERT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2262 privkey_path, ExtensionCreator::kOverwriteCRX));
2263
2264 ASSERT_TRUE(base::PathExists(privkey_path));
2265 InstallCRX(crx_path, INSTALL_NEW);
2266
2267 // Try packing with invalid paths.
2268 creator.reset(new ExtensionCreator());
2269 ASSERT_FALSE(
2270 creator->Run(base::FilePath(), base::FilePath(), base::FilePath(),
2271 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2272
2273 // Try packing an empty directory. Should fail because an empty directory is
2274 // not a valid extension.
2275 base::ScopedTempDir temp_dir2;
2276 ASSERT_TRUE(temp_dir2.CreateUniqueTempDir());
2277 creator.reset(new ExtensionCreator());
2278 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2279 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2280
2281 // Try packing with an invalid manifest.
2282 std::string invalid_manifest_content = "I am not a manifest.";
2283 ASSERT_TRUE(file_util::WriteFile(
2284 temp_dir2.path().Append(extensions::kManifestFilename),
2285 invalid_manifest_content.c_str(), invalid_manifest_content.size()));
2286 creator.reset(new ExtensionCreator());
2287 ASSERT_FALSE(creator->Run(temp_dir2.path(), crx_path, privkey_path,
2288 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2289
2290 // Try packing with a private key that is a valid key, but invalid for the
2291 // extension.
2292 base::FilePath bad_private_key_dir = data_dir_.AppendASCII("bad_private_key");
2293 crx_path = output_directory.AppendASCII("bad_private_key.crx");
2294 privkey_path = data_dir_.AppendASCII("bad_private_key.pem");
2295 ASSERT_FALSE(creator->Run(bad_private_key_dir, crx_path, base::FilePath(),
2296 privkey_path, ExtensionCreator::kOverwriteCRX));
2297 }
2298
2299 // Test Packaging and installing an extension whose name contains punctuation.
TEST_F(ExtensionServiceTest,PackPunctuatedExtension)2300 TEST_F(ExtensionServiceTest, PackPunctuatedExtension) {
2301 InitializeEmptyExtensionService();
2302 base::FilePath input_directory = data_dir_
2303 .AppendASCII("good")
2304 .AppendASCII("Extensions")
2305 .AppendASCII(good0)
2306 .AppendASCII("1.0.0.0");
2307
2308 base::ScopedTempDir temp_dir;
2309 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2310
2311 // Extension names containing punctuation, and the expected names for the
2312 // packed extensions.
2313 const base::FilePath punctuated_names[] = {
2314 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods")),
2315 base::FilePath(FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod")),
2316 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname/")).
2317 NormalizePathSeparators(),
2318 };
2319 const base::FilePath expected_crx_names[] = {
2320 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.crx")),
2321 base::FilePath(
2322 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.crx")),
2323 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.crx")),
2324 };
2325 const base::FilePath expected_private_key_names[] = {
2326 base::FilePath(FILE_PATH_LITERAL("this.extensions.name.has.periods.pem")),
2327 base::FilePath(
2328 FILE_PATH_LITERAL(".thisextensionsnamestartswithaperiod.pem")),
2329 base::FilePath(FILE_PATH_LITERAL("thisextensionhasaslashinitsname.pem")),
2330 };
2331
2332 for (size_t i = 0; i < arraysize(punctuated_names); ++i) {
2333 SCOPED_TRACE(punctuated_names[i].value().c_str());
2334 base::FilePath output_dir = temp_dir.path().Append(punctuated_names[i]);
2335
2336 // Copy the extension into the output directory, as PackExtensionJob doesn't
2337 // let us choose where to output the packed extension.
2338 ASSERT_TRUE(base::CopyDirectory(input_directory, output_dir, true));
2339
2340 base::FilePath expected_crx_path =
2341 temp_dir.path().Append(expected_crx_names[i]);
2342 base::FilePath expected_private_key_path =
2343 temp_dir.path().Append(expected_private_key_names[i]);
2344 PackExtensionTestClient pack_client(expected_crx_path,
2345 expected_private_key_path);
2346 scoped_refptr<extensions::PackExtensionJob> packer(
2347 new extensions::PackExtensionJob(&pack_client, output_dir,
2348 base::FilePath(),
2349 ExtensionCreator::kOverwriteCRX));
2350 packer->Start();
2351
2352 // The packer will post a notification task to the current thread's message
2353 // loop when it is finished. We manually run the loop here so that we
2354 // block and catch the notification; otherwise, the process would exit.
2355 // This call to |Run()| is matched by a call to |Quit()| in the
2356 // |PackExtensionTestClient|'s notification handling code.
2357 base::MessageLoop::current()->Run();
2358
2359 if (HasFatalFailure())
2360 return;
2361
2362 InstallCRX(expected_crx_path, INSTALL_NEW);
2363 }
2364 }
2365
TEST_F(ExtensionServiceTest,PackExtensionContainingKeyFails)2366 TEST_F(ExtensionServiceTest, PackExtensionContainingKeyFails) {
2367 InitializeEmptyExtensionService();
2368
2369 base::ScopedTempDir extension_temp_dir;
2370 ASSERT_TRUE(extension_temp_dir.CreateUniqueTempDir());
2371 base::FilePath input_directory = extension_temp_dir.path().AppendASCII("ext");
2372 ASSERT_TRUE(base::CopyDirectory(
2373 data_dir_
2374 .AppendASCII("good")
2375 .AppendASCII("Extensions")
2376 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2377 .AppendASCII("1.0.0.0"),
2378 input_directory,
2379 /*recursive=*/true));
2380
2381 base::ScopedTempDir output_temp_dir;
2382 ASSERT_TRUE(output_temp_dir.CreateUniqueTempDir());
2383 base::FilePath output_directory = output_temp_dir.path();
2384
2385 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2386 base::FilePath privkey_path(output_directory.AppendASCII("privkey.pem"));
2387
2388 // Pack the extension once to get a private key.
2389 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2390 ASSERT_TRUE(creator->Run(input_directory, crx_path, base::FilePath(),
2391 privkey_path, ExtensionCreator::kNoRunFlags))
2392 << creator->error_message();
2393 ASSERT_TRUE(base::PathExists(crx_path));
2394 ASSERT_TRUE(base::PathExists(privkey_path));
2395
2396 base::DeleteFile(crx_path, false);
2397 // Move the pem file into the extension.
2398 base::Move(privkey_path,
2399 input_directory.AppendASCII("privkey.pem"));
2400
2401 // This pack should fail because of the contained private key.
2402 EXPECT_FALSE(creator->Run(input_directory, crx_path, base::FilePath(),
2403 privkey_path, ExtensionCreator::kNoRunFlags));
2404 EXPECT_THAT(creator->error_message(),
2405 testing::ContainsRegex(
2406 "extension includes the key file.*privkey.pem"));
2407 }
2408
2409 // Test Packaging and installing an extension using an openssl generated key.
2410 // The openssl is generated with the following:
2411 // > openssl genrsa -out privkey.pem 1024
2412 // > openssl pkcs8 -topk8 -nocrypt -in privkey.pem -out privkey_asn1.pem
2413 // The privkey.pem is a PrivateKey, and the pcks8 -topk8 creates a
2414 // PrivateKeyInfo ASN.1 structure, we our RSAPrivateKey expects.
TEST_F(ExtensionServiceTest,PackExtensionOpenSSLKey)2415 TEST_F(ExtensionServiceTest, PackExtensionOpenSSLKey) {
2416 InitializeEmptyExtensionService();
2417 base::FilePath input_directory = data_dir_
2418 .AppendASCII("good")
2419 .AppendASCII("Extensions")
2420 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
2421 .AppendASCII("1.0.0.0");
2422 base::FilePath privkey_path(data_dir_.AppendASCII(
2423 "openssl_privkey_asn1.pem"));
2424 ASSERT_TRUE(base::PathExists(privkey_path));
2425
2426 base::ScopedTempDir temp_dir;
2427 ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
2428 base::FilePath output_directory = temp_dir.path();
2429
2430 base::FilePath crx_path(output_directory.AppendASCII("ex1.crx"));
2431
2432 scoped_ptr<ExtensionCreator> creator(new ExtensionCreator());
2433 ASSERT_TRUE(creator->Run(input_directory, crx_path, privkey_path,
2434 base::FilePath(), ExtensionCreator::kOverwriteCRX));
2435
2436 InstallCRX(crx_path, INSTALL_NEW);
2437 }
2438
TEST_F(ExtensionServiceTest,InstallTheme)2439 TEST_F(ExtensionServiceTest, InstallTheme) {
2440 InitializeEmptyExtensionService();
2441 service_->Init();
2442
2443 // A theme.
2444 base::FilePath path = data_dir_.AppendASCII("theme.crx");
2445 InstallCRX(path, INSTALL_NEW);
2446 int pref_count = 0;
2447 ValidatePrefKeyCount(++pref_count);
2448 ValidateIntegerPref(theme_crx, "state", Extension::ENABLED);
2449 ValidateIntegerPref(theme_crx, "location", Manifest::INTERNAL);
2450
2451 // A theme when extensions are disabled. Themes can be installed, even when
2452 // extensions are disabled.
2453 set_extensions_enabled(false);
2454 path = data_dir_.AppendASCII("theme2.crx");
2455 InstallCRX(path, INSTALL_NEW);
2456 ValidatePrefKeyCount(++pref_count);
2457 ValidateIntegerPref(theme2_crx, "state", Extension::ENABLED);
2458 ValidateIntegerPref(theme2_crx, "location", Manifest::INTERNAL);
2459
2460 // A theme with extension elements. Themes cannot have extension elements,
2461 // so any such elements (like content scripts) should be ignored.
2462 set_extensions_enabled(true);
2463 {
2464 path = data_dir_.AppendASCII("theme_with_extension.crx");
2465 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2466 ValidatePrefKeyCount(++pref_count);
2467 ASSERT_TRUE(extension);
2468 EXPECT_TRUE(extension->is_theme());
2469 EXPECT_EQ(
2470 0u,
2471 extensions::ContentScriptsInfo::GetContentScripts(extension).size());
2472 }
2473
2474 // A theme with image resources missing (misspelt path).
2475 path = data_dir_.AppendASCII("theme_missing_image.crx");
2476 InstallCRX(path, INSTALL_FAILED);
2477 ValidatePrefKeyCount(pref_count);
2478 }
2479
TEST_F(ExtensionServiceTest,LoadLocalizedTheme)2480 TEST_F(ExtensionServiceTest, LoadLocalizedTheme) {
2481 // Load.
2482 InitializeEmptyExtensionService();
2483 service_->Init();
2484
2485 base::FilePath extension_path = data_dir_
2486 .AppendASCII("theme_i18n");
2487
2488 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2489 base::RunLoop().RunUntilIdle();
2490 EXPECT_EQ(0u, GetErrors().size());
2491 ASSERT_EQ(1u, loaded_.size());
2492 EXPECT_EQ(1u, service_->extensions()->size());
2493 const Extension* theme = service_->extensions()->begin()->get();
2494 EXPECT_EQ("name", theme->name());
2495 EXPECT_EQ("description", theme->description());
2496
2497 // Cleanup the "Cached Theme.pak" file. Ideally, this would be installed in a
2498 // temporary directory, but it automatically installs to the extension's
2499 // directory, and we don't want to copy the whole extension for a unittest.
2500 base::FilePath theme_file = extension_path.Append(chrome::kThemePackFilename);
2501 ASSERT_TRUE(base::PathExists(theme_file));
2502 ASSERT_TRUE(base::DeleteFile(theme_file, false)); // Not recursive.
2503 }
2504
2505 // Tests that we can change the ID of an unpacked extension by adding a key
2506 // to its manifest.
TEST_F(ExtensionServiceTest,UnpackedExtensionCanChangeID)2507 TEST_F(ExtensionServiceTest, UnpackedExtensionCanChangeID) {
2508 InitializeEmptyExtensionService();
2509
2510 base::ScopedTempDir temp;
2511 ASSERT_TRUE(temp.CreateUniqueTempDir());
2512
2513 base::FilePath extension_path = temp.path();
2514 base::FilePath manifest_path =
2515 extension_path.Append(extensions::kManifestFilename);
2516 base::FilePath manifest_no_key = data_dir_.
2517 AppendASCII("unpacked").
2518 AppendASCII("manifest_no_key.json");
2519
2520 base::FilePath manifest_with_key = data_dir_.
2521 AppendASCII("unpacked").
2522 AppendASCII("manifest_with_key.json");
2523
2524 ASSERT_TRUE(base::PathExists(manifest_no_key));
2525 ASSERT_TRUE(base::PathExists(manifest_with_key));
2526
2527 // Load the unpacked extension with no key.
2528 base::CopyFile(manifest_no_key, manifest_path);
2529 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2530
2531 base::RunLoop().RunUntilIdle();
2532 EXPECT_EQ(0u, GetErrors().size());
2533 ASSERT_EQ(1u, loaded_.size());
2534 EXPECT_EQ(1u, service_->extensions()->size());
2535
2536 // Add the key to the manifest.
2537 base::CopyFile(manifest_with_key, manifest_path);
2538 loaded_.clear();
2539
2540 // Reload the extensions.
2541 service_->ReloadExtensions();
2542 const Extension* extension = service_->GetExtensionById(unpacked, false);
2543 EXPECT_EQ(unpacked, extension->id());
2544 ASSERT_EQ(1u, loaded_.size());
2545
2546 // TODO(jstritar): Right now this just makes sure we don't crash and burn, but
2547 // we should also test that preferences are preserved.
2548 }
2549
2550 #if defined(OS_POSIX)
TEST_F(ExtensionServiceTest,UnpackedExtensionMayContainSymlinkedFiles)2551 TEST_F(ExtensionServiceTest, UnpackedExtensionMayContainSymlinkedFiles) {
2552 base::FilePath source_data_dir = data_dir_.
2553 AppendASCII("unpacked").
2554 AppendASCII("symlinks_allowed");
2555
2556 // Paths to test data files.
2557 base::FilePath source_manifest = source_data_dir.AppendASCII("manifest.json");
2558 ASSERT_TRUE(base::PathExists(source_manifest));
2559 base::FilePath source_icon = source_data_dir.AppendASCII("icon.png");
2560 ASSERT_TRUE(base::PathExists(source_icon));
2561
2562 // Set up the temporary extension directory.
2563 base::ScopedTempDir temp;
2564 ASSERT_TRUE(temp.CreateUniqueTempDir());
2565 base::FilePath extension_path = temp.path();
2566 base::FilePath manifest = extension_path.Append(
2567 extensions::kManifestFilename);
2568 base::FilePath icon_symlink = extension_path.AppendASCII("icon.png");
2569 base::CopyFile(source_manifest, manifest);
2570 base::CreateSymbolicLink(source_icon, icon_symlink);
2571
2572 // Load extension.
2573 InitializeEmptyExtensionService();
2574 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2575 base::RunLoop().RunUntilIdle();
2576
2577 EXPECT_TRUE(GetErrors().empty());
2578 ASSERT_EQ(1u, loaded_.size());
2579 EXPECT_EQ(1u, service_->extensions()->size());
2580 }
2581 #endif
2582
TEST_F(ExtensionServiceTest,UnpackedExtensionMayNotHaveUnderscore)2583 TEST_F(ExtensionServiceTest, UnpackedExtensionMayNotHaveUnderscore) {
2584 InitializeEmptyExtensionService();
2585 base::FilePath extension_path = data_dir_
2586 .AppendASCII("underscore_name");
2587 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
2588 base::RunLoop().RunUntilIdle();
2589 EXPECT_EQ(1u, GetErrors().size());
2590 EXPECT_EQ(0u, service_->extensions()->size());
2591 }
2592
TEST_F(ExtensionServiceTest,InstallLocalizedTheme)2593 TEST_F(ExtensionServiceTest, InstallLocalizedTheme) {
2594 InitializeEmptyExtensionService();
2595 service_->Init();
2596
2597 base::FilePath theme_path = data_dir_
2598 .AppendASCII("theme_i18n");
2599
2600 const Extension* theme = PackAndInstallCRX(theme_path, INSTALL_NEW);
2601
2602 EXPECT_EQ(0u, GetErrors().size());
2603 EXPECT_EQ(1u, service_->extensions()->size());
2604 EXPECT_EQ("name", theme->name());
2605 EXPECT_EQ("description", theme->description());
2606 }
2607
TEST_F(ExtensionServiceTest,InstallApps)2608 TEST_F(ExtensionServiceTest, InstallApps) {
2609 InitializeEmptyExtensionService();
2610
2611 // An empty app.
2612 const Extension* app = PackAndInstallCRX(data_dir_.AppendASCII("app1"),
2613 INSTALL_NEW);
2614 int pref_count = 0;
2615 ValidatePrefKeyCount(++pref_count);
2616 ASSERT_EQ(1u, service_->extensions()->size());
2617 ValidateIntegerPref(app->id(), "state", Extension::ENABLED);
2618 ValidateIntegerPref(app->id(), "location", Manifest::INTERNAL);
2619
2620 // Another app with non-overlapping extent. Should succeed.
2621 PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
2622 ValidatePrefKeyCount(++pref_count);
2623
2624 // A third app whose extent overlaps the first. Should fail.
2625 PackAndInstallCRX(data_dir_.AppendASCII("app3"), INSTALL_FAILED);
2626 ValidatePrefKeyCount(pref_count);
2627 }
2628
2629 // Tests that file access is OFF by default.
TEST_F(ExtensionServiceTest,DefaultFileAccess)2630 TEST_F(ExtensionServiceTest, DefaultFileAccess) {
2631 InitializeEmptyExtensionService();
2632 const Extension* extension =
2633 PackAndInstallCRX(data_dir_
2634 .AppendASCII("permissions")
2635 .AppendASCII("files"),
2636 INSTALL_NEW);
2637 EXPECT_EQ(0u, GetErrors().size());
2638 EXPECT_EQ(1u, service_->extensions()->size());
2639 EXPECT_FALSE(service_->extension_prefs()->AllowFileAccess(extension->id()));
2640 }
2641
TEST_F(ExtensionServiceTest,UpdateApps)2642 TEST_F(ExtensionServiceTest, UpdateApps) {
2643 InitializeEmptyExtensionService();
2644 base::FilePath extensions_path = data_dir_.AppendASCII("app_update");
2645
2646 // First install v1 of a hosted app.
2647 const Extension* extension =
2648 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2649 ASSERT_EQ(1u, service_->extensions()->size());
2650 std::string id = extension->id();
2651 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2652
2653 // Now try updating to v2.
2654 UpdateExtension(id,
2655 extensions_path.AppendASCII("v2.crx"),
2656 ENABLED);
2657 ASSERT_EQ(std::string("2"),
2658 service_->GetExtensionById(id, false)->version()->GetString());
2659 }
2660
2661 // Verifies that the NTP page and launch ordinals are kept when updating apps.
TEST_F(ExtensionServiceTest,UpdateAppsRetainOrdinals)2662 TEST_F(ExtensionServiceTest, UpdateAppsRetainOrdinals) {
2663 InitializeEmptyExtensionService();
2664 AppSorting* sorting = service_->extension_prefs()->app_sorting();
2665 base::FilePath extensions_path = data_dir_.AppendASCII("app_update");
2666
2667 // First install v1 of a hosted app.
2668 const Extension* extension =
2669 InstallCRX(extensions_path.AppendASCII("v1.crx"), INSTALL_NEW);
2670 ASSERT_EQ(1u, service_->extensions()->size());
2671 std::string id = extension->id();
2672 ASSERT_EQ(std::string("1"), extension->version()->GetString());
2673
2674 // Modify the ordinals so we can distinguish them from the defaults.
2675 syncer::StringOrdinal new_page_ordinal =
2676 sorting->GetPageOrdinal(id).CreateAfter();
2677 syncer::StringOrdinal new_launch_ordinal =
2678 sorting->GetAppLaunchOrdinal(id).CreateBefore();
2679
2680 sorting->SetPageOrdinal(id, new_page_ordinal);
2681 sorting->SetAppLaunchOrdinal(id, new_launch_ordinal);
2682
2683 // Now try updating to v2.
2684 UpdateExtension(id, extensions_path.AppendASCII("v2.crx"), ENABLED);
2685 ASSERT_EQ(std::string("2"),
2686 service_->GetExtensionById(id, false)->version()->GetString());
2687
2688 // Verify that the ordinals match.
2689 ASSERT_TRUE(new_page_ordinal.Equals(sorting->GetPageOrdinal(id)));
2690 ASSERT_TRUE(new_launch_ordinal.Equals(sorting->GetAppLaunchOrdinal(id)));
2691 }
2692
2693 // Ensures that the CWS has properly initialized ordinals.
TEST_F(ExtensionServiceTest,EnsureCWSOrdinalsInitialized)2694 TEST_F(ExtensionServiceTest, EnsureCWSOrdinalsInitialized) {
2695 InitializeEmptyExtensionService();
2696 service_->component_loader()->Add(
2697 IDR_WEBSTORE_MANIFEST, base::FilePath(FILE_PATH_LITERAL("web_store")));
2698 service_->Init();
2699
2700 AppSorting* sorting = service_->extension_prefs()->app_sorting();
2701 EXPECT_TRUE(
2702 sorting->GetPageOrdinal(extension_misc::kWebStoreAppId).IsValid());
2703 EXPECT_TRUE(
2704 sorting->GetAppLaunchOrdinal(extension_misc::kWebStoreAppId).IsValid());
2705 }
2706
TEST_F(ExtensionServiceTest,InstallAppsWithUnlimitedStorage)2707 TEST_F(ExtensionServiceTest, InstallAppsWithUnlimitedStorage) {
2708 InitializeEmptyExtensionService();
2709 EXPECT_TRUE(service_->extensions()->is_empty());
2710
2711 int pref_count = 0;
2712
2713 // Install app1 with unlimited storage.
2714 const Extension* extension =
2715 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
2716 ValidatePrefKeyCount(++pref_count);
2717 ASSERT_EQ(1u, service_->extensions()->size());
2718 const std::string id1 = extension->id();
2719 EXPECT_TRUE(extension->HasAPIPermission(
2720 APIPermission::kUnlimitedStorage));
2721 EXPECT_TRUE(extension->web_extent().MatchesURL(
2722 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2723 const GURL origin1(
2724 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2725 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2726 IsStorageUnlimited(origin1));
2727
2728 // Install app2 from the same origin with unlimited storage.
2729 extension = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
2730 ValidatePrefKeyCount(++pref_count);
2731 ASSERT_EQ(2u, service_->extensions()->size());
2732 const std::string id2 = extension->id();
2733 EXPECT_TRUE(extension->HasAPIPermission(
2734 APIPermission::kUnlimitedStorage));
2735 EXPECT_TRUE(extension->web_extent().MatchesURL(
2736 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
2737 const GURL origin2(
2738 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2739 EXPECT_EQ(origin1, origin2);
2740 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2741 IsStorageUnlimited(origin2));
2742
2743
2744 // Uninstall one of them, unlimited storage should still be granted
2745 // to the origin.
2746 UninstallExtension(id1, false);
2747 EXPECT_EQ(1u, service_->extensions()->size());
2748 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2749 IsStorageUnlimited(origin1));
2750
2751 // Uninstall the other, unlimited storage should be revoked.
2752 UninstallExtension(id2, false);
2753 EXPECT_EQ(0u, service_->extensions()->size());
2754 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2755 IsStorageUnlimited(origin2));
2756 }
2757
TEST_F(ExtensionServiceTest,InstallAppsAndCheckStorageProtection)2758 TEST_F(ExtensionServiceTest, InstallAppsAndCheckStorageProtection) {
2759 InitializeEmptyExtensionService();
2760 EXPECT_TRUE(service_->extensions()->is_empty());
2761
2762 int pref_count = 0;
2763
2764 const Extension* extension =
2765 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
2766 ValidatePrefKeyCount(++pref_count);
2767 ASSERT_EQ(1u, service_->extensions()->size());
2768 EXPECT_TRUE(extension->is_app());
2769 const std::string id1 = extension->id();
2770 const GURL origin1(
2771 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2772 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2773 IsStorageProtected(origin1));
2774
2775 // App 4 has a different origin (maps.google.com).
2776 extension = PackAndInstallCRX(data_dir_.AppendASCII("app4"), INSTALL_NEW);
2777 ValidatePrefKeyCount(++pref_count);
2778 ASSERT_EQ(2u, service_->extensions()->size());
2779 const std::string id2 = extension->id();
2780 const GURL origin2(
2781 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
2782 ASSERT_NE(origin1, origin2);
2783 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
2784 IsStorageProtected(origin2));
2785
2786 UninstallExtension(id1, false);
2787 EXPECT_EQ(1u, service_->extensions()->size());
2788
2789 UninstallExtension(id2, false);
2790
2791 EXPECT_TRUE(service_->extensions()->is_empty());
2792 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2793 IsStorageProtected(origin1));
2794 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
2795 IsStorageProtected(origin2));
2796 }
2797
2798 // Test that when an extension version is reinstalled, nothing happens.
TEST_F(ExtensionServiceTest,Reinstall)2799 TEST_F(ExtensionServiceTest, Reinstall) {
2800 InitializeEmptyExtensionService();
2801
2802 // A simple extension that should install without error.
2803 base::FilePath path = data_dir_.AppendASCII("good.crx");
2804 InstallCRX(path, INSTALL_NEW);
2805
2806 ValidatePrefKeyCount(1);
2807 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2808 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2809
2810 // Reinstall the same version, it should overwrite the previous one.
2811 InstallCRX(path, INSTALL_UPDATED);
2812
2813 ValidatePrefKeyCount(1);
2814 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
2815 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
2816 }
2817
2818 // Test that we can determine if extensions came from the
2819 // Chrome web store.
TEST_F(ExtensionServiceTest,FromWebStore)2820 TEST_F(ExtensionServiceTest, FromWebStore) {
2821 InitializeEmptyExtensionService();
2822
2823 // A simple extension that should install without error.
2824 base::FilePath path = data_dir_.AppendASCII("good.crx");
2825 // Not from web store.
2826 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2827 std::string id = extension->id();
2828
2829 ValidatePrefKeyCount(1);
2830 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", false));
2831 ASSERT_FALSE(extension->from_webstore());
2832
2833 // Test install from web store.
2834 InstallCRXFromWebStore(path, INSTALL_UPDATED); // From web store.
2835
2836 ValidatePrefKeyCount(1);
2837 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2838
2839 // Reload so extension gets reinitialized with new value.
2840 service_->ReloadExtensions();
2841 extension = service_->GetExtensionById(id, false);
2842 ASSERT_TRUE(extension->from_webstore());
2843
2844 // Upgrade to version 2.0
2845 path = data_dir_.AppendASCII("good2.crx");
2846 UpdateExtension(good_crx, path, ENABLED);
2847 ValidatePrefKeyCount(1);
2848 ASSERT_TRUE(ValidateBooleanPref(good_crx, "from_webstore", true));
2849 }
2850
2851 // Test upgrading a signed extension.
TEST_F(ExtensionServiceTest,UpgradeSignedGood)2852 TEST_F(ExtensionServiceTest, UpgradeSignedGood) {
2853 InitializeEmptyExtensionService();
2854
2855 base::FilePath path = data_dir_.AppendASCII("good.crx");
2856 const Extension* extension = InstallCRX(path, INSTALL_NEW);
2857 std::string id = extension->id();
2858
2859 ASSERT_EQ("1.0.0.0", extension->version()->GetString());
2860 ASSERT_EQ(0u, GetErrors().size());
2861
2862 // Upgrade to version 1.0.0.1.
2863 // Also test that the extension's old and new title are correctly retrieved.
2864 path = data_dir_.AppendASCII("good2.crx");
2865 InstallCRX(path, INSTALL_UPDATED, Extension::NO_FLAGS, "My extension 1");
2866 extension = service_->GetExtensionById(id, false);
2867
2868 ASSERT_EQ("1.0.0.1", extension->version()->GetString());
2869 ASSERT_EQ("My updated extension 1", extension->name());
2870 ASSERT_EQ(0u, GetErrors().size());
2871 }
2872
2873 // Test upgrading a signed extension with a bad signature.
TEST_F(ExtensionServiceTest,UpgradeSignedBad)2874 TEST_F(ExtensionServiceTest, UpgradeSignedBad) {
2875 InitializeEmptyExtensionService();
2876
2877 base::FilePath path = data_dir_.AppendASCII("good.crx");
2878 InstallCRX(path, INSTALL_NEW);
2879
2880 // Try upgrading with a bad signature. This should fail during the unpack,
2881 // because the key will not match the signature.
2882 path = data_dir_.AppendASCII("bad_signature.crx");
2883 InstallCRX(path, INSTALL_FAILED);
2884 }
2885
2886 // Test a normal update via the UpdateExtension API
TEST_F(ExtensionServiceTest,UpdateExtension)2887 TEST_F(ExtensionServiceTest, UpdateExtension) {
2888 InitializeEmptyExtensionService();
2889
2890 base::FilePath path = data_dir_.AppendASCII("good.crx");
2891
2892 const Extension* good = InstallCRX(path, INSTALL_NEW);
2893 ASSERT_EQ("1.0.0.0", good->VersionString());
2894 ASSERT_EQ(good_crx, good->id());
2895
2896 path = data_dir_.AppendASCII("good2.crx");
2897 UpdateExtension(good_crx, path, ENABLED);
2898 ASSERT_EQ("1.0.0.1",
2899 service_->GetExtensionById(good_crx, false)->
2900 version()->GetString());
2901 }
2902
2903 // Extensions should not be updated during browser shutdown.
TEST_F(ExtensionServiceTest,UpdateExtensionDuringShutdown)2904 TEST_F(ExtensionServiceTest, UpdateExtensionDuringShutdown) {
2905 InitializeEmptyExtensionService();
2906
2907 // Install an extension.
2908 base::FilePath path = data_dir_.AppendASCII("good.crx");
2909 const Extension* good = InstallCRX(path, INSTALL_NEW);
2910 ASSERT_EQ(good_crx, good->id());
2911
2912 // Simulate shutdown.
2913 service_->set_browser_terminating_for_test(true);
2914
2915 // Update should fail and extension should not be updated.
2916 path = data_dir_.AppendASCII("good2.crx");
2917 bool updated = service_->UpdateExtension(good_crx, path, GURL(), NULL);
2918 ASSERT_FALSE(updated);
2919 ASSERT_EQ("1.0.0.0",
2920 service_->GetExtensionById(good_crx, false)->
2921 version()->GetString());
2922 }
2923
2924 // Test updating a not-already-installed extension - this should fail
TEST_F(ExtensionServiceTest,UpdateNotInstalledExtension)2925 TEST_F(ExtensionServiceTest, UpdateNotInstalledExtension) {
2926 InitializeEmptyExtensionService();
2927
2928 base::FilePath path = data_dir_.AppendASCII("good.crx");
2929 UpdateExtension(good_crx, path, UPDATED);
2930 base::RunLoop().RunUntilIdle();
2931
2932 ASSERT_EQ(0u, service_->extensions()->size());
2933 ASSERT_FALSE(installed_);
2934 ASSERT_EQ(0u, loaded_.size());
2935 }
2936
2937 // Makes sure you can't downgrade an extension via UpdateExtension
TEST_F(ExtensionServiceTest,UpdateWillNotDowngrade)2938 TEST_F(ExtensionServiceTest, UpdateWillNotDowngrade) {
2939 InitializeEmptyExtensionService();
2940
2941 base::FilePath path = data_dir_.AppendASCII("good2.crx");
2942
2943 const Extension* good = InstallCRX(path, INSTALL_NEW);
2944 ASSERT_EQ("1.0.0.1", good->VersionString());
2945 ASSERT_EQ(good_crx, good->id());
2946
2947 // Change path from good2.crx -> good.crx
2948 path = data_dir_.AppendASCII("good.crx");
2949 UpdateExtension(good_crx, path, FAILED);
2950 ASSERT_EQ("1.0.0.1",
2951 service_->GetExtensionById(good_crx, false)->
2952 version()->GetString());
2953 }
2954
2955 // Make sure calling update with an identical version does nothing
TEST_F(ExtensionServiceTest,UpdateToSameVersionIsNoop)2956 TEST_F(ExtensionServiceTest, UpdateToSameVersionIsNoop) {
2957 InitializeEmptyExtensionService();
2958
2959 base::FilePath path = data_dir_.AppendASCII("good.crx");
2960
2961 const Extension* good = InstallCRX(path, INSTALL_NEW);
2962 ASSERT_EQ(good_crx, good->id());
2963 UpdateExtension(good_crx, path, FAILED_SILENTLY);
2964 }
2965
2966 // Tests that updating an extension does not clobber old state.
TEST_F(ExtensionServiceTest,UpdateExtensionPreservesState)2967 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesState) {
2968 InitializeEmptyExtensionService();
2969
2970 base::FilePath path = data_dir_.AppendASCII("good.crx");
2971
2972 const Extension* good = InstallCRX(path, INSTALL_NEW);
2973 ASSERT_EQ("1.0.0.0", good->VersionString());
2974 ASSERT_EQ(good_crx, good->id());
2975
2976 // Disable it and allow it to run in incognito. These settings should carry
2977 // over to the updated version.
2978 service_->DisableExtension(good->id(), Extension::DISABLE_USER_ACTION);
2979 extension_util::SetIsIncognitoEnabled(good->id(), service_, true);
2980 service_->extension_prefs()->SetDidExtensionEscalatePermissions(good, true);
2981
2982 path = data_dir_.AppendASCII("good2.crx");
2983 UpdateExtension(good_crx, path, INSTALLED);
2984 ASSERT_EQ(1u, service_->disabled_extensions()->size());\
2985 const Extension* good2 = service_->GetExtensionById(good_crx, true);
2986 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
2987 EXPECT_TRUE(extension_util::IsIncognitoEnabled(good2->id(), service_));
2988 EXPECT_TRUE(service_->extension_prefs()->DidExtensionEscalatePermissions(
2989 good2->id()));
2990 }
2991
2992 // Tests that updating preserves extension location.
TEST_F(ExtensionServiceTest,UpdateExtensionPreservesLocation)2993 TEST_F(ExtensionServiceTest, UpdateExtensionPreservesLocation) {
2994 InitializeEmptyExtensionService();
2995
2996 base::FilePath path = data_dir_.AppendASCII("good.crx");
2997
2998 const Extension* good =
2999 InstallCRXWithLocation(path, Manifest::EXTERNAL_PREF, INSTALL_NEW);
3000
3001 ASSERT_EQ("1.0.0.0", good->VersionString());
3002 ASSERT_EQ(good_crx, good->id());
3003
3004 path = data_dir_.AppendASCII("good2.crx");
3005 UpdateExtension(good_crx, path, ENABLED);
3006 const Extension* good2 = service_->GetExtensionById(good_crx, false);
3007 ASSERT_EQ("1.0.0.1", good2->version()->GetString());
3008 EXPECT_EQ(good2->location(), Manifest::EXTERNAL_PREF);
3009 }
3010
3011 // Makes sure that LOAD extension types can downgrade.
TEST_F(ExtensionServiceTest,LoadExtensionsCanDowngrade)3012 TEST_F(ExtensionServiceTest, LoadExtensionsCanDowngrade) {
3013 InitializeEmptyExtensionService();
3014
3015 base::ScopedTempDir temp;
3016 ASSERT_TRUE(temp.CreateUniqueTempDir());
3017
3018 // We'll write the extension manifest dynamically to a temporary path
3019 // to make it easier to change the version number.
3020 base::FilePath extension_path = temp.path();
3021 base::FilePath manifest_path =
3022 extension_path.Append(extensions::kManifestFilename);
3023 ASSERT_FALSE(base::PathExists(manifest_path));
3024
3025 // Start with version 2.0.
3026 DictionaryValue manifest;
3027 manifest.SetString("version", "2.0");
3028 manifest.SetString("name", "LOAD Downgrade Test");
3029 manifest.SetInteger("manifest_version", 2);
3030
3031 JSONFileValueSerializer serializer(manifest_path);
3032 ASSERT_TRUE(serializer.Serialize(manifest));
3033
3034 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
3035 base::RunLoop().RunUntilIdle();
3036
3037 EXPECT_EQ(0u, GetErrors().size());
3038 ASSERT_EQ(1u, loaded_.size());
3039 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
3040 EXPECT_EQ(1u, service_->extensions()->size());
3041 EXPECT_EQ("2.0", loaded_[0]->VersionString());
3042
3043 // Now set the version number to 1.0, reload the extensions and verify that
3044 // the downgrade was accepted.
3045 manifest.SetString("version", "1.0");
3046 ASSERT_TRUE(serializer.Serialize(manifest));
3047
3048 extensions::UnpackedInstaller::Create(service_)->Load(extension_path);
3049 base::RunLoop().RunUntilIdle();
3050
3051 EXPECT_EQ(0u, GetErrors().size());
3052 ASSERT_EQ(1u, loaded_.size());
3053 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
3054 EXPECT_EQ(1u, service_->extensions()->size());
3055 EXPECT_EQ("1.0", loaded_[0]->VersionString());
3056 }
3057
3058 #if !defined(OS_CHROMEOS)
3059 // LOAD extensions with plugins require approval.
TEST_F(ExtensionServiceTest,LoadExtensionsWithPlugins)3060 TEST_F(ExtensionServiceTest, LoadExtensionsWithPlugins) {
3061 base::FilePath extension_with_plugin_path = good1_path();
3062 base::FilePath extension_no_plugin_path = good2_path();
3063
3064 InitPluginService();
3065 InitializeEmptyExtensionService();
3066 InitializeProcessManager();
3067 service_->set_show_extensions_prompts(true);
3068
3069 // Start by canceling any install prompts.
3070 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
3071 switches::kAppsGalleryInstallAutoConfirmForTests,
3072 "cancel");
3073
3074 // The extension that has a plugin should not install.
3075 extensions::UnpackedInstaller::Create(service_)->Load(
3076 extension_with_plugin_path);
3077 base::RunLoop().RunUntilIdle();
3078 EXPECT_EQ(0u, GetErrors().size());
3079 EXPECT_EQ(0u, loaded_.size());
3080 EXPECT_EQ(0u, service_->extensions()->size());
3081 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3082
3083 // But the extension with no plugin should since there's no prompt.
3084 ExtensionErrorReporter::GetInstance()->ClearErrors();
3085 extensions::UnpackedInstaller::Create(service_)->Load(
3086 extension_no_plugin_path);
3087 base::RunLoop().RunUntilIdle();
3088 EXPECT_EQ(0u, GetErrors().size());
3089 EXPECT_EQ(1u, loaded_.size());
3090 EXPECT_EQ(1u, service_->extensions()->size());
3091 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3092 EXPECT_TRUE(service_->extensions()->Contains(good2));
3093
3094 // The plugin extension should install if we accept the dialog.
3095 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
3096 switches::kAppsGalleryInstallAutoConfirmForTests,
3097 "accept");
3098
3099 ExtensionErrorReporter::GetInstance()->ClearErrors();
3100 extensions::UnpackedInstaller::Create(service_)->Load(
3101 extension_with_plugin_path);
3102 base::RunLoop().RunUntilIdle();
3103 EXPECT_EQ(0u, GetErrors().size());
3104 EXPECT_EQ(2u, loaded_.size());
3105 EXPECT_EQ(2u, service_->extensions()->size());
3106 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3107 EXPECT_TRUE(service_->extensions()->Contains(good1));
3108 EXPECT_TRUE(service_->extensions()->Contains(good2));
3109
3110 // Make sure the granted permissions have been setup.
3111 scoped_refptr<PermissionSet> permissions(
3112 service_->extension_prefs()->GetGrantedPermissions(good1));
3113 EXPECT_FALSE(permissions->IsEmpty());
3114 EXPECT_TRUE(permissions->HasEffectiveFullAccess());
3115 EXPECT_FALSE(permissions->apis().empty());
3116 EXPECT_TRUE(permissions->HasAPIPermission(APIPermission::kPlugin));
3117
3118 // We should be able to reload the extension without getting another prompt.
3119 loaded_.clear();
3120 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
3121 switches::kAppsGalleryInstallAutoConfirmForTests,
3122 "cancel");
3123
3124 service_->ReloadExtension(good1);
3125 base::RunLoop().RunUntilIdle();
3126 EXPECT_EQ(1u, loaded_.size());
3127 EXPECT_EQ(2u, service_->extensions()->size());
3128 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3129 }
3130 #endif // !defined(OS_CHROMEOS)
3131
3132 namespace {
3133
IsExtension(const Extension * extension)3134 bool IsExtension(const Extension* extension) {
3135 return extension->GetType() == Manifest::TYPE_EXTENSION;
3136 }
3137
3138 } // namespace
3139
3140 // Test adding a pending extension.
TEST_F(ExtensionServiceTest,AddPendingExtensionFromSync)3141 TEST_F(ExtensionServiceTest, AddPendingExtensionFromSync) {
3142 InitializeEmptyExtensionService();
3143
3144 const std::string kFakeId(all_zero);
3145 const GURL kFakeUpdateURL("http:://fake.update/url");
3146 const bool kFakeInstallSilently(true);
3147
3148 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
3149 kFakeId, kFakeUpdateURL, &IsExtension,
3150 kFakeInstallSilently));
3151
3152 const extensions::PendingExtensionInfo* pending_extension_info;
3153 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
3154 GetById(kFakeId)));
3155 EXPECT_EQ(kFakeUpdateURL, pending_extension_info->update_url());
3156 EXPECT_EQ(&IsExtension, pending_extension_info->should_allow_install_);
3157 EXPECT_EQ(kFakeInstallSilently, pending_extension_info->install_silently());
3158 }
3159
3160 namespace {
3161 const char kGoodId[] = "ldnnhddmnhbkjipkidpdiheffobcpfmf";
3162 const char kGoodUpdateURL[] = "http://good.update/url";
3163 const bool kGoodIsFromSync = true;
3164 const bool kGoodInstallSilently = true;
3165 } // namespace
3166
3167 // Test updating a pending extension.
TEST_F(ExtensionServiceTest,UpdatePendingExtension)3168 TEST_F(ExtensionServiceTest, UpdatePendingExtension) {
3169 InitializeEmptyExtensionService();
3170 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
3171 kGoodId, GURL(kGoodUpdateURL), &IsExtension,
3172 kGoodInstallSilently));
3173 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3174
3175 base::FilePath path = data_dir_.AppendASCII("good.crx");
3176 UpdateExtension(kGoodId, path, ENABLED);
3177
3178 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3179
3180 const Extension* extension = service_->GetExtensionById(kGoodId, true);
3181 ASSERT_TRUE(extension);
3182 }
3183
3184 namespace {
3185
IsTheme(const Extension * extension)3186 bool IsTheme(const Extension* extension) {
3187 return extension->is_theme();
3188 }
3189
3190 } // namespace
3191
3192 // Test updating a pending theme.
3193 // Disabled due to ASAN failure. http://crbug.com/108320
TEST_F(ExtensionServiceTest,DISABLED_UpdatePendingTheme)3194 TEST_F(ExtensionServiceTest, DISABLED_UpdatePendingTheme) {
3195 InitializeEmptyExtensionService();
3196 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
3197 theme_crx, GURL(), &IsTheme, false));
3198 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3199
3200 base::FilePath path = data_dir_.AppendASCII("theme.crx");
3201 UpdateExtension(theme_crx, path, ENABLED);
3202
3203 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3204
3205 const Extension* extension = service_->GetExtensionById(theme_crx, true);
3206 ASSERT_TRUE(extension);
3207
3208 EXPECT_FALSE(
3209 service_->extension_prefs()->IsExtensionDisabled(extension->id()));
3210 EXPECT_TRUE(service_->IsExtensionEnabled(theme_crx));
3211 }
3212
3213 #if defined(OS_CHROMEOS)
3214 // Always fails on ChromeOS: http://crbug.com/79737
3215 #define MAYBE_UpdatePendingExternalCrx DISABLED_UpdatePendingExternalCrx
3216 #else
3217 #define MAYBE_UpdatePendingExternalCrx UpdatePendingExternalCrx
3218 #endif
3219 // Test updating a pending CRX as if the source is an external extension
3220 // with an update URL. In this case we don't know if the CRX is a theme
3221 // or not.
TEST_F(ExtensionServiceTest,MAYBE_UpdatePendingExternalCrx)3222 TEST_F(ExtensionServiceTest, MAYBE_UpdatePendingExternalCrx) {
3223 InitializeEmptyExtensionService();
3224 EXPECT_TRUE(service_->pending_extension_manager()->AddFromExternalUpdateUrl(
3225 theme_crx, GURL(), Manifest::EXTERNAL_PREF_DOWNLOAD, Extension::NO_FLAGS,
3226 false));
3227
3228 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3229
3230 base::FilePath path = data_dir_.AppendASCII("theme.crx");
3231 UpdateExtension(theme_crx, path, ENABLED);
3232
3233 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3234
3235 const Extension* extension = service_->GetExtensionById(theme_crx, true);
3236 ASSERT_TRUE(extension);
3237
3238 EXPECT_FALSE(
3239 service_->extension_prefs()->IsExtensionDisabled(extension->id()));
3240 EXPECT_TRUE(service_->IsExtensionEnabled(extension->id()));
3241 EXPECT_FALSE(extension_util::IsIncognitoEnabled(extension->id(), service_));
3242 }
3243
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.
TEST_F(ExtensionServiceTest,UpdatePendingExternalCrxWinsOverSync)3247 TEST_F(ExtensionServiceTest, UpdatePendingExternalCrxWinsOverSync) {
3248 InitializeEmptyExtensionService();
3249
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));
3254
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()->
3258 GetById(kGoodId)));
3259 EXPECT_TRUE(pending_extension_info->is_from_sync());
3260
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));
3265
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()->
3268 GetById(kGoodId)));
3269 EXPECT_FALSE(pending_extension_info->is_from_sync());
3270 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3271 pending_extension_info->install_source());
3272
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));
3277
3278 // Check that the external, non-sync update was not overridden.
3279 ASSERT_TRUE((pending_extension_info = service_->pending_extension_manager()->
3280 GetById(kGoodId)));
3281 EXPECT_FALSE(pending_extension_info->is_from_sync());
3282 EXPECT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD,
3283 pending_extension_info->install_source());
3284 }
3285
3286 // Updating a theme should fail if the updater is explicitly told that
3287 // the CRX is not a theme.
TEST_F(ExtensionServiceTest,UpdatePendingCrxThemeMismatch)3288 TEST_F(ExtensionServiceTest, UpdatePendingCrxThemeMismatch) {
3289 InitializeEmptyExtensionService();
3290 EXPECT_TRUE(service_->pending_extension_manager()->AddFromSync(
3291 theme_crx, GURL(), &IsExtension, true));
3292
3293 EXPECT_TRUE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3294
3295 base::FilePath path = data_dir_.AppendASCII("theme.crx");
3296 UpdateExtension(theme_crx, path, FAILED_SILENTLY);
3297
3298 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(theme_crx));
3299
3300 const Extension* extension = service_->GetExtensionById(theme_crx, true);
3301 ASSERT_FALSE(extension);
3302 }
3303
3304 // TODO(akalin): Test updating a pending extension non-silently once
3305 // we can mock out ExtensionInstallUI and inject our version into
3306 // UpdateExtension().
3307
3308 // Test updating a pending extension which fails the should-install test.
TEST_F(ExtensionServiceTest,UpdatePendingExtensionFailedShouldInstallTest)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));
3315
3316 base::FilePath path = data_dir_.AppendASCII("good.crx");
3317 UpdateExtension(kGoodId, path, UPDATED);
3318
3319 // TODO(akalin): Figure out how to check that the extensions
3320 // directory is cleaned up properly in OnExtensionInstalled().
3321
3322 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3323 }
3324
3325 // TODO(akalin): Figure out how to test that installs of pending
3326 // unsyncable extensions are blocked.
3327
3328 // Test updating a pending extension for one that is not pending.
TEST_F(ExtensionServiceTest,UpdatePendingExtensionNotPending)3329 TEST_F(ExtensionServiceTest, UpdatePendingExtensionNotPending) {
3330 InitializeEmptyExtensionService();
3331
3332 base::FilePath path = data_dir_.AppendASCII("good.crx");
3333 UpdateExtension(kGoodId, path, UPDATED);
3334
3335 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3336 }
3337
3338 // Test updating a pending extension for one that is already
3339 // installed.
TEST_F(ExtensionServiceTest,UpdatePendingExtensionAlreadyInstalled)3340 TEST_F(ExtensionServiceTest, UpdatePendingExtensionAlreadyInstalled) {
3341 InitializeEmptyExtensionService();
3342
3343 base::FilePath path = data_dir_.AppendASCII("good.crx");
3344 const Extension* good = InstallCRX(path, INSTALL_NEW);
3345 ASSERT_EQ(1u, service_->extensions()->size());
3346
3347 EXPECT_FALSE(good->is_theme());
3348
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);
3356
3357 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(kGoodId));
3358 }
3359
3360 #if defined(ENABLE_BLACKLIST_TESTS)
3361 // Tests blacklisting then unblacklisting extensions after the service has been
3362 // initialized.
TEST_F(ExtensionServiceTest,SetUnsetBlacklistInPrefs)3363 TEST_F(ExtensionServiceTest, SetUnsetBlacklistInPrefs) {
3364 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3365 new FakeSafeBrowsingDatabaseManager(true));
3366 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3367
3368 // A profile with 3 extensions installed: good0, good1, and good2.
3369 InitializeGoodInstalledExtensionService();
3370 service_->Init();
3371
3372 const ExtensionSet* extensions = service_->extensions();
3373 const ExtensionSet* blacklisted_extensions =
3374 service_->blacklisted_extensions();
3375
3376 EXPECT_TRUE( extensions->Contains(good0) &&
3377 !blacklisted_extensions->Contains(good0));
3378 EXPECT_TRUE( extensions->Contains(good1) &&
3379 !blacklisted_extensions->Contains(good1));
3380 EXPECT_TRUE( extensions->Contains(good2) &&
3381 !blacklisted_extensions->Contains(good2));
3382
3383 EXPECT_FALSE(IsPrefExist(good0, "blacklist"));
3384 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3385 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3386 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3387
3388 // Blacklist good0 and good1 (and an invalid extension ID).
3389 blacklist_db->SetUnsafe(good0, good1, "invalid_id").NotifyUpdate();
3390 base::RunLoop().RunUntilIdle();
3391
3392 EXPECT_TRUE(!extensions->Contains(good0) &&
3393 blacklisted_extensions->Contains(good0));
3394 EXPECT_TRUE(!extensions->Contains(good1) &&
3395 blacklisted_extensions->Contains(good1));
3396 EXPECT_TRUE( extensions->Contains(good2) &&
3397 !blacklisted_extensions->Contains(good2));
3398
3399 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3400 EXPECT_TRUE(ValidateBooleanPref(good1, "blacklist", true));
3401 EXPECT_FALSE(IsPrefExist(good2, "blacklist"));
3402 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3403
3404 // Un-blacklist good1 and blacklist good2.
3405 blacklist_db->SetUnsafe(good0, good2, "invalid_id").NotifyUpdate();
3406 base::RunLoop().RunUntilIdle();
3407
3408 EXPECT_TRUE(!extensions->Contains(good0) &&
3409 blacklisted_extensions->Contains(good0));
3410 EXPECT_TRUE( extensions->Contains(good1) &&
3411 !blacklisted_extensions->Contains(good1));
3412 EXPECT_TRUE(!extensions->Contains(good2) &&
3413 blacklisted_extensions->Contains(good2));
3414
3415 EXPECT_TRUE(ValidateBooleanPref(good0, "blacklist", true));
3416 EXPECT_FALSE(IsPrefExist(good1, "blacklist"));
3417 EXPECT_TRUE(ValidateBooleanPref(good2, "blacklist", true));
3418 EXPECT_FALSE(IsPrefExist("invalid_id", "blacklist"));
3419 }
3420 #endif // defined(ENABLE_BLACKLIST_TESTS)
3421
3422 #if defined(ENABLE_BLACKLIST_TESTS)
3423 // Tests trying to install a blacklisted extension.
TEST_F(ExtensionServiceTest,BlacklistedExtensionWillNotInstall)3424 TEST_F(ExtensionServiceTest, BlacklistedExtensionWillNotInstall) {
3425 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3426 new FakeSafeBrowsingDatabaseManager(true));
3427 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3428
3429 InitializeEmptyExtensionService();
3430 service_->Init();
3431
3432 // After blacklisting good_crx, we cannot install it.
3433 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
3434 base::RunLoop().RunUntilIdle();
3435
3436 base::FilePath path = data_dir_.AppendASCII("good.crx");
3437 // HACK: specify WAS_INSTALLED_BY_DEFAULT so that test machinery doesn't
3438 // decide to install this silently. Somebody should fix these tests, all
3439 // 6,000 lines of them. Hah!
3440 InstallCRX(path, INSTALL_FAILED, Extension::WAS_INSTALLED_BY_DEFAULT);
3441 EXPECT_EQ(0u, service_->extensions()->size());
3442 }
3443 #endif // defined(ENABLE_BLACKLIST_TESTS)
3444
3445 #if defined(ENABLE_BLACKLIST_TESTS)
3446 // Unload blacklisted extension on policy change.
TEST_F(ExtensionServiceTest,UnloadBlacklistedExtensionPolicy)3447 TEST_F(ExtensionServiceTest, UnloadBlacklistedExtensionPolicy) {
3448 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3449 new FakeSafeBrowsingDatabaseManager(true));
3450 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3451
3452 // A profile with no extensions installed.
3453 InitializeEmptyExtensionService();
3454
3455 base::FilePath path = data_dir_.AppendASCII("good.crx");
3456
3457 const Extension* good = InstallCRX(path, INSTALL_NEW);
3458 EXPECT_EQ(good_crx, good->id());
3459 UpdateExtension(good_crx, path, FAILED_SILENTLY);
3460 EXPECT_EQ(1u, service_->extensions()->size());
3461
3462 base::ListValue whitelist;
3463 PrefService* prefs = service_->extension_prefs()->pref_service();
3464 whitelist.Append(new base::StringValue(good_crx));
3465 prefs->Set(prefs::kExtensionInstallAllowList, whitelist);
3466
3467 blacklist_db->SetUnsafe(good_crx).NotifyUpdate();
3468 base::RunLoop().RunUntilIdle();
3469
3470 // The good_crx is blacklisted and the whitelist doesn't negate it.
3471 ASSERT_TRUE(ValidateBooleanPref(good_crx, "blacklist", true));
3472 EXPECT_EQ(0u, service_->extensions()->size());
3473 }
3474 #endif // defined(ENABLE_BLACKLIST_TESTS)
3475
3476 #if defined(ENABLE_BLACKLIST_TESTS)
3477 // Tests that a blacklisted extension is eventually unloaded on startup, if it
3478 // wasn't already.
TEST_F(ExtensionServiceTest,WillNotLoadBlacklistedExtensionsFromDirectory)3479 TEST_F(ExtensionServiceTest, WillNotLoadBlacklistedExtensionsFromDirectory) {
3480 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3481 new FakeSafeBrowsingDatabaseManager(true));
3482 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3483
3484 // A profile with 3 extensions installed: good0, good1, and good2.
3485 InitializeGoodInstalledExtensionService();
3486
3487 // Blacklist good1 before the service initializes.
3488 blacklist_db->SetUnsafe(good1);
3489
3490 // Load extensions.
3491 service_->Init();
3492 ASSERT_EQ(3u, loaded_.size()); // hasn't had time to blacklist yet
3493
3494 base::RunLoop().RunUntilIdle();
3495 ASSERT_EQ(1u, service_->blacklisted_extensions()->size());
3496 ASSERT_EQ(2u, service_->extensions()->size());
3497
3498 ASSERT_TRUE(service_->extensions()->Contains(good0));
3499 ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good1));
3500 ASSERT_TRUE(service_->extensions()->Contains(good2));
3501 }
3502 #endif // defined(ENABLE_BLACKLIST_TESTS)
3503
3504 #if defined(ENABLE_BLACKLIST_TESTS)
3505 // Tests extensions blacklisted in prefs on startup; one still blacklisted by
3506 // safe browsing, the other not. The not-blacklisted one should recover.
TEST_F(ExtensionServiceTest,BlacklistedInPrefsFromStartup)3507 TEST_F(ExtensionServiceTest, BlacklistedInPrefsFromStartup) {
3508 scoped_refptr<FakeSafeBrowsingDatabaseManager> blacklist_db(
3509 new FakeSafeBrowsingDatabaseManager(true));
3510 Blacklist::ScopedDatabaseManagerForTest scoped_blacklist_db(blacklist_db);
3511
3512 InitializeGoodInstalledExtensionService();
3513 service_->extension_prefs()->SetExtensionBlacklisted(good0, true);
3514 service_->extension_prefs()->SetExtensionBlacklisted(good1, true);
3515
3516 blacklist_db->SetUnsafe(good1);
3517
3518 service_->Init();
3519
3520 ASSERT_EQ(2u, service_->blacklisted_extensions()->size());
3521 ASSERT_EQ(1u, service_->extensions()->size());
3522
3523 ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good0));
3524 ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good1));
3525 ASSERT_TRUE(service_->extensions()->Contains(good2));
3526
3527 // Give time for the blacklist to update.
3528 base::RunLoop().RunUntilIdle();
3529
3530 ASSERT_EQ(1u, service_->blacklisted_extensions()->size());
3531 ASSERT_EQ(2u, service_->extensions()->size());
3532
3533 ASSERT_TRUE(service_->extensions()->Contains(good0));
3534 ASSERT_TRUE(service_->blacklisted_extensions()->Contains(good1));
3535 ASSERT_TRUE(service_->extensions()->Contains(good2));
3536 }
3537 #endif // defined(ENABLE_BLACKLIST_TESTS)
3538
3539 // Will not install extension blacklisted by policy.
TEST_F(ExtensionServiceTest,BlacklistedByPolicyWillNotInstall)3540 TEST_F(ExtensionServiceTest, BlacklistedByPolicyWillNotInstall) {
3541 InitializeEmptyExtensionService();
3542
3543 // Blacklist everything.
3544 {
3545 ListPrefUpdate update(profile_->GetPrefs(),
3546 prefs::kExtensionInstallDenyList);
3547 ListValue* blacklist = update.Get();
3548 blacklist->Append(new base::StringValue("*"));
3549 }
3550
3551 // Blacklist prevents us from installing good_crx.
3552 base::FilePath path = data_dir_.AppendASCII("good.crx");
3553 InstallCRX(path, INSTALL_FAILED);
3554 EXPECT_EQ(0u, service_->extensions()->size());
3555
3556 // Now whitelist this particular extension.
3557 {
3558 ListPrefUpdate update(profile_->GetPrefs(),
3559 prefs::kExtensionInstallAllowList);
3560 ListValue* whitelist = update.Get();
3561 whitelist->Append(new base::StringValue(good_crx));
3562 }
3563
3564 // Ensure we can now install good_crx.
3565 InstallCRX(path, INSTALL_NEW);
3566 EXPECT_EQ(1u, service_->extensions()->size());
3567 }
3568
3569 // Extension blacklisted by policy get unloaded after installing.
TEST_F(ExtensionServiceTest,BlacklistedByPolicyRemovedIfRunning)3570 TEST_F(ExtensionServiceTest, BlacklistedByPolicyRemovedIfRunning) {
3571 InitializeEmptyExtensionService();
3572
3573 // Install good_crx.
3574 base::FilePath path = data_dir_.AppendASCII("good.crx");
3575 InstallCRX(path, INSTALL_NEW);
3576 EXPECT_EQ(1u, service_->extensions()->size());
3577
3578 { // Scope for pref update notification.
3579 PrefService* prefs = profile_->GetPrefs();
3580 ListPrefUpdate update(prefs, prefs::kExtensionInstallDenyList);
3581 ListValue* blacklist = update.Get();
3582 ASSERT_TRUE(blacklist != NULL);
3583
3584 // Blacklist this extension.
3585 blacklist->Append(new base::StringValue(good_crx));
3586 }
3587
3588 // Extension should not be running now.
3589 base::RunLoop().RunUntilIdle();
3590 EXPECT_EQ(0u, service_->extensions()->size());
3591 }
3592
3593 // Tests that component extensions are not blacklisted by policy.
TEST_F(ExtensionServiceTest,ComponentExtensionWhitelisted)3594 TEST_F(ExtensionServiceTest, ComponentExtensionWhitelisted) {
3595 InitializeEmptyExtensionService();
3596
3597 // Blacklist everything.
3598 {
3599 ListPrefUpdate update(profile_->GetPrefs(),
3600 prefs::kExtensionInstallDenyList);
3601 ListValue* blacklist = update.Get();
3602 blacklist->Append(new base::StringValue("*"));
3603 }
3604
3605 // Install a component extension.
3606 base::FilePath path = data_dir_
3607 .AppendASCII("good")
3608 .AppendASCII("Extensions")
3609 .AppendASCII(good0)
3610 .AppendASCII("1.0.0.0");
3611 std::string manifest;
3612 ASSERT_TRUE(base::ReadFileToString(
3613 path.Append(extensions::kManifestFilename), &manifest));
3614 service_->component_loader()->Add(manifest, path);
3615 service_->Init();
3616
3617 // Extension should be installed despite blacklist.
3618 ASSERT_EQ(1u, service_->extensions()->size());
3619 EXPECT_TRUE(service_->GetExtensionById(good0, false));
3620
3621 // Poke external providers and make sure the extension is still present.
3622 service_->CheckForExternalUpdates();
3623 ASSERT_EQ(1u, service_->extensions()->size());
3624 EXPECT_TRUE(service_->GetExtensionById(good0, false));
3625
3626 // Extension should not be uninstalled on blacklist changes.
3627 {
3628 ListPrefUpdate update(profile_->GetPrefs(),
3629 prefs::kExtensionInstallDenyList);
3630 ListValue* blacklist = update.Get();
3631 blacklist->Append(new base::StringValue(good0));
3632 }
3633 base::RunLoop().RunUntilIdle();
3634 ASSERT_EQ(1u, service_->extensions()->size());
3635 EXPECT_TRUE(service_->GetExtensionById(good0, false));
3636 }
3637
3638 // Tests that policy-installed extensions are not blacklisted by policy.
TEST_F(ExtensionServiceTest,PolicyInstalledExtensionsWhitelisted)3639 TEST_F(ExtensionServiceTest, PolicyInstalledExtensionsWhitelisted) {
3640 InitializeEmptyExtensionService();
3641
3642 {
3643 // Blacklist everything.
3644 ListPrefUpdate blacklist_update(profile_->GetPrefs(),
3645 prefs::kExtensionInstallDenyList);
3646 ListValue* blacklist = blacklist_update.Get();
3647 blacklist->AppendString("*");
3648
3649 // Mark good.crx for force-installation.
3650 DictionaryPrefUpdate forcelist_update(profile_->GetPrefs(),
3651 prefs::kExtensionInstallForceList);
3652 extensions::ExternalPolicyLoader::AddExtension(
3653 forcelist_update.Get(), good_crx, "http://example.com/update_url");
3654 }
3655
3656 // Have policy force-install an extension.
3657 MockExtensionProvider* provider =
3658 new MockExtensionProvider(service_,
3659 Manifest::EXTERNAL_POLICY_DOWNLOAD);
3660 AddMockExternalProvider(provider);
3661 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
3662 data_dir_.AppendASCII("good.crx"));
3663
3664 // Reloading extensions should find our externally registered extension
3665 // and install it.
3666 content::WindowedNotificationObserver observer(
3667 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
3668 content::NotificationService::AllSources());
3669 service_->CheckForExternalUpdates();
3670 observer.Wait();
3671
3672 // Extension should be installed despite blacklist.
3673 ASSERT_EQ(1u, service_->extensions()->size());
3674 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3675
3676 // Blacklist update should not uninstall the extension.
3677 {
3678 ListPrefUpdate update(profile_->GetPrefs(),
3679 prefs::kExtensionInstallDenyList);
3680 ListValue* blacklist = update.Get();
3681 blacklist->Append(new base::StringValue(good0));
3682 }
3683 base::RunLoop().RunUntilIdle();
3684 ASSERT_EQ(1u, service_->extensions()->size());
3685 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3686 }
3687
3688 // Tests that extensions cannot be installed if the policy provider prohibits
3689 // it. This functionality is implemented in CrxInstaller::ConfirmInstall().
TEST_F(ExtensionServiceTest,ManagementPolicyProhibitsInstall)3690 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsInstall) {
3691 InitializeEmptyExtensionService();
3692
3693 management_policy_->UnregisterAllProviders();
3694 extensions::TestManagementPolicyProvider provider_(
3695 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3696 management_policy_->RegisterProvider(&provider_);
3697
3698 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_FAILED);
3699 EXPECT_EQ(0u, service_->extensions()->size());
3700 }
3701
3702 // Tests that extensions cannot be loaded from prefs if the policy provider
3703 // prohibits it. This functionality is implemented in InstalledLoader::Load().
TEST_F(ExtensionServiceTest,ManagementPolicyProhibitsLoadFromPrefs)3704 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsLoadFromPrefs) {
3705 InitializeEmptyExtensionService();
3706
3707 // Create a fake extension to be loaded as though it were read from prefs.
3708 base::FilePath path = data_dir_.AppendASCII("management")
3709 .AppendASCII("simple_extension");
3710 DictionaryValue manifest;
3711 manifest.SetString(keys::kName, "simple_extension");
3712 manifest.SetString(keys::kVersion, "1");
3713 // UNPACKED is for extensions loaded from a directory. We use it here, even
3714 // though we're testing loading from prefs, so that we don't need to provide
3715 // an extension key.
3716 extensions::ExtensionInfo extension_info(
3717 &manifest, std::string(), path, Manifest::UNPACKED);
3718
3719 // Ensure we can load it with no management policy in place.
3720 management_policy_->UnregisterAllProviders();
3721 EXPECT_EQ(0u, service_->extensions()->size());
3722 extensions::InstalledLoader(service_).Load(extension_info, false);
3723 EXPECT_EQ(1u, service_->extensions()->size());
3724
3725 const Extension* extension = (service_->extensions()->begin())->get();
3726 EXPECT_TRUE(service_->UninstallExtension(extension->id(), false, NULL));
3727 EXPECT_EQ(0u, service_->extensions()->size());
3728
3729 // Ensure we cannot load it if management policy prohibits installation.
3730 extensions::TestManagementPolicyProvider provider_(
3731 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3732 management_policy_->RegisterProvider(&provider_);
3733
3734 extensions::InstalledLoader(service_).Load(extension_info, false);
3735 EXPECT_EQ(0u, service_->extensions()->size());
3736 }
3737
3738 // Tests disabling an extension when prohibited by the ManagementPolicy.
TEST_F(ExtensionServiceTest,ManagementPolicyProhibitsDisable)3739 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsDisable) {
3740 InitializeEmptyExtensionService();
3741
3742 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3743 EXPECT_EQ(1u, service_->extensions()->size());
3744 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3745
3746 management_policy_->UnregisterAllProviders();
3747 extensions::TestManagementPolicyProvider provider(
3748 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3749 management_policy_->RegisterProvider(&provider);
3750
3751 // Attempt to disable it.
3752 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3753
3754 EXPECT_EQ(1u, service_->extensions()->size());
3755 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3756 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3757 }
3758
3759 // Tests uninstalling an extension when prohibited by the ManagementPolicy.
TEST_F(ExtensionServiceTest,ManagementPolicyProhibitsUninstall)3760 TEST_F(ExtensionServiceTest, ManagementPolicyProhibitsUninstall) {
3761 InitializeEmptyExtensionService();
3762
3763 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3764 EXPECT_EQ(1u, service_->extensions()->size());
3765 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3766
3767 management_policy_->UnregisterAllProviders();
3768 extensions::TestManagementPolicyProvider provider(
3769 extensions::TestManagementPolicyProvider::PROHIBIT_MODIFY_STATUS);
3770 management_policy_->RegisterProvider(&provider);
3771
3772 // Attempt to uninstall it.
3773 EXPECT_FALSE(service_->UninstallExtension(good_crx, false, NULL));
3774
3775 EXPECT_EQ(1u, service_->extensions()->size());
3776 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3777 }
3778
3779 // Tests that previously installed extensions that are now prohibited from
3780 // being installed are removed.
TEST_F(ExtensionServiceTest,ManagementPolicyUnloadsAllProhibited)3781 TEST_F(ExtensionServiceTest, ManagementPolicyUnloadsAllProhibited) {
3782 InitializeEmptyExtensionService();
3783
3784 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3785 InstallCRX(data_dir_.AppendASCII("page_action.crx"), INSTALL_NEW);
3786 EXPECT_EQ(2u, service_->extensions()->size());
3787 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3788
3789 management_policy_->UnregisterAllProviders();
3790 extensions::TestManagementPolicyProvider provider(
3791 extensions::TestManagementPolicyProvider::PROHIBIT_LOAD);
3792 management_policy_->RegisterProvider(&provider);
3793
3794 // Run the policy check.
3795 service_->CheckManagementPolicy();
3796 EXPECT_EQ(0u, service_->extensions()->size());
3797 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3798 }
3799
3800 // Tests that previously disabled extensions that are now required to be
3801 // enabled are re-enabled on reinstall.
TEST_F(ExtensionServiceTest,ManagementPolicyRequiresEnable)3802 TEST_F(ExtensionServiceTest, ManagementPolicyRequiresEnable) {
3803 InitializeEmptyExtensionService();
3804
3805 // Install, then disable, an extension.
3806 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3807 EXPECT_EQ(1u, service_->extensions()->size());
3808 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3809 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3810
3811 // Register an ExtensionMnagementPolicy that requires the extension to remain
3812 // enabled.
3813 management_policy_->UnregisterAllProviders();
3814 extensions::TestManagementPolicyProvider provider(
3815 extensions::TestManagementPolicyProvider::MUST_REMAIN_ENABLED);
3816 management_policy_->RegisterProvider(&provider);
3817
3818 // Reinstall the extension.
3819 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_UPDATED);
3820 EXPECT_EQ(1u, service_->extensions()->size());
3821 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3822 }
3823
3824 // Flaky on windows; http://crbug.com/309833
3825 #if defined(OS_WIN)
3826 #define MAYBE_ExternalExtensionAutoAcknowledgement DISABLED_ExternalExtensionAutoAcknowledgement
3827 #else
3828 #define MAYBE_ExternalExtensionAutoAcknowledgement ExternalExtensionAutoAcknowledgement
3829 #endif
TEST_F(ExtensionServiceTest,ExternalExtensionAutoAcknowledgement)3830 TEST_F(ExtensionServiceTest, ExternalExtensionAutoAcknowledgement) {
3831 InitializeEmptyExtensionService();
3832 set_extensions_enabled(true);
3833
3834 {
3835 // Register and install an external extension.
3836 MockExtensionProvider* provider =
3837 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
3838 AddMockExternalProvider(provider);
3839 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
3840 data_dir_.AppendASCII("good.crx"));
3841 }
3842 {
3843 // Have policy force-install an extension.
3844 MockExtensionProvider* provider =
3845 new MockExtensionProvider(service_,
3846 Manifest::EXTERNAL_POLICY_DOWNLOAD);
3847 AddMockExternalProvider(provider);
3848 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
3849 data_dir_.AppendASCII("page_action.crx"));
3850 }
3851
3852 // Providers are set up. Let them run.
3853 int count = 2;
3854 content::WindowedNotificationObserver observer(
3855 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
3856 base::Bind(&WaitForCountNotificationsCallback, &count));
3857 service_->CheckForExternalUpdates();
3858
3859 observer.Wait();
3860
3861 ASSERT_EQ(2u, service_->extensions()->size());
3862 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3863 EXPECT_TRUE(service_->GetExtensionById(page_action, false));
3864 ExtensionPrefs* prefs = service_->extension_prefs();
3865 ASSERT_TRUE(!prefs->IsExternalExtensionAcknowledged(good_crx));
3866 ASSERT_TRUE(prefs->IsExternalExtensionAcknowledged(page_action));
3867 }
3868
3869 #if !defined(OS_CHROMEOS)
3870 // This tests if default apps are installed correctly.
TEST_F(ExtensionServiceTest,DefaultAppsInstall)3871 TEST_F(ExtensionServiceTest, DefaultAppsInstall) {
3872 InitializeEmptyExtensionService();
3873 set_extensions_enabled(true);
3874
3875 {
3876 std::string json_data =
3877 "{"
3878 " \"ldnnhddmnhbkjipkidpdiheffobcpfmf\" : {"
3879 " \"external_crx\": \"good.crx\","
3880 " \"external_version\": \"1.0.0.0\","
3881 " \"is_bookmark_app\": false"
3882 " }"
3883 "}";
3884 default_apps::Provider* provider =
3885 new default_apps::Provider(
3886 profile_.get(),
3887 service_,
3888 new extensions::ExternalTestingLoader(json_data, data_dir_),
3889 Manifest::INTERNAL,
3890 Manifest::INVALID_LOCATION,
3891 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
3892
3893 AddMockExternalProvider(provider);
3894 }
3895
3896 ASSERT_EQ(0u, service_->extensions()->size());
3897 content::WindowedNotificationObserver observer(
3898 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
3899 content::NotificationService::AllSources());
3900 service_->CheckForExternalUpdates();
3901 observer.Wait();
3902
3903 ASSERT_EQ(1u, service_->extensions()->size());
3904 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3905 const Extension* extension = service_->GetExtensionById(good_crx, false);
3906 EXPECT_TRUE(extension->from_webstore());
3907 EXPECT_TRUE(extension->was_installed_by_default());
3908 }
3909 #endif
3910
3911 // Tests disabling extensions
TEST_F(ExtensionServiceTest,DisableExtension)3912 TEST_F(ExtensionServiceTest, DisableExtension) {
3913 InitializeEmptyExtensionService();
3914
3915 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3916 EXPECT_FALSE(service_->extensions()->is_empty());
3917 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3918 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
3919 EXPECT_TRUE(service_->disabled_extensions()->is_empty());
3920
3921 // Disable it.
3922 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3923
3924 EXPECT_TRUE(service_->extensions()->is_empty());
3925 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3926 EXPECT_FALSE(service_->GetExtensionById(good_crx, false));
3927 EXPECT_FALSE(service_->disabled_extensions()->is_empty());
3928 }
3929
TEST_F(ExtensionServiceTest,DisableTerminatedExtension)3930 TEST_F(ExtensionServiceTest, DisableTerminatedExtension) {
3931 InitializeEmptyExtensionService();
3932
3933 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
3934 TerminateExtension(good_crx);
3935 EXPECT_TRUE(service_->GetTerminatedExtension(good_crx));
3936
3937 // Disable it.
3938 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
3939
3940 EXPECT_FALSE(service_->GetTerminatedExtension(good_crx));
3941 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
3942 EXPECT_FALSE(service_->disabled_extensions()->is_empty());
3943 }
3944
3945 // Tests disabling all extensions (simulating --disable-extensions flag).
TEST_F(ExtensionServiceTest,DisableAllExtensions)3946 TEST_F(ExtensionServiceTest, DisableAllExtensions) {
3947 InitializeEmptyExtensionService();
3948
3949 base::FilePath path = data_dir_.AppendASCII("good.crx");
3950 InstallCRX(path, INSTALL_NEW);
3951
3952 EXPECT_EQ(1u, service_->extensions()->size());
3953 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3954
3955 // Disable extensions.
3956 service_->set_extensions_enabled(false);
3957 service_->ReloadExtensions();
3958
3959 // There shouldn't be extensions in either list.
3960 EXPECT_EQ(0u, service_->extensions()->size());
3961 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3962
3963 // This shouldn't do anything when all extensions are disabled.
3964 service_->EnableExtension(good_crx);
3965 service_->ReloadExtensions();
3966
3967 // There still shouldn't be extensions in either list.
3968 EXPECT_EQ(0u, service_->extensions()->size());
3969 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3970
3971 // And then re-enable the extensions.
3972 service_->set_extensions_enabled(true);
3973 service_->ReloadExtensions();
3974
3975 EXPECT_EQ(1u, service_->extensions()->size());
3976 EXPECT_EQ(0u, service_->disabled_extensions()->size());
3977 }
3978
3979 // Tests reloading extensions.
TEST_F(ExtensionServiceTest,ReloadExtensions)3980 TEST_F(ExtensionServiceTest, ReloadExtensions) {
3981 InitializeEmptyExtensionService();
3982
3983 // Simple extension that should install without error.
3984 base::FilePath path = data_dir_.AppendASCII("good.crx");
3985 InstallCRX(path, INSTALL_NEW,
3986 Extension::FROM_WEBSTORE | Extension::WAS_INSTALLED_BY_DEFAULT);
3987 const char* extension_id = good_crx;
3988 service_->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
3989
3990 EXPECT_EQ(0u, service_->extensions()->size());
3991 EXPECT_EQ(1u, service_->disabled_extensions()->size());
3992
3993 service_->ReloadExtensions();
3994
3995 // The creation flags should not change when reloading the extension.
3996 const Extension* extension = service_->GetExtensionById(good_crx, true);
3997 EXPECT_TRUE(extension->from_webstore());
3998 EXPECT_TRUE(extension->was_installed_by_default());
3999 EXPECT_FALSE(extension->from_bookmark());
4000
4001 // Extension counts shouldn't change.
4002 EXPECT_EQ(0u, service_->extensions()->size());
4003 EXPECT_EQ(1u, service_->disabled_extensions()->size());
4004
4005 service_->EnableExtension(extension_id);
4006
4007 EXPECT_EQ(1u, service_->extensions()->size());
4008 EXPECT_EQ(0u, service_->disabled_extensions()->size());
4009
4010 // Need to clear |loaded_| manually before reloading as the
4011 // EnableExtension() call above inserted into it and
4012 // UnloadAllExtensions() doesn't send out notifications.
4013 loaded_.clear();
4014 service_->ReloadExtensions();
4015
4016 // Extension counts shouldn't change.
4017 EXPECT_EQ(1u, service_->extensions()->size());
4018 EXPECT_EQ(0u, service_->disabled_extensions()->size());
4019 }
4020
4021 // Tests reloading an extension.
TEST_F(ExtensionServiceTest,ReloadExtension)4022 TEST_F(ExtensionServiceTest, ReloadExtension) {
4023 InitializeEmptyExtensionService();
4024 InitializeProcessManager();
4025
4026 // Simple extension that should install without error.
4027 const char* extension_id = "behllobkkfkfnphdnhnkndlbkcpglgmj";
4028 base::FilePath ext = data_dir_
4029 .AppendASCII("good")
4030 .AppendASCII("Extensions")
4031 .AppendASCII(extension_id)
4032 .AppendASCII("1.0.0.0");
4033 extensions::UnpackedInstaller::Create(service_)->Load(ext);
4034 base::RunLoop().RunUntilIdle();
4035
4036 EXPECT_EQ(1u, service_->extensions()->size());
4037 EXPECT_EQ(0u, service_->disabled_extensions()->size());
4038
4039 service_->ReloadExtension(extension_id);
4040
4041 // Extension should be disabled now, waiting to be reloaded.
4042 EXPECT_EQ(0u, service_->extensions()->size());
4043 EXPECT_EQ(1u, service_->disabled_extensions()->size());
4044 EXPECT_EQ(Extension::DISABLE_RELOAD,
4045 service_->extension_prefs()->GetDisableReasons(extension_id));
4046
4047 // Reloading again should not crash.
4048 service_->ReloadExtension(extension_id);
4049
4050 // Finish reloading
4051 base::RunLoop().RunUntilIdle();
4052
4053 // Extension should be enabled again.
4054 EXPECT_EQ(1u, service_->extensions()->size());
4055 EXPECT_EQ(0u, service_->disabled_extensions()->size());
4056 }
4057
TEST_F(ExtensionServiceTest,UninstallExtension)4058 TEST_F(ExtensionServiceTest, UninstallExtension) {
4059 InitializeEmptyExtensionService();
4060 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
4061 EXPECT_EQ(1u, service_->extensions()->size());
4062 UninstallExtension(good_crx, false);
4063 EXPECT_EQ(0u, service_->extensions()->size());
4064 }
4065
TEST_F(ExtensionServiceTest,UninstallTerminatedExtension)4066 TEST_F(ExtensionServiceTest, UninstallTerminatedExtension) {
4067 InitializeEmptyExtensionService();
4068 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
4069 TerminateExtension(good_crx);
4070 UninstallExtension(good_crx, false);
4071 }
4072
4073 // Tests the uninstaller helper.
TEST_F(ExtensionServiceTest,UninstallExtensionHelper)4074 TEST_F(ExtensionServiceTest, UninstallExtensionHelper) {
4075 InitializeEmptyExtensionService();
4076 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
4077 UninstallExtension(good_crx, true);
4078 }
4079
TEST_F(ExtensionServiceTest,UninstallExtensionHelperTerminated)4080 TEST_F(ExtensionServiceTest, UninstallExtensionHelperTerminated) {
4081 InitializeEmptyExtensionService();
4082 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
4083 TerminateExtension(good_crx);
4084 UninstallExtension(good_crx, true);
4085 }
4086
4087 // An extension disabled because of unsupported requirements should re-enabled
4088 // if updated to a version with supported requirements as long as there are no
4089 // other disable reasons.
TEST_F(ExtensionServiceTest,UpgradingRequirementsEnabled)4090 TEST_F(ExtensionServiceTest, UpgradingRequirementsEnabled) {
4091 InitializeEmptyExtensionService();
4092 BlackListWebGL();
4093
4094 base::FilePath path = data_dir_.AppendASCII("requirements");
4095 base::FilePath pem_path = data_dir_.AppendASCII("requirements")
4096 .AppendASCII("v1_good.pem");
4097 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4098 pem_path,
4099 INSTALL_NEW);
4100 std::string id = extension_v1->id();
4101 EXPECT_TRUE(service_->IsExtensionEnabled(id));
4102
4103 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4104
4105 PackCRX(path.AppendASCII("v2_bad_requirements"),
4106 pem_path,
4107 v2_bad_requirements_crx);
4108 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4109 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4110
4111 base::FilePath v3_good_crx = GetTemporaryFile();
4112
4113 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4114 UpdateExtension(id, v3_good_crx, ENABLED);
4115 EXPECT_TRUE(service_->IsExtensionEnabled(id));
4116 }
4117
4118 // Extensions disabled through user action should stay disabled.
TEST_F(ExtensionServiceTest,UpgradingRequirementsDisabled)4119 TEST_F(ExtensionServiceTest, UpgradingRequirementsDisabled) {
4120 InitializeEmptyExtensionService();
4121 BlackListWebGL();
4122
4123 base::FilePath path = data_dir_.AppendASCII("requirements");
4124 base::FilePath pem_path = data_dir_.AppendASCII("requirements")
4125 .AppendASCII("v1_good.pem");
4126 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4127 pem_path,
4128 INSTALL_NEW);
4129 std::string id = extension_v1->id();
4130 service_->DisableExtension(id, Extension::DISABLE_USER_ACTION);
4131 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4132
4133 base::FilePath v2_bad_requirements_crx = GetTemporaryFile();
4134
4135 PackCRX(path.AppendASCII("v2_bad_requirements"),
4136 pem_path,
4137 v2_bad_requirements_crx);
4138 UpdateExtension(id, v2_bad_requirements_crx, INSTALLED);
4139 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4140
4141 base::FilePath v3_good_crx = GetTemporaryFile();
4142
4143 PackCRX(path.AppendASCII("v3_good"), pem_path, v3_good_crx);
4144 UpdateExtension(id, v3_good_crx, INSTALLED);
4145 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4146 }
4147
4148 // The extension should not re-enabled because it was disabled from a
4149 // permission increase.
TEST_F(ExtensionServiceTest,UpgradingRequirementsPermissions)4150 TEST_F(ExtensionServiceTest, UpgradingRequirementsPermissions) {
4151 InitializeEmptyExtensionService();
4152 BlackListWebGL();
4153
4154 base::FilePath path = data_dir_.AppendASCII("requirements");
4155 base::FilePath pem_path = data_dir_.AppendASCII("requirements")
4156 .AppendASCII("v1_good.pem");
4157 const Extension* extension_v1 = PackAndInstallCRX(path.AppendASCII("v1_good"),
4158 pem_path,
4159 INSTALL_NEW);
4160 std::string id = extension_v1->id();
4161 EXPECT_TRUE(service_->IsExtensionEnabled(id));
4162
4163 base::FilePath v2_bad_requirements_and_permissions_crx = GetTemporaryFile();
4164
4165 PackCRX(path.AppendASCII("v2_bad_requirements_and_permissions"),
4166 pem_path,
4167 v2_bad_requirements_and_permissions_crx);
4168 UpdateExtension(id, v2_bad_requirements_and_permissions_crx, INSTALLED);
4169 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4170
4171 base::FilePath v3_bad_permissions_crx = GetTemporaryFile();
4172
4173 PackCRX(path.AppendASCII("v3_bad_permissions"),
4174 pem_path,
4175 v3_bad_permissions_crx);
4176 UpdateExtension(id, v3_bad_permissions_crx, INSTALLED);
4177 EXPECT_FALSE(service_->IsExtensionEnabled(id));
4178 }
4179
4180 // Unpacked extensions are not allowed to be installed if they have unsupported
4181 // requirements.
TEST_F(ExtensionServiceTest,UnpackedRequirements)4182 TEST_F(ExtensionServiceTest, UnpackedRequirements) {
4183 InitializeEmptyExtensionService();
4184 BlackListWebGL();
4185
4186 base::FilePath path = data_dir_.AppendASCII("requirements")
4187 .AppendASCII("v2_bad_requirements");
4188 extensions::UnpackedInstaller::Create(service_)->Load(path);
4189 base::RunLoop().RunUntilIdle();
4190 EXPECT_EQ(1u, GetErrors().size());
4191 EXPECT_EQ(0u, service_->extensions()->size());
4192 }
4193
4194 class ExtensionCookieCallback {
4195 public:
ExtensionCookieCallback()4196 ExtensionCookieCallback()
4197 : result_(false),
4198 weak_factory_(base::MessageLoop::current()) {}
4199
SetCookieCallback(bool result)4200 void SetCookieCallback(bool result) {
4201 base::MessageLoop::current()->PostTask(FROM_HERE,
4202 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4203 result_ = result;
4204 }
4205
GetAllCookiesCallback(const net::CookieList & list)4206 void GetAllCookiesCallback(const net::CookieList& list) {
4207 base::MessageLoop::current()->PostTask(FROM_HERE,
4208 base::Bind(&base::MessageLoop::Quit, weak_factory_.GetWeakPtr()));
4209 list_ = list;
4210 }
4211 net::CookieList list_;
4212 bool result_;
4213 base::WeakPtrFactory<base::MessageLoop> weak_factory_;
4214 };
4215
4216 // Verifies extension state is removed upon uninstall.
TEST_F(ExtensionServiceTest,ClearExtensionData)4217 TEST_F(ExtensionServiceTest, ClearExtensionData) {
4218 InitializeEmptyExtensionService();
4219 ExtensionCookieCallback callback;
4220
4221 // Load a test extension.
4222 base::FilePath path = data_dir_;
4223 path = path.AppendASCII("good.crx");
4224 const Extension* extension = InstallCRX(path, INSTALL_NEW);
4225 ASSERT_TRUE(extension);
4226 GURL ext_url(extension->url());
4227 std::string origin_id = webkit_database::GetIdentifierFromOrigin(ext_url);
4228
4229 // Set a cookie for the extension.
4230 net::CookieMonster* cookie_monster =
4231 profile_->GetRequestContextForExtensions()->GetURLRequestContext()->
4232 cookie_store()->GetCookieMonster();
4233 ASSERT_TRUE(cookie_monster);
4234 net::CookieOptions options;
4235 cookie_monster->SetCookieWithOptionsAsync(
4236 ext_url, "dummy=value", options,
4237 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4238 base::Unretained(&callback)));
4239 base::RunLoop().RunUntilIdle();
4240 EXPECT_TRUE(callback.result_);
4241
4242 cookie_monster->GetAllCookiesForURLAsync(
4243 ext_url,
4244 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4245 base::Unretained(&callback)));
4246 base::RunLoop().RunUntilIdle();
4247 EXPECT_EQ(1U, callback.list_.size());
4248
4249 // Open a database.
4250 webkit_database::DatabaseTracker* db_tracker =
4251 BrowserContext::GetDefaultStoragePartition(profile_.get())->
4252 GetDatabaseTracker();
4253 base::string16 db_name = UTF8ToUTF16("db");
4254 base::string16 description = UTF8ToUTF16("db_description");
4255 int64 size;
4256 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4257 db_tracker->DatabaseClosed(origin_id, db_name);
4258 std::vector<webkit_database::OriginInfo> origins;
4259 db_tracker->GetAllOriginsInfo(&origins);
4260 EXPECT_EQ(1U, origins.size());
4261 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4262
4263 // Create local storage. We only simulate this by creating the backing files.
4264 // Note: This test depends on details of how the dom_storage library
4265 // stores data in the host file system.
4266 base::FilePath lso_dir_path =
4267 profile_->GetPath().AppendASCII("Local Storage");
4268 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4269 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4270 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4271 EXPECT_EQ(0, file_util::WriteFile(lso_file_path, NULL, 0));
4272 EXPECT_TRUE(base::PathExists(lso_file_path));
4273
4274 // Create indexed db. Similarly, it is enough to only simulate this by
4275 // creating the directory on the disk.
4276 IndexedDBContext* idb_context =
4277 BrowserContext::GetDefaultStoragePartition(profile_.get())->
4278 GetIndexedDBContext();
4279 idb_context->SetTaskRunnerForTesting(
4280 base::MessageLoop::current()->message_loop_proxy().get());
4281 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4282 EXPECT_TRUE(base::CreateDirectory(idb_path));
4283 EXPECT_TRUE(base::DirectoryExists(idb_path));
4284
4285 // Uninstall the extension.
4286 service_->UninstallExtension(good_crx, false, NULL);
4287 base::RunLoop().RunUntilIdle();
4288
4289 // Check that the cookie is gone.
4290 cookie_monster->GetAllCookiesForURLAsync(
4291 ext_url,
4292 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4293 base::Unretained(&callback)));
4294 base::RunLoop().RunUntilIdle();
4295 EXPECT_EQ(0U, callback.list_.size());
4296
4297 // The database should have vanished as well.
4298 origins.clear();
4299 db_tracker->GetAllOriginsInfo(&origins);
4300 EXPECT_EQ(0U, origins.size());
4301
4302 // Check that the LSO file has been removed.
4303 EXPECT_FALSE(base::PathExists(lso_file_path));
4304
4305 // Check if the indexed db has disappeared too.
4306 EXPECT_FALSE(base::DirectoryExists(idb_path));
4307 }
4308
4309 // Verifies app state is removed upon uninstall.
TEST_F(ExtensionServiceTest,ClearAppData)4310 TEST_F(ExtensionServiceTest, ClearAppData) {
4311 InitializeEmptyExtensionService();
4312 ExtensionCookieCallback callback;
4313
4314 int pref_count = 0;
4315
4316 // Install app1 with unlimited storage.
4317 const Extension* extension =
4318 PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
4319 ValidatePrefKeyCount(++pref_count);
4320 ASSERT_EQ(1u, service_->extensions()->size());
4321 const std::string id1 = extension->id();
4322 EXPECT_TRUE(extension->HasAPIPermission(
4323 APIPermission::kUnlimitedStorage));
4324 const GURL origin1(
4325 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4326 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
4327 IsStorageUnlimited(origin1));
4328 std::string origin_id = webkit_database::GetIdentifierFromOrigin(origin1);
4329
4330 // Install app2 from the same origin with unlimited storage.
4331 extension = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
4332 ValidatePrefKeyCount(++pref_count);
4333 ASSERT_EQ(2u, service_->extensions()->size());
4334 const std::string id2 = extension->id();
4335 EXPECT_TRUE(extension->HasAPIPermission(
4336 APIPermission::kUnlimitedStorage));
4337 EXPECT_TRUE(extension->web_extent().MatchesURL(
4338 extensions::AppLaunchInfo::GetFullLaunchURL(extension)));
4339 const GURL origin2(
4340 extensions::AppLaunchInfo::GetFullLaunchURL(extension).GetOrigin());
4341 EXPECT_EQ(origin1, origin2);
4342 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
4343 IsStorageUnlimited(origin2));
4344
4345 // Set a cookie for the extension.
4346 net::CookieMonster* cookie_monster =
4347 profile_->GetRequestContext()->GetURLRequestContext()->
4348 cookie_store()->GetCookieMonster();
4349 ASSERT_TRUE(cookie_monster);
4350 net::CookieOptions options;
4351 cookie_monster->SetCookieWithOptionsAsync(
4352 origin1, "dummy=value", options,
4353 base::Bind(&ExtensionCookieCallback::SetCookieCallback,
4354 base::Unretained(&callback)));
4355 base::RunLoop().RunUntilIdle();
4356 EXPECT_TRUE(callback.result_);
4357
4358 cookie_monster->GetAllCookiesForURLAsync(
4359 origin1,
4360 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4361 base::Unretained(&callback)));
4362 base::RunLoop().RunUntilIdle();
4363 EXPECT_EQ(1U, callback.list_.size());
4364
4365 // Open a database.
4366 webkit_database::DatabaseTracker* db_tracker =
4367 BrowserContext::GetDefaultStoragePartition(profile_.get())->
4368 GetDatabaseTracker();
4369 base::string16 db_name = UTF8ToUTF16("db");
4370 base::string16 description = UTF8ToUTF16("db_description");
4371 int64 size;
4372 db_tracker->DatabaseOpened(origin_id, db_name, description, 1, &size);
4373 db_tracker->DatabaseClosed(origin_id, db_name);
4374 std::vector<webkit_database::OriginInfo> origins;
4375 db_tracker->GetAllOriginsInfo(&origins);
4376 EXPECT_EQ(1U, origins.size());
4377 EXPECT_EQ(origin_id, origins[0].GetOriginIdentifier());
4378
4379 // Create local storage. We only simulate this by creating the backing files.
4380 // Note: This test depends on details of how the dom_storage library
4381 // stores data in the host file system.
4382 base::FilePath lso_dir_path =
4383 profile_->GetPath().AppendASCII("Local Storage");
4384 base::FilePath lso_file_path = lso_dir_path.AppendASCII(origin_id)
4385 .AddExtension(FILE_PATH_LITERAL(".localstorage"));
4386 EXPECT_TRUE(base::CreateDirectory(lso_dir_path));
4387 EXPECT_EQ(0, file_util::WriteFile(lso_file_path, NULL, 0));
4388 EXPECT_TRUE(base::PathExists(lso_file_path));
4389
4390 // Create indexed db. Similarly, it is enough to only simulate this by
4391 // creating the directory on the disk.
4392 IndexedDBContext* idb_context =
4393 BrowserContext::GetDefaultStoragePartition(profile_.get())->
4394 GetIndexedDBContext();
4395 idb_context->SetTaskRunnerForTesting(
4396 base::MessageLoop::current()->message_loop_proxy().get());
4397 base::FilePath idb_path = idb_context->GetFilePathForTesting(origin_id);
4398 EXPECT_TRUE(base::CreateDirectory(idb_path));
4399 EXPECT_TRUE(base::DirectoryExists(idb_path));
4400
4401 // Uninstall one of them, unlimited storage should still be granted
4402 // to the origin.
4403 UninstallExtension(id1, false);
4404 EXPECT_EQ(1u, service_->extensions()->size());
4405 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->
4406 IsStorageUnlimited(origin1));
4407
4408 // Check that the cookie is still there.
4409 cookie_monster->GetAllCookiesForURLAsync(
4410 origin1,
4411 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4412 base::Unretained(&callback)));
4413 base::RunLoop().RunUntilIdle();
4414 EXPECT_EQ(1U, callback.list_.size());
4415
4416 // Now uninstall the other. Storage should be cleared for the apps.
4417 UninstallExtension(id2, false);
4418 EXPECT_EQ(0u, service_->extensions()->size());
4419 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->
4420 IsStorageUnlimited(origin1));
4421
4422 // Check that the cookie is gone.
4423 cookie_monster->GetAllCookiesForURLAsync(
4424 origin1,
4425 base::Bind(&ExtensionCookieCallback::GetAllCookiesCallback,
4426 base::Unretained(&callback)));
4427 base::RunLoop().RunUntilIdle();
4428 EXPECT_EQ(0U, callback.list_.size());
4429
4430 // The database should have vanished as well.
4431 origins.clear();
4432 db_tracker->GetAllOriginsInfo(&origins);
4433 EXPECT_EQ(0U, origins.size());
4434
4435 // Check that the LSO file has been removed.
4436 EXPECT_FALSE(base::PathExists(lso_file_path));
4437
4438 // Check if the indexed db has disappeared too.
4439 EXPECT_FALSE(base::DirectoryExists(idb_path));
4440 }
4441
4442 // Tests loading single extensions (like --load-extension)
4443 // Flaky crashes. http://crbug.com/231806
TEST_F(ExtensionServiceTest,DISABLED_LoadExtension)4444 TEST_F(ExtensionServiceTest, DISABLED_LoadExtension) {
4445 InitializeEmptyExtensionService();
4446
4447 base::FilePath ext1 = data_dir_
4448 .AppendASCII("good")
4449 .AppendASCII("Extensions")
4450 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
4451 .AppendASCII("1.0.0.0");
4452 extensions::UnpackedInstaller::Create(service_)->Load(ext1);
4453 base::RunLoop().RunUntilIdle();
4454 EXPECT_EQ(0u, GetErrors().size());
4455 ASSERT_EQ(1u, loaded_.size());
4456 EXPECT_EQ(Manifest::UNPACKED, loaded_[0]->location());
4457 EXPECT_EQ(1u, service_->extensions()->size());
4458
4459 ValidatePrefKeyCount(1);
4460
4461 base::FilePath no_manifest = data_dir_
4462 .AppendASCII("bad")
4463 // .AppendASCII("Extensions")
4464 .AppendASCII("cccccccccccccccccccccccccccccccc")
4465 .AppendASCII("1");
4466 extensions::UnpackedInstaller::Create(service_)->Load(no_manifest);
4467 base::RunLoop().RunUntilIdle();
4468 EXPECT_EQ(1u, GetErrors().size());
4469 ASSERT_EQ(1u, loaded_.size());
4470 EXPECT_EQ(1u, service_->extensions()->size());
4471
4472 // Test uninstall.
4473 std::string id = loaded_[0]->id();
4474 EXPECT_FALSE(unloaded_id_.length());
4475 service_->UninstallExtension(id, false, NULL);
4476 base::RunLoop().RunUntilIdle();
4477 EXPECT_EQ(id, unloaded_id_);
4478 ASSERT_EQ(0u, loaded_.size());
4479 EXPECT_EQ(0u, service_->extensions()->size());
4480 }
4481
4482 // Tests that we generate IDs when they are not specified in the manifest for
4483 // --load-extension.
TEST_F(ExtensionServiceTest,GenerateID)4484 TEST_F(ExtensionServiceTest, GenerateID) {
4485 InitializeEmptyExtensionService();
4486
4487 base::FilePath no_id_ext = data_dir_.AppendASCII("no_id");
4488 extensions::UnpackedInstaller::Create(service_)->Load(no_id_ext);
4489 base::RunLoop().RunUntilIdle();
4490 EXPECT_EQ(0u, GetErrors().size());
4491 ASSERT_EQ(1u, loaded_.size());
4492 ASSERT_TRUE(Extension::IdIsValid(loaded_[0]->id()));
4493 EXPECT_EQ(loaded_[0]->location(), Manifest::UNPACKED);
4494
4495 ValidatePrefKeyCount(1);
4496
4497 std::string previous_id = loaded_[0]->id();
4498
4499 // If we reload the same path, we should get the same extension ID.
4500 extensions::UnpackedInstaller::Create(service_)->Load(no_id_ext);
4501 base::RunLoop().RunUntilIdle();
4502 ASSERT_EQ(1u, loaded_.size());
4503 ASSERT_EQ(previous_id, loaded_[0]->id());
4504 }
4505
TEST_F(ExtensionServiceTest,UnpackedValidatesLocales)4506 TEST_F(ExtensionServiceTest, UnpackedValidatesLocales) {
4507 InitializeEmptyExtensionService();
4508
4509 base::FilePath bad_locale = data_dir_.AppendASCII("unpacked").
4510 AppendASCII("bad_messages_file");
4511 extensions::UnpackedInstaller::Create(service_)->Load(bad_locale);
4512 base::RunLoop().RunUntilIdle();
4513 EXPECT_EQ(1u, GetErrors().size());
4514 base::FilePath ms_messages_file = bad_locale.AppendASCII("_locales")
4515 .AppendASCII("ms")
4516 .AppendASCII("messages.json");
4517 EXPECT_THAT(UTF16ToUTF8(GetErrors()[0]), testing::AllOf(
4518 testing::HasSubstr(UTF16ToUTF8(ms_messages_file.LossyDisplayName())),
4519 testing::HasSubstr("Dictionary keys must be quoted.")));
4520 ASSERT_EQ(0u, loaded_.size());
4521 }
4522
TestExternalProvider(MockExtensionProvider * provider,Manifest::Location location)4523 void ExtensionServiceTest::TestExternalProvider(
4524 MockExtensionProvider* provider, Manifest::Location location) {
4525 // Verify that starting with no providers loads no extensions.
4526 service_->Init();
4527 ASSERT_EQ(0u, loaded_.size());
4528
4529 provider->set_visit_count(0);
4530
4531 // Register a test extension externally using the mock registry provider.
4532 base::FilePath source_path = data_dir_.AppendASCII("good.crx");
4533
4534 // Add the extension.
4535 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
4536
4537 // Reloading extensions should find our externally registered extension
4538 // and install it.
4539 content::WindowedNotificationObserver observer(
4540 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
4541 content::NotificationService::AllSources());
4542 service_->CheckForExternalUpdates();
4543 observer.Wait();
4544
4545 ASSERT_EQ(0u, GetErrors().size());
4546 ASSERT_EQ(1u, loaded_.size());
4547 ASSERT_EQ(location, loaded_[0]->location());
4548 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
4549 ValidatePrefKeyCount(1);
4550 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4551 ValidateIntegerPref(good_crx, "location", location);
4552
4553 // Reload extensions without changing anything. The extension should be
4554 // loaded again.
4555 loaded_.clear();
4556 service_->ReloadExtensions();
4557 base::RunLoop().RunUntilIdle();
4558 ASSERT_EQ(0u, GetErrors().size());
4559 ASSERT_EQ(1u, loaded_.size());
4560 ValidatePrefKeyCount(1);
4561 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4562 ValidateIntegerPref(good_crx, "location", location);
4563
4564 // Now update the extension with a new version. We should get upgraded.
4565 source_path = source_path.DirName().AppendASCII("good2.crx");
4566 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
4567
4568 loaded_.clear();
4569 content::WindowedNotificationObserver observer_2(
4570 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
4571 content::NotificationService::AllSources());
4572 service_->CheckForExternalUpdates();
4573 observer_2.Wait();
4574 ASSERT_EQ(0u, GetErrors().size());
4575 ASSERT_EQ(1u, loaded_.size());
4576 ASSERT_EQ("1.0.0.1", loaded_[0]->version()->GetString());
4577 ValidatePrefKeyCount(1);
4578 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4579 ValidateIntegerPref(good_crx, "location", location);
4580
4581 // Uninstall the extension and reload. Nothing should happen because the
4582 // preference should prevent us from reinstalling.
4583 std::string id = loaded_[0]->id();
4584 bool no_uninstall =
4585 management_policy_->MustRemainEnabled(loaded_[0].get(), NULL);
4586 service_->UninstallExtension(id, false, NULL);
4587 base::RunLoop().RunUntilIdle();
4588
4589 base::FilePath install_path = extensions_install_dir_.AppendASCII(id);
4590 if (no_uninstall) {
4591 // Policy controlled extensions should not have been touched by uninstall.
4592 ASSERT_TRUE(base::PathExists(install_path));
4593 } else {
4594 // The extension should also be gone from the install directory.
4595 ASSERT_FALSE(base::PathExists(install_path));
4596 loaded_.clear();
4597 service_->CheckForExternalUpdates();
4598 base::RunLoop().RunUntilIdle();
4599 ASSERT_EQ(0u, loaded_.size());
4600 ValidatePrefKeyCount(1);
4601 ValidateIntegerPref(good_crx, "state",
4602 Extension::EXTERNAL_EXTENSION_UNINSTALLED);
4603 ValidateIntegerPref(good_crx, "location", location);
4604
4605 // Now clear the preference and reinstall.
4606 SetPrefInteg(good_crx, "state", Extension::ENABLED);
4607
4608 loaded_.clear();
4609 content::WindowedNotificationObserver observer(
4610 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
4611 content::NotificationService::AllSources());
4612 service_->CheckForExternalUpdates();
4613 observer.Wait();
4614 ASSERT_EQ(1u, loaded_.size());
4615 }
4616 ValidatePrefKeyCount(1);
4617 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4618 ValidateIntegerPref(good_crx, "location", location);
4619
4620 if (management_policy_->MustRemainEnabled(loaded_[0].get(), NULL)) {
4621 EXPECT_EQ(2, provider->visit_count());
4622 } else {
4623 // Now test an externally triggered uninstall (deleting the registry key or
4624 // the pref entry).
4625 provider->RemoveExtension(good_crx);
4626
4627 loaded_.clear();
4628 service_->OnExternalProviderReady(provider);
4629 base::RunLoop().RunUntilIdle();
4630 ASSERT_EQ(0u, loaded_.size());
4631 ValidatePrefKeyCount(0);
4632
4633 // The extension should also be gone from the install directory.
4634 ASSERT_FALSE(base::PathExists(install_path));
4635
4636 // Now test the case where user uninstalls and then the extension is removed
4637 // from the external provider.
4638 content::WindowedNotificationObserver observer(
4639 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
4640 content::NotificationService::AllSources());
4641 provider->UpdateOrAddExtension(good_crx, "1.0.0.1", source_path);
4642 service_->CheckForExternalUpdates();
4643 observer.Wait();
4644
4645 ASSERT_EQ(1u, loaded_.size());
4646 ASSERT_EQ(0u, GetErrors().size());
4647
4648 // User uninstalls.
4649 loaded_.clear();
4650 service_->UninstallExtension(id, false, NULL);
4651 base::RunLoop().RunUntilIdle();
4652 ASSERT_EQ(0u, loaded_.size());
4653
4654 // Then remove the extension from the extension provider.
4655 provider->RemoveExtension(good_crx);
4656
4657 // Should still be at 0.
4658 loaded_.clear();
4659 extensions::InstalledLoader(service_).LoadAllExtensions();
4660 base::RunLoop().RunUntilIdle();
4661 ASSERT_EQ(0u, loaded_.size());
4662 ValidatePrefKeyCount(1);
4663
4664 EXPECT_EQ(5, provider->visit_count());
4665 }
4666 }
4667
4668 // Tests the external installation feature
4669 #if defined(OS_WIN)
TEST_F(ExtensionServiceTest,ExternalInstallRegistry)4670 TEST_F(ExtensionServiceTest, ExternalInstallRegistry) {
4671 // This should all work, even when normal extension installation is disabled.
4672 InitializeEmptyExtensionService();
4673 set_extensions_enabled(false);
4674
4675 // Now add providers. Extension system takes ownership of the objects.
4676 MockExtensionProvider* reg_provider =
4677 new MockExtensionProvider(service_, Manifest::EXTERNAL_REGISTRY);
4678 AddMockExternalProvider(reg_provider);
4679 TestExternalProvider(reg_provider, Manifest::EXTERNAL_REGISTRY);
4680 }
4681 #endif
4682
TEST_F(ExtensionServiceTest,ExternalInstallPref)4683 TEST_F(ExtensionServiceTest, ExternalInstallPref) {
4684 InitializeEmptyExtensionService();
4685
4686 // Now add providers. Extension system takes ownership of the objects.
4687 MockExtensionProvider* pref_provider =
4688 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
4689
4690 AddMockExternalProvider(pref_provider);
4691 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF);
4692 }
4693
TEST_F(ExtensionServiceTest,ExternalInstallPrefUpdateUrl)4694 TEST_F(ExtensionServiceTest, ExternalInstallPrefUpdateUrl) {
4695 // This should all work, even when normal extension installation is disabled.
4696 InitializeEmptyExtensionService();
4697 set_extensions_enabled(false);
4698
4699 // TODO(skerner): The mock provider is not a good model of a provider
4700 // that works with update URLs, because it adds file and version info.
4701 // Extend the mock to work with update URLs. This test checks the
4702 // behavior that is common to all external extension visitors. The
4703 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4704 // what the visitor does results in an extension being downloaded and
4705 // installed.
4706 MockExtensionProvider* pref_provider =
4707 new MockExtensionProvider(service_,
4708 Manifest::EXTERNAL_PREF_DOWNLOAD);
4709 AddMockExternalProvider(pref_provider);
4710 TestExternalProvider(pref_provider, Manifest::EXTERNAL_PREF_DOWNLOAD);
4711 }
4712
TEST_F(ExtensionServiceTest,ExternalInstallPolicyUpdateUrl)4713 TEST_F(ExtensionServiceTest, ExternalInstallPolicyUpdateUrl) {
4714 // This should all work, even when normal extension installation is disabled.
4715 InitializeEmptyExtensionService();
4716 set_extensions_enabled(false);
4717
4718 // TODO(skerner): The mock provider is not a good model of a provider
4719 // that works with update URLs, because it adds file and version info.
4720 // Extend the mock to work with update URLs. This test checks the
4721 // behavior that is common to all external extension visitors. The
4722 // browser test ExtensionManagementTest.ExternalUrlUpdate tests that
4723 // what the visitor does results in an extension being downloaded and
4724 // installed.
4725 MockExtensionProvider* pref_provider =
4726 new MockExtensionProvider(service_,
4727 Manifest::EXTERNAL_POLICY_DOWNLOAD);
4728 AddMockExternalProvider(pref_provider);
4729 TestExternalProvider(pref_provider, Manifest::EXTERNAL_POLICY_DOWNLOAD);
4730 }
4731
4732 // Tests that external extensions get uninstalled when the external extension
4733 // providers can't account for them.
TEST_F(ExtensionServiceTest,ExternalUninstall)4734 TEST_F(ExtensionServiceTest, ExternalUninstall) {
4735 // Start the extensions service with one external extension already installed.
4736 base::FilePath source_install_dir = data_dir_
4737 .AppendASCII("good")
4738 .AppendASCII("Extensions");
4739 base::FilePath pref_path = source_install_dir
4740 .DirName()
4741 .AppendASCII("PreferencesExternal");
4742
4743 // This initializes the extensions service with no ExternalProviders.
4744 InitializeInstalledExtensionService(pref_path, source_install_dir);
4745 set_extensions_enabled(false);
4746
4747 service_->Init();
4748
4749 ASSERT_EQ(0u, GetErrors().size());
4750 ASSERT_EQ(0u, loaded_.size());
4751
4752 // Verify that it's not the disabled extensions flag causing it not to load.
4753 set_extensions_enabled(true);
4754 service_->ReloadExtensions();
4755 base::RunLoop().RunUntilIdle();
4756
4757 ASSERT_EQ(0u, GetErrors().size());
4758 ASSERT_EQ(0u, loaded_.size());
4759 }
4760
4761 // Test that running multiple update checks simultaneously does not
4762 // keep the update from succeeding.
TEST_F(ExtensionServiceTest,MultipleExternalUpdateCheck)4763 TEST_F(ExtensionServiceTest, MultipleExternalUpdateCheck) {
4764 InitializeEmptyExtensionService();
4765
4766 MockExtensionProvider* provider =
4767 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
4768 AddMockExternalProvider(provider);
4769
4770 // Verify that starting with no providers loads no extensions.
4771 service_->Init();
4772 ASSERT_EQ(0u, loaded_.size());
4773
4774 // Start two checks for updates.
4775 provider->set_visit_count(0);
4776 service_->CheckForExternalUpdates();
4777 service_->CheckForExternalUpdates();
4778 base::RunLoop().RunUntilIdle();
4779
4780 // Two calls should cause two checks for external extensions.
4781 EXPECT_EQ(2, provider->visit_count());
4782 EXPECT_EQ(0u, GetErrors().size());
4783 EXPECT_EQ(0u, loaded_.size());
4784
4785 // Register a test extension externally using the mock registry provider.
4786 base::FilePath source_path = data_dir_.AppendASCII("good.crx");
4787 provider->UpdateOrAddExtension(good_crx, "1.0.0.0", source_path);
4788
4789 // Two checks for external updates should find the extension, and install it
4790 // once.
4791 content::WindowedNotificationObserver observer(
4792 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
4793 content::NotificationService::AllSources());
4794 provider->set_visit_count(0);
4795 service_->CheckForExternalUpdates();
4796 service_->CheckForExternalUpdates();
4797 observer.Wait();
4798 EXPECT_EQ(2, provider->visit_count());
4799 ASSERT_EQ(0u, GetErrors().size());
4800 ASSERT_EQ(1u, loaded_.size());
4801 ASSERT_EQ(Manifest::EXTERNAL_PREF, loaded_[0]->location());
4802 ASSERT_EQ("1.0.0.0", loaded_[0]->version()->GetString());
4803 ValidatePrefKeyCount(1);
4804 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
4805 ValidateIntegerPref(good_crx, "location", Manifest::EXTERNAL_PREF);
4806
4807 provider->RemoveExtension(good_crx);
4808 provider->set_visit_count(0);
4809 service_->CheckForExternalUpdates();
4810 service_->CheckForExternalUpdates();
4811 base::RunLoop().RunUntilIdle();
4812
4813 // Two calls should cause two checks for external extensions.
4814 // Because the external source no longer includes good_crx,
4815 // good_crx will be uninstalled. So, expect that no extensions
4816 // are loaded.
4817 EXPECT_EQ(2, provider->visit_count());
4818 EXPECT_EQ(0u, GetErrors().size());
4819 EXPECT_EQ(0u, loaded_.size());
4820 }
4821
TEST_F(ExtensionServiceTest,ExternalPrefProvider)4822 TEST_F(ExtensionServiceTest, ExternalPrefProvider) {
4823 InitializeEmptyExtensionService();
4824
4825 // Test some valid extension records.
4826 // Set a base path to avoid erroring out on relative paths.
4827 // Paths starting with // are absolute on every platform we support.
4828 base::FilePath base_path(FILE_PATH_LITERAL("//base/path"));
4829 ASSERT_TRUE(base_path.IsAbsolute());
4830 MockProviderVisitor visitor(base_path);
4831 std::string json_data =
4832 "{"
4833 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4834 " \"external_crx\": \"RandomExtension.crx\","
4835 " \"external_version\": \"1.0\""
4836 " },"
4837 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4838 " \"external_crx\": \"RandomExtension2.crx\","
4839 " \"external_version\": \"2.0\""
4840 " },"
4841 " \"cccccccccccccccccccccccccccccccc\": {"
4842 " \"external_update_url\": \"http:\\\\foo.com/update\""
4843 " }"
4844 "}";
4845 EXPECT_EQ(3, visitor.Visit(json_data));
4846
4847 // Simulate an external_extensions.json file that contains seven invalid
4848 // records:
4849 // - One that is missing the 'external_crx' key.
4850 // - One that is missing the 'external_version' key.
4851 // - One that is specifying .. in the path.
4852 // - One that specifies both a file and update URL.
4853 // - One that specifies no file or update URL.
4854 // - One that has an update URL that is not well formed.
4855 // - One that contains a malformed version.
4856 // - One that has an invalid id.
4857 // - One that has a non-dictionary value.
4858 // - One that has an integer 'external_version' instead of a string.
4859 // The final extension is valid, and we check that it is read to make sure
4860 // failures don't stop valid records from being read.
4861 json_data =
4862 "{"
4863 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4864 " \"external_version\": \"1.0\""
4865 " },"
4866 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4867 " \"external_crx\": \"RandomExtension.crx\""
4868 " },"
4869 " \"cccccccccccccccccccccccccccccccc\": {"
4870 " \"external_crx\": \"..\\\\foo\\\\RandomExtension2.crx\","
4871 " \"external_version\": \"2.0\""
4872 " },"
4873 " \"dddddddddddddddddddddddddddddddd\": {"
4874 " \"external_crx\": \"RandomExtension2.crx\","
4875 " \"external_version\": \"2.0\","
4876 " \"external_update_url\": \"http:\\\\foo.com/update\""
4877 " },"
4878 " \"eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee\": {"
4879 " },"
4880 " \"ffffffffffffffffffffffffffffffff\": {"
4881 " \"external_update_url\": \"This string is not a valid URL\""
4882 " },"
4883 " \"gggggggggggggggggggggggggggggggg\": {"
4884 " \"external_crx\": \"RandomExtension3.crx\","
4885 " \"external_version\": \"This is not a valid version!\""
4886 " },"
4887 " \"This is not a valid id!\": {},"
4888 " \"hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\": true,"
4889 " \"iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\": {"
4890 " \"external_crx\": \"RandomExtension4.crx\","
4891 " \"external_version\": 1.0"
4892 " },"
4893 " \"pppppppppppppppppppppppppppppppp\": {"
4894 " \"external_crx\": \"RandomValidExtension.crx\","
4895 " \"external_version\": \"1.0\""
4896 " }"
4897 "}";
4898 EXPECT_EQ(1, visitor.Visit(json_data));
4899
4900 // Check that if a base path is not provided, use of a relative
4901 // path fails.
4902 base::FilePath empty;
4903 MockProviderVisitor visitor_no_relative_paths(empty);
4904
4905 // Use absolute paths. Expect success.
4906 json_data =
4907 "{"
4908 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4909 " \"external_crx\": \"//RandomExtension1.crx\","
4910 " \"external_version\": \"3.0\""
4911 " },"
4912 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4913 " \"external_crx\": \"//path/to/RandomExtension2.crx\","
4914 " \"external_version\": \"3.0\""
4915 " }"
4916 "}";
4917 EXPECT_EQ(2, visitor_no_relative_paths.Visit(json_data));
4918
4919 // Use a relative path. Expect that it will error out.
4920 json_data =
4921 "{"
4922 " \"cccccccccccccccccccccccccccccccc\": {"
4923 " \"external_crx\": \"RandomExtension2.crx\","
4924 " \"external_version\": \"3.0\""
4925 " }"
4926 "}";
4927 EXPECT_EQ(0, visitor_no_relative_paths.Visit(json_data));
4928
4929 // Test supported_locales.
4930 json_data =
4931 "{"
4932 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4933 " \"external_crx\": \"RandomExtension.crx\","
4934 " \"external_version\": \"1.0\","
4935 " \"supported_locales\": [ \"en\" ]"
4936 " },"
4937 " \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\": {"
4938 " \"external_crx\": \"RandomExtension2.crx\","
4939 " \"external_version\": \"2.0\","
4940 " \"supported_locales\": [ \"en-GB\" ]"
4941 " },"
4942 " \"cccccccccccccccccccccccccccccccc\": {"
4943 " \"external_crx\": \"RandomExtension2.crx\","
4944 " \"external_version\": \"3.0\","
4945 " \"supported_locales\": [ \"en_US\", \"fr\" ]"
4946 " }"
4947 "}";
4948 {
4949 ScopedBrowserLocale guard("en-US");
4950 EXPECT_EQ(2, visitor.Visit(json_data));
4951 }
4952
4953 // Test keep_if_present.
4954 json_data =
4955 "{"
4956 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4957 " \"external_crx\": \"RandomExtension.crx\","
4958 " \"external_version\": \"1.0\","
4959 " \"keep_if_present\": true"
4960 " }"
4961 "}";
4962 {
4963 EXPECT_EQ(0, visitor.Visit(json_data));
4964 }
4965
4966 // Test is_bookmark_app.
4967 MockProviderVisitor from_bookmark_visitor(
4968 base_path, Extension::FROM_BOOKMARK);
4969 json_data =
4970 "{"
4971 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4972 " \"external_crx\": \"RandomExtension.crx\","
4973 " \"external_version\": \"1.0\","
4974 " \"is_bookmark_app\": true"
4975 " }"
4976 "}";
4977 EXPECT_EQ(1, from_bookmark_visitor.Visit(json_data));
4978
4979 // Test is_from_webstore.
4980 MockProviderVisitor from_webstore_visitor(
4981 base_path, Extension::FROM_WEBSTORE);
4982 json_data =
4983 "{"
4984 " \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\": {"
4985 " \"external_crx\": \"RandomExtension.crx\","
4986 " \"external_version\": \"1.0\","
4987 " \"is_from_webstore\": true"
4988 " }"
4989 "}";
4990 EXPECT_EQ(1, from_webstore_visitor.Visit(json_data));
4991 }
4992
4993 // Test loading good extensions from the profile directory.
TEST_F(ExtensionServiceTest,LoadAndRelocalizeExtensions)4994 TEST_F(ExtensionServiceTest, LoadAndRelocalizeExtensions) {
4995 // Ensure we're testing in "en" and leave global state untouched.
4996 extension_l10n_util::ScopedLocaleForTest testLocale("en");
4997
4998 // Initialize the test dir with a good Preferences/extensions.
4999 base::FilePath source_install_dir = data_dir_
5000 .AppendASCII("l10n");
5001 base::FilePath pref_path = source_install_dir.AppendASCII("Preferences");
5002 InitializeInstalledExtensionService(pref_path, source_install_dir);
5003
5004 service_->Init();
5005
5006 ASSERT_EQ(3u, loaded_.size());
5007
5008 // This was equal to "sr" on load.
5009 ValidateStringPref(loaded_[0]->id(), keys::kCurrentLocale, "en");
5010
5011 // These are untouched by re-localization.
5012 ValidateStringPref(loaded_[1]->id(), keys::kCurrentLocale, "en");
5013 EXPECT_FALSE(IsPrefExist(loaded_[1]->id(), keys::kCurrentLocale));
5014
5015 // This one starts with Serbian name, and gets re-localized into English.
5016 EXPECT_EQ("My name is simple.", loaded_[0]->name());
5017
5018 // These are untouched by re-localization.
5019 EXPECT_EQ("My name is simple.", loaded_[1]->name());
5020 EXPECT_EQ("no l10n", loaded_[2]->name());
5021 }
5022
5023 class ExtensionsReadyRecorder : public content::NotificationObserver {
5024 public:
ExtensionsReadyRecorder()5025 ExtensionsReadyRecorder() : ready_(false) {
5026 registrar_.Add(this, chrome::NOTIFICATION_EXTENSIONS_READY,
5027 content::NotificationService::AllSources());
5028 }
5029
set_ready(bool value)5030 void set_ready(bool value) { ready_ = value; }
ready()5031 bool ready() { return ready_; }
5032
5033 private:
Observe(int type,const content::NotificationSource & source,const content::NotificationDetails & details)5034 virtual void Observe(int type,
5035 const content::NotificationSource& source,
5036 const content::NotificationDetails& details) OVERRIDE {
5037 switch (type) {
5038 case chrome::NOTIFICATION_EXTENSIONS_READY:
5039 ready_ = true;
5040 break;
5041 default:
5042 NOTREACHED();
5043 }
5044 }
5045
5046 content::NotificationRegistrar registrar_;
5047 bool ready_;
5048 };
5049
5050 // Test that we get enabled/disabled correctly for all the pref/command-line
5051 // combinations. We don't want to derive from the ExtensionServiceTest class
5052 // for this test, so we use ExtensionServiceTestSimple.
5053 //
5054 // Also tests that we always fire EXTENSIONS_READY, no matter whether we are
5055 // enabled or not.
TEST(ExtensionServiceTestSimple,Enabledness)5056 TEST(ExtensionServiceTestSimple, Enabledness) {
5057 // Make sure the PluginService singleton is destroyed at the end of the test.
5058 base::ShadowingAtExitManager at_exit_manager;
5059 #if defined(ENABLE_PLUGINS)
5060 content::PluginService::GetInstance()->Init();
5061 content::PluginService::GetInstance()->DisablePluginsDiscoveryForTesting();
5062 #endif
5063
5064 ExtensionErrorReporter::Init(false); // no noisy errors
5065 ExtensionsReadyRecorder recorder;
5066 scoped_ptr<TestingProfile> profile(new TestingProfile());
5067 content::TestBrowserThreadBundle thread_bundle_;
5068 #if defined OS_CHROMEOS
5069 chromeos::ScopedTestDeviceSettingsService device_settings_service;
5070 chromeos::ScopedTestCrosSettings cros_settings;
5071 scoped_ptr<chromeos::ScopedTestUserManager> user_manager(
5072 new chromeos::ScopedTestUserManager);
5073 #endif
5074 scoped_ptr<CommandLine> command_line;
5075 base::FilePath install_dir = profile->GetPath()
5076 .AppendASCII(extensions::kInstallDirectoryName);
5077
5078 // By default, we are enabled.
5079 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
5080 ExtensionService* service = static_cast<extensions::TestExtensionSystem*>(
5081 ExtensionSystem::Get(profile.get()))->
5082 CreateExtensionService(
5083 command_line.get(),
5084 install_dir,
5085 false);
5086 EXPECT_TRUE(service->extensions_enabled());
5087 service->Init();
5088 base::RunLoop().RunUntilIdle();
5089 EXPECT_TRUE(recorder.ready());
5090 #if defined OS_CHROMEOS
5091 user_manager.reset();
5092 #endif
5093
5094 // If either the command line or pref is set, we are disabled.
5095 recorder.set_ready(false);
5096 profile.reset(new TestingProfile());
5097 command_line->AppendSwitch(switches::kDisableExtensions);
5098 service = static_cast<extensions::TestExtensionSystem*>(
5099 ExtensionSystem::Get(profile.get()))->
5100 CreateExtensionService(
5101 command_line.get(),
5102 install_dir,
5103 false);
5104 EXPECT_FALSE(service->extensions_enabled());
5105 service->Init();
5106 base::RunLoop().RunUntilIdle();
5107 EXPECT_TRUE(recorder.ready());
5108
5109 recorder.set_ready(false);
5110 profile.reset(new TestingProfile());
5111 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5112 service = static_cast<extensions::TestExtensionSystem*>(
5113 ExtensionSystem::Get(profile.get()))->
5114 CreateExtensionService(
5115 command_line.get(),
5116 install_dir,
5117 false);
5118 EXPECT_FALSE(service->extensions_enabled());
5119 service->Init();
5120 base::RunLoop().RunUntilIdle();
5121 EXPECT_TRUE(recorder.ready());
5122
5123 recorder.set_ready(false);
5124 profile.reset(new TestingProfile());
5125 profile->GetPrefs()->SetBoolean(prefs::kDisableExtensions, true);
5126 command_line.reset(new CommandLine(CommandLine::NO_PROGRAM));
5127 service = static_cast<extensions::TestExtensionSystem*>(
5128 ExtensionSystem::Get(profile.get()))->
5129 CreateExtensionService(
5130 command_line.get(),
5131 install_dir,
5132 false);
5133 EXPECT_FALSE(service->extensions_enabled());
5134 service->Init();
5135 base::RunLoop().RunUntilIdle();
5136 EXPECT_TRUE(recorder.ready());
5137
5138 // Explicitly delete all the resources used in this test.
5139 profile.reset();
5140 service = NULL;
5141 // Execute any pending deletion tasks.
5142 base::RunLoop().RunUntilIdle();
5143 }
5144
5145 // Test loading extensions that require limited and unlimited storage quotas.
TEST_F(ExtensionServiceTest,StorageQuota)5146 TEST_F(ExtensionServiceTest, StorageQuota) {
5147 InitializeEmptyExtensionService();
5148
5149 base::FilePath extensions_path = data_dir_
5150 .AppendASCII("storage_quota");
5151
5152 base::FilePath limited_quota_ext =
5153 extensions_path.AppendASCII("limited_quota")
5154 .AppendASCII("1.0");
5155
5156 // The old permission name for unlimited quota was "unlimited_storage", but
5157 // we changed it to "unlimitedStorage". This tests both versions.
5158 base::FilePath unlimited_quota_ext =
5159 extensions_path.AppendASCII("unlimited_quota")
5160 .AppendASCII("1.0");
5161 base::FilePath unlimited_quota_ext2 =
5162 extensions_path.AppendASCII("unlimited_quota")
5163 .AppendASCII("2.0");
5164 extensions::UnpackedInstaller::Create(service_)->Load(limited_quota_ext);
5165 extensions::UnpackedInstaller::Create(service_)->Load(unlimited_quota_ext);
5166 extensions::UnpackedInstaller::Create(service_)->Load(unlimited_quota_ext2);
5167 base::RunLoop().RunUntilIdle();
5168
5169 ASSERT_EQ(3u, loaded_.size());
5170 EXPECT_TRUE(profile_.get());
5171 EXPECT_FALSE(profile_->IsOffTheRecord());
5172 EXPECT_FALSE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5173 loaded_[0]->url()));
5174 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5175 loaded_[1]->url()));
5176 EXPECT_TRUE(profile_->GetExtensionSpecialStoragePolicy()->IsStorageUnlimited(
5177 loaded_[2]->url()));
5178 }
5179
5180 // Tests ComponentLoader::Add().
TEST_F(ExtensionServiceTest,ComponentExtensions)5181 TEST_F(ExtensionServiceTest, ComponentExtensions) {
5182 InitializeEmptyExtensionService();
5183
5184 // Component extensions should work even when extensions are disabled.
5185 set_extensions_enabled(false);
5186
5187 base::FilePath path = data_dir_
5188 .AppendASCII("good")
5189 .AppendASCII("Extensions")
5190 .AppendASCII("behllobkkfkfnphdnhnkndlbkcpglgmj")
5191 .AppendASCII("1.0.0.0");
5192
5193 std::string manifest;
5194 ASSERT_TRUE(base::ReadFileToString(
5195 path.Append(extensions::kManifestFilename), &manifest));
5196
5197 service_->component_loader()->Add(manifest, path);
5198 service_->Init();
5199
5200 // Note that we do not pump messages -- the extension should be loaded
5201 // immediately.
5202
5203 EXPECT_EQ(0u, GetErrors().size());
5204 ASSERT_EQ(1u, loaded_.size());
5205 EXPECT_EQ(Manifest::COMPONENT, loaded_[0]->location());
5206 EXPECT_EQ(1u, service_->extensions()->size());
5207
5208 // Component extensions get a prefs entry on first install.
5209 ValidatePrefKeyCount(1);
5210
5211 // Reload all extensions, and make sure it comes back.
5212 std::string extension_id = (*service_->extensions()->begin())->id();
5213 loaded_.clear();
5214 service_->ReloadExtensions();
5215 ASSERT_EQ(1u, service_->extensions()->size());
5216 EXPECT_EQ(extension_id, (*service_->extensions()->begin())->id());
5217 }
5218
5219 namespace {
5220
5221 class TestSyncProcessorStub : public syncer::SyncChangeProcessor {
ProcessSyncChanges(const tracked_objects::Location & from_here,const syncer::SyncChangeList & change_list)5222 virtual syncer::SyncError ProcessSyncChanges(
5223 const tracked_objects::Location& from_here,
5224 const syncer::SyncChangeList& change_list) OVERRIDE {
5225 return syncer::SyncError();
5226 }
5227
GetAllSyncData(syncer::ModelType type) const5228 virtual syncer::SyncDataList GetAllSyncData(
5229 syncer::ModelType type) const OVERRIDE {
5230 return syncer::SyncDataList();
5231 }
5232 };
5233
5234 } // namespace
5235
TEST_F(ExtensionServiceTest,DeferredSyncStartupPreInstalledComponent)5236 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledComponent) {
5237 InitializeEmptyExtensionService();
5238 InitializeExtensionSyncService();
5239
5240 bool flare_was_called = false;
5241 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5242 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5243 extension_sync_service_->SetSyncStartFlare(
5244 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5245 factory.GetWeakPtr(),
5246 &flare_was_called, // Safe due to WeakPtrFactory scope.
5247 &triggered_type)); // Safe due to WeakPtrFactory scope.
5248
5249 // Install a component extension.
5250 std::string manifest;
5251 ASSERT_TRUE(base::ReadFileToString(
5252 good0_path().Append(extensions::kManifestFilename), &manifest));
5253 service_->component_loader()->Add(manifest, good0_path());
5254 ASSERT_FALSE(service_->is_ready());
5255 service_->Init();
5256 ASSERT_TRUE(service_->is_ready());
5257
5258 // Extensions added before service is_ready() don't trigger sync startup.
5259 EXPECT_FALSE(flare_was_called);
5260 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5261 }
5262
TEST_F(ExtensionServiceTest,DeferredSyncStartupPreInstalledNormal)5263 TEST_F(ExtensionServiceTest, DeferredSyncStartupPreInstalledNormal) {
5264 InitializeGoodInstalledExtensionService();
5265 InitializeExtensionSyncService();
5266
5267 bool flare_was_called = false;
5268 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5269 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5270 extension_sync_service_->SetSyncStartFlare(
5271 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5272 factory.GetWeakPtr(),
5273 &flare_was_called, // Safe due to WeakPtrFactory scope.
5274 &triggered_type)); // Safe due to WeakPtrFactory scope.
5275
5276 ASSERT_FALSE(service_->is_ready());
5277 service_->Init();
5278 ASSERT_EQ(3u, loaded_.size());
5279 ASSERT_TRUE(service_->is_ready());
5280
5281 // Extensions added before service is_ready() don't trigger sync startup.
5282 EXPECT_FALSE(flare_was_called);
5283 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5284 }
5285
TEST_F(ExtensionServiceTest,DeferredSyncStartupOnInstall)5286 TEST_F(ExtensionServiceTest, DeferredSyncStartupOnInstall) {
5287 InitializeEmptyExtensionService();
5288 InitializeExtensionSyncService();
5289 service_->Init();
5290 ASSERT_TRUE(service_->is_ready());
5291
5292 bool flare_was_called = false;
5293 syncer::ModelType triggered_type(syncer::UNSPECIFIED);
5294 base::WeakPtrFactory<ExtensionServiceTest> factory(this);
5295 extension_sync_service_->SetSyncStartFlare(
5296 base::Bind(&ExtensionServiceTest::MockSyncStartFlare,
5297 factory.GetWeakPtr(),
5298 &flare_was_called, // Safe due to WeakPtrFactory scope.
5299 &triggered_type)); // Safe due to WeakPtrFactory scope.
5300
5301 base::FilePath path = data_dir_.AppendASCII("good.crx");
5302 InstallCRX(path, INSTALL_NEW);
5303
5304 EXPECT_TRUE(flare_was_called);
5305 EXPECT_EQ(syncer::EXTENSIONS, triggered_type);
5306
5307 // Reset.
5308 flare_was_called = false;
5309 triggered_type = syncer::UNSPECIFIED;
5310
5311 // Once sync starts, flare should no longer be invoked.
5312 extension_sync_service_->MergeDataAndStartSyncing(
5313 syncer::EXTENSIONS, syncer::SyncDataList(),
5314 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5315 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5316 path = data_dir_.AppendASCII("page_action.crx");
5317 InstallCRX(path, INSTALL_NEW);
5318 EXPECT_FALSE(flare_was_called);
5319 ASSERT_EQ(syncer::UNSPECIFIED, triggered_type);
5320 }
5321
TEST_F(ExtensionServiceTest,DisableExtensionFromSync)5322 TEST_F(ExtensionServiceTest, DisableExtensionFromSync) {
5323 // Start the extensions service with one external extension already installed.
5324 base::FilePath source_install_dir = data_dir_
5325 .AppendASCII("good")
5326 .AppendASCII("Extensions");
5327 base::FilePath pref_path = source_install_dir
5328 .DirName()
5329 .AppendASCII("Preferences");
5330
5331 InitializeInstalledExtensionService(pref_path, source_install_dir);
5332 InitializeExtensionSyncService();
5333
5334 // The user has enabled sync.
5335 ProfileSyncService* sync_service =
5336 ProfileSyncServiceFactory::GetForProfile(profile_.get());
5337 sync_service->SetSyncSetupCompleted();
5338
5339 service_->Init();
5340 ASSERT_TRUE(service_->is_ready());
5341
5342 ASSERT_EQ(3u, loaded_.size());
5343
5344 // We start enabled.
5345 const Extension* extension = service_->GetExtensionById(good0, true);
5346 ASSERT_TRUE(extension);
5347 ASSERT_TRUE(service_->IsExtensionEnabled(good0));
5348 extensions::ExtensionSyncData disable_good_crx(*extension, false, false);
5349
5350 // Then sync data arrives telling us to disable |good0|.
5351 syncer::SyncDataList sync_data;
5352 sync_data.push_back(disable_good_crx.GetSyncData());
5353 extension_sync_service_->MergeDataAndStartSyncing(
5354 syncer::EXTENSIONS, sync_data,
5355 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5356 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5357 ASSERT_FALSE(service_->IsExtensionEnabled(good0));
5358 }
5359
TEST_F(ExtensionServiceTest,DontDisableExtensionWithPendingEnableFromSync)5360 TEST_F(ExtensionServiceTest, DontDisableExtensionWithPendingEnableFromSync) {
5361 // Start the extensions service with one external extension already installed.
5362 base::FilePath source_install_dir = data_dir_
5363 .AppendASCII("good")
5364 .AppendASCII("Extensions");
5365 base::FilePath pref_path = source_install_dir
5366 .DirName()
5367 .AppendASCII("Preferences");
5368
5369 InitializeInstalledExtensionService(pref_path, source_install_dir);
5370 InitializeExtensionSyncService();
5371
5372 // The user has enabled sync.
5373 ProfileSyncService* sync_service =
5374 ProfileSyncServiceFactory::GetForProfile(profile_.get());
5375 sync_service->SetSyncSetupCompleted();
5376
5377 service_->Init();
5378 ASSERT_TRUE(service_->is_ready());
5379 ASSERT_EQ(3u, loaded_.size());
5380
5381 const Extension* extension = service_->GetExtensionById(good0, true);
5382 ASSERT_TRUE(service_->IsExtensionEnabled(good0));
5383
5384 // Disable extension before first sync data arrives.
5385 service_->DisableExtension(good0, Extension::DISABLE_USER_ACTION);
5386 ASSERT_FALSE(service_->IsExtensionEnabled(good0));
5387
5388 // Enable extension - this is now the most recent state.
5389 service_->EnableExtension(good0);
5390 ASSERT_TRUE(service_->IsExtensionEnabled(good0));
5391
5392 // Now sync data comes in that says to disable good0. This should be
5393 // ignored.
5394 extensions::ExtensionSyncData disable_good_crx(*extension, false, false);
5395 syncer::SyncDataList sync_data;
5396 sync_data.push_back(disable_good_crx.GetSyncData());
5397 extension_sync_service_->MergeDataAndStartSyncing(
5398 syncer::EXTENSIONS, sync_data,
5399 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5400 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5401
5402 // The extension was enabled locally before the sync data arrived, so it
5403 // should still be enabled now.
5404 ASSERT_TRUE(service_->IsExtensionEnabled(good0));
5405 }
5406
TEST_F(ExtensionServiceTest,GetSyncData)5407 TEST_F(ExtensionServiceTest, GetSyncData) {
5408 InitializeEmptyExtensionService();
5409 InitializeExtensionSyncService();
5410 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5411 const Extension* extension = service_->GetInstalledExtension(good_crx);
5412 ASSERT_TRUE(extension);
5413
5414 extension_sync_service_->MergeDataAndStartSyncing(
5415 syncer::EXTENSIONS, syncer::SyncDataList(),
5416 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5417 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5418
5419 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5420 syncer::EXTENSIONS);
5421 ASSERT_EQ(list.size(), 1U);
5422 extensions::ExtensionSyncData data(list[0]);
5423 EXPECT_EQ(extension->id(), data.id());
5424 EXPECT_FALSE(data.uninstalled());
5425 EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
5426 EXPECT_EQ(extension_util::IsIncognitoEnabled(good_crx, service_),
5427 data.incognito_enabled());
5428 EXPECT_TRUE(data.version().Equals(*extension->version()));
5429 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
5430 data.update_url());
5431 EXPECT_EQ(extension->name(), data.name());
5432 }
5433
TEST_F(ExtensionServiceTest,GetSyncDataTerminated)5434 TEST_F(ExtensionServiceTest, GetSyncDataTerminated) {
5435 InitializeEmptyExtensionService();
5436 InitializeExtensionSyncService();
5437 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5438 TerminateExtension(good_crx);
5439 const Extension* extension = service_->GetInstalledExtension(good_crx);
5440 ASSERT_TRUE(extension);
5441
5442 TestSyncProcessorStub processor;
5443 extension_sync_service_->MergeDataAndStartSyncing(
5444 syncer::EXTENSIONS, syncer::SyncDataList(),
5445 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5446 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5447
5448 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5449 syncer::EXTENSIONS);
5450 ASSERT_EQ(list.size(), 1U);
5451 extensions::ExtensionSyncData data(list[0]);
5452 EXPECT_EQ(extension->id(), data.id());
5453 EXPECT_FALSE(data.uninstalled());
5454 EXPECT_EQ(service_->IsExtensionEnabled(good_crx), data.enabled());
5455 EXPECT_EQ(extension_util::IsIncognitoEnabled(good_crx, service_),
5456 data.incognito_enabled());
5457 EXPECT_TRUE(data.version().Equals(*extension->version()));
5458 EXPECT_EQ(extensions::ManifestURL::GetUpdateURL(extension),
5459 data.update_url());
5460 EXPECT_EQ(extension->name(), data.name());
5461 }
5462
TEST_F(ExtensionServiceTest,GetSyncDataFilter)5463 TEST_F(ExtensionServiceTest, GetSyncDataFilter) {
5464 InitializeEmptyExtensionService();
5465 InitializeExtensionSyncService();
5466 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5467 const Extension* extension = service_->GetInstalledExtension(good_crx);
5468 ASSERT_TRUE(extension);
5469
5470 TestSyncProcessorStub processor;
5471 extension_sync_service_->MergeDataAndStartSyncing(syncer::APPS,
5472 syncer::SyncDataList(),
5473 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5474 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5475
5476 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5477 syncer::EXTENSIONS);
5478 ASSERT_EQ(list.size(), 0U);
5479 }
5480
TEST_F(ExtensionServiceTest,GetSyncExtensionDataUserSettings)5481 TEST_F(ExtensionServiceTest, GetSyncExtensionDataUserSettings) {
5482 InitializeEmptyExtensionService();
5483 InitializeProcessManager();
5484 InitializeExtensionSyncService();
5485 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5486 const Extension* extension = service_->GetInstalledExtension(good_crx);
5487 ASSERT_TRUE(extension);
5488
5489 TestSyncProcessorStub processor;
5490 extension_sync_service_->MergeDataAndStartSyncing(
5491 syncer::EXTENSIONS, syncer::SyncDataList(),
5492 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5493 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5494
5495 {
5496 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5497 syncer::EXTENSIONS);
5498 ASSERT_EQ(list.size(), 1U);
5499 extensions::ExtensionSyncData data(list[0]);
5500 EXPECT_TRUE(data.enabled());
5501 EXPECT_FALSE(data.incognito_enabled());
5502 }
5503
5504 service_->DisableExtension(good_crx, Extension::DISABLE_USER_ACTION);
5505 {
5506 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5507 syncer::EXTENSIONS);
5508 ASSERT_EQ(list.size(), 1U);
5509 extensions::ExtensionSyncData data(list[0]);
5510 EXPECT_FALSE(data.enabled());
5511 EXPECT_FALSE(data.incognito_enabled());
5512 }
5513
5514 extension_util::SetIsIncognitoEnabled(good_crx, service_, true);
5515 {
5516 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5517 syncer::EXTENSIONS);
5518 ASSERT_EQ(list.size(), 1U);
5519 extensions::ExtensionSyncData data(list[0]);
5520 EXPECT_FALSE(data.enabled());
5521 EXPECT_TRUE(data.incognito_enabled());
5522 }
5523
5524 service_->EnableExtension(good_crx);
5525 {
5526 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5527 syncer::EXTENSIONS);
5528 ASSERT_EQ(list.size(), 1U);
5529 extensions::ExtensionSyncData data(list[0]);
5530 EXPECT_TRUE(data.enabled());
5531 EXPECT_TRUE(data.incognito_enabled());
5532 }
5533 }
5534
TEST_F(ExtensionServiceTest,SyncForUninstalledExternalExtension)5535 TEST_F(ExtensionServiceTest, SyncForUninstalledExternalExtension) {
5536 InitializeEmptyExtensionService();
5537 InitializeExtensionSyncService();
5538 InstallCRXWithLocation(data_dir_.AppendASCII("good.crx"),
5539 Manifest::EXTERNAL_PREF, INSTALL_NEW);
5540 const Extension* extension = service_->GetInstalledExtension(good_crx);
5541 ASSERT_TRUE(extension);
5542
5543 TestSyncProcessorStub processor;
5544 extension_sync_service_->MergeDataAndStartSyncing(
5545 syncer::EXTENSIONS, syncer::SyncDataList(),
5546 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5547 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5548
5549 UninstallExtension(good_crx, false);
5550 EXPECT_TRUE(service_->IsExternalExtensionUninstalled(good_crx));
5551
5552 sync_pb::EntitySpecifics specifics;
5553 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
5554 sync_pb::ExtensionSpecifics* extension_specifics =
5555 app_specifics->mutable_extension();
5556 extension_specifics->set_id(good_crx);
5557 extension_specifics->set_version("1.0");
5558 extension_specifics->set_enabled(true);
5559
5560 syncer::SyncData sync_data =
5561 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5562 syncer::SyncChange sync_change(FROM_HERE,
5563 syncer::SyncChange::ACTION_UPDATE,
5564 sync_data);
5565 syncer::SyncChangeList list(1);
5566 list[0] = sync_change;
5567
5568 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5569 EXPECT_TRUE(service_->IsExternalExtensionUninstalled(good_crx));
5570 }
5571
TEST_F(ExtensionServiceTest,GetSyncAppDataUserSettings)5572 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettings) {
5573 InitializeEmptyExtensionService();
5574 InitializeExtensionSyncService();
5575 const Extension* app =
5576 PackAndInstallCRX(data_dir_.AppendASCII("app"), INSTALL_NEW);
5577 ASSERT_TRUE(app);
5578 ASSERT_TRUE(app->is_app());
5579
5580 TestSyncProcessorStub processor;
5581 extension_sync_service_->MergeDataAndStartSyncing(syncer::APPS,
5582 syncer::SyncDataList(),
5583 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5584 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5585
5586 syncer::StringOrdinal initial_ordinal =
5587 syncer::StringOrdinal::CreateInitialOrdinal();
5588 {
5589 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5590 syncer::APPS);
5591 ASSERT_EQ(list.size(), 1U);
5592
5593 extensions::AppSyncData app_sync_data(list[0]);
5594 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.app_launch_ordinal()));
5595 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
5596 }
5597
5598 AppSorting* sorting = service_->extension_prefs()->app_sorting();
5599 sorting->SetAppLaunchOrdinal(app->id(), initial_ordinal.CreateAfter());
5600 {
5601 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5602 syncer::APPS);
5603 ASSERT_EQ(list.size(), 1U);
5604
5605 extensions::AppSyncData app_sync_data(list[0]);
5606 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
5607 EXPECT_TRUE(initial_ordinal.Equals(app_sync_data.page_ordinal()));
5608 }
5609
5610 sorting->SetPageOrdinal(app->id(), initial_ordinal.CreateAfter());
5611 {
5612 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5613 syncer::APPS);
5614 ASSERT_EQ(list.size(), 1U);
5615
5616 extensions::AppSyncData app_sync_data(list[0]);
5617 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.app_launch_ordinal()));
5618 EXPECT_TRUE(initial_ordinal.LessThan(app_sync_data.page_ordinal()));
5619 }
5620 }
5621
TEST_F(ExtensionServiceTest,GetSyncAppDataUserSettingsOnExtensionMoved)5622 TEST_F(ExtensionServiceTest, GetSyncAppDataUserSettingsOnExtensionMoved) {
5623 InitializeEmptyExtensionService();
5624 InitializeExtensionSyncService();
5625 const size_t kAppCount = 3;
5626 const Extension* apps[kAppCount];
5627 apps[0] = PackAndInstallCRX(data_dir_.AppendASCII("app1"), INSTALL_NEW);
5628 apps[1] = PackAndInstallCRX(data_dir_.AppendASCII("app2"), INSTALL_NEW);
5629 apps[2] = PackAndInstallCRX(data_dir_.AppendASCII("app4"), INSTALL_NEW);
5630 for (size_t i = 0; i < kAppCount; ++i) {
5631 ASSERT_TRUE(apps[i]);
5632 ASSERT_TRUE(apps[i]->is_app());
5633 }
5634
5635 TestSyncProcessorStub processor;
5636 extension_sync_service_->MergeDataAndStartSyncing(syncer::APPS,
5637 syncer::SyncDataList(),
5638 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5639 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5640
5641 service_->OnExtensionMoved(apps[0]->id(), apps[1]->id(), apps[2]->id());
5642 {
5643 syncer::SyncDataList list = extension_sync_service_->GetAllSyncData(
5644 syncer::APPS);
5645 ASSERT_EQ(list.size(), 3U);
5646
5647 extensions::AppSyncData data[kAppCount];
5648 for (size_t i = 0; i < kAppCount; ++i) {
5649 data[i] = extensions::AppSyncData(list[i]);
5650 }
5651
5652 // The sync data is not always in the same order our apps were installed in,
5653 // so we do that sorting here so we can make sure the values are changed as
5654 // expected.
5655 syncer::StringOrdinal app_launch_ordinals[kAppCount];
5656 for (size_t i = 0; i < kAppCount; ++i) {
5657 for (size_t j = 0; j < kAppCount; ++j) {
5658 if (apps[i]->id() == data[j].id())
5659 app_launch_ordinals[i] = data[j].app_launch_ordinal();
5660 }
5661 }
5662
5663 EXPECT_TRUE(app_launch_ordinals[1].LessThan(app_launch_ordinals[0]));
5664 EXPECT_TRUE(app_launch_ordinals[0].LessThan(app_launch_ordinals[2]));
5665 }
5666 }
5667
TEST_F(ExtensionServiceTest,GetSyncDataList)5668 TEST_F(ExtensionServiceTest, GetSyncDataList) {
5669 InitializeEmptyExtensionService();
5670 InitializeExtensionSyncService();
5671 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5672 InstallCRX(data_dir_.AppendASCII("page_action.crx"), INSTALL_NEW);
5673 InstallCRX(data_dir_.AppendASCII("theme.crx"), INSTALL_NEW);
5674 InstallCRX(data_dir_.AppendASCII("theme2.crx"), INSTALL_NEW);
5675
5676 TestSyncProcessorStub processor;
5677 extension_sync_service_->MergeDataAndStartSyncing(
5678 syncer::APPS, syncer::SyncDataList(),
5679 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5680 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5681 extension_sync_service_->MergeDataAndStartSyncing(
5682 syncer::EXTENSIONS, syncer::SyncDataList(),
5683 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5684 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5685
5686 service_->DisableExtension(page_action, Extension::DISABLE_USER_ACTION);
5687 TerminateExtension(theme2_crx);
5688
5689 EXPECT_EQ(0u, extension_sync_service_->GetAllSyncData(syncer::APPS).size());
5690 EXPECT_EQ(2u, extension_sync_service_->
5691 GetAllSyncData(syncer::EXTENSIONS).size());
5692 }
5693
TEST_F(ExtensionServiceTest,ProcessSyncDataUninstall)5694 TEST_F(ExtensionServiceTest, ProcessSyncDataUninstall) {
5695 InitializeEmptyExtensionService();
5696 InitializeExtensionSyncService();
5697 TestSyncProcessorStub processor;
5698 extension_sync_service_->MergeDataAndStartSyncing(
5699 syncer::EXTENSIONS, syncer::SyncDataList(),
5700 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5701 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5702
5703 sync_pb::EntitySpecifics specifics;
5704 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5705 ext_specifics->set_id(good_crx);
5706 ext_specifics->set_version("1.0");
5707 syncer::SyncData sync_data =
5708 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5709 syncer::SyncChange sync_change(FROM_HERE,
5710 syncer::SyncChange::ACTION_DELETE,
5711 sync_data);
5712 syncer::SyncChangeList list(1);
5713 list[0] = sync_change;
5714
5715 // Should do nothing.
5716 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5717 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
5718
5719 // Install the extension.
5720 base::FilePath extension_path = data_dir_.AppendASCII("good.crx");
5721 InstallCRX(extension_path, INSTALL_NEW);
5722 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
5723
5724 // Should uninstall the extension.
5725 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5726 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
5727
5728 // Should again do nothing.
5729 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5730 EXPECT_FALSE(service_->GetExtensionById(good_crx, true));
5731 }
5732
TEST_F(ExtensionServiceTest,ProcessSyncDataWrongType)5733 TEST_F(ExtensionServiceTest, ProcessSyncDataWrongType) {
5734 InitializeEmptyExtensionService();
5735 InitializeExtensionSyncService();
5736
5737 // Install the extension.
5738 base::FilePath extension_path = data_dir_.AppendASCII("good.crx");
5739 InstallCRX(extension_path, INSTALL_NEW);
5740 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
5741
5742 sync_pb::EntitySpecifics specifics;
5743 sync_pb::AppSpecifics* app_specifics = specifics.mutable_app();
5744 sync_pb::ExtensionSpecifics* extension_specifics =
5745 app_specifics->mutable_extension();
5746 extension_specifics->set_id(good_crx);
5747 extension_specifics->set_version(
5748 service_->GetInstalledExtension(good_crx)->version()->GetString());
5749
5750 {
5751 extension_specifics->set_enabled(true);
5752 syncer::SyncData sync_data =
5753 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5754 syncer::SyncChange sync_change(FROM_HERE,
5755 syncer::SyncChange::ACTION_DELETE,
5756 sync_data);
5757 syncer::SyncChangeList list(1);
5758 list[0] = sync_change;
5759
5760 // Should do nothing
5761 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5762 EXPECT_TRUE(service_->GetExtensionById(good_crx, true));
5763 }
5764
5765 {
5766 extension_specifics->set_enabled(false);
5767 syncer::SyncData sync_data =
5768 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5769 syncer::SyncChange sync_change(FROM_HERE,
5770 syncer::SyncChange::ACTION_UPDATE,
5771 sync_data);
5772 syncer::SyncChangeList list(1);
5773 list[0] = sync_change;
5774
5775 // Should again do nothing.
5776 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5777 EXPECT_TRUE(service_->GetExtensionById(good_crx, false));
5778 }
5779 }
5780
TEST_F(ExtensionServiceTest,ProcessSyncDataSettings)5781 TEST_F(ExtensionServiceTest, ProcessSyncDataSettings) {
5782 InitializeEmptyExtensionService();
5783 InitializeProcessManager();
5784 InitializeExtensionSyncService();
5785 TestSyncProcessorStub processor;
5786 extension_sync_service_->MergeDataAndStartSyncing(
5787 syncer::EXTENSIONS, syncer::SyncDataList(),
5788 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5789 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5790
5791 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5792 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5793 EXPECT_FALSE(extension_util::IsIncognitoEnabled(good_crx, service_));
5794
5795 sync_pb::EntitySpecifics specifics;
5796 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5797 ext_specifics->set_id(good_crx);
5798 ext_specifics->set_version(
5799 service_->GetInstalledExtension(good_crx)->version()->GetString());
5800 ext_specifics->set_enabled(false);
5801
5802 {
5803 syncer::SyncData sync_data =
5804 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5805 syncer::SyncChange sync_change(FROM_HERE,
5806 syncer::SyncChange::ACTION_UPDATE,
5807 sync_data);
5808 syncer::SyncChangeList list(1);
5809 list[0] = sync_change;
5810 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5811 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5812 EXPECT_FALSE(extension_util::IsIncognitoEnabled(good_crx, service_));
5813 }
5814
5815 {
5816 ext_specifics->set_enabled(true);
5817 ext_specifics->set_incognito_enabled(true);
5818 syncer::SyncData sync_data =
5819 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5820 syncer::SyncChange sync_change(FROM_HERE,
5821 syncer::SyncChange::ACTION_UPDATE,
5822 sync_data);
5823 syncer::SyncChangeList list(1);
5824 list[0] = sync_change;
5825 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5826 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5827 EXPECT_TRUE(extension_util::IsIncognitoEnabled(good_crx, service_));
5828 }
5829
5830 {
5831 ext_specifics->set_enabled(false);
5832 ext_specifics->set_incognito_enabled(true);
5833 syncer::SyncData sync_data =
5834 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5835 syncer::SyncChange sync_change(FROM_HERE,
5836 syncer::SyncChange::ACTION_UPDATE,
5837 sync_data);
5838 syncer::SyncChangeList list(1);
5839 list[0] = sync_change;
5840 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5841 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5842 EXPECT_TRUE(extension_util::IsIncognitoEnabled(good_crx, service_));
5843 }
5844
5845 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5846 }
5847
TEST_F(ExtensionServiceTest,ProcessSyncDataTerminatedExtension)5848 TEST_F(ExtensionServiceTest, ProcessSyncDataTerminatedExtension) {
5849 InitializeExtensionServiceWithUpdater();
5850 InitializeExtensionSyncService();
5851 TestSyncProcessorStub processor;
5852 extension_sync_service_->MergeDataAndStartSyncing(
5853 syncer::EXTENSIONS, syncer::SyncDataList(),
5854 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5855 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5856
5857 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5858 TerminateExtension(good_crx);
5859 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5860 EXPECT_FALSE(extension_util::IsIncognitoEnabled(good_crx, service_));
5861
5862 sync_pb::EntitySpecifics specifics;
5863 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5864 ext_specifics->set_id(good_crx);
5865 ext_specifics->set_version(
5866 service_->GetInstalledExtension(good_crx)->version()->GetString());
5867 ext_specifics->set_enabled(false);
5868 ext_specifics->set_incognito_enabled(true);
5869 syncer::SyncData sync_data =
5870 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5871 syncer::SyncChange sync_change(FROM_HERE,
5872 syncer::SyncChange::ACTION_UPDATE,
5873 sync_data);
5874 syncer::SyncChangeList list(1);
5875 list[0] = sync_change;
5876
5877 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5878 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5879 EXPECT_TRUE(extension_util::IsIncognitoEnabled(good_crx, service_));
5880
5881 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5882 }
5883
TEST_F(ExtensionServiceTest,ProcessSyncDataVersionCheck)5884 TEST_F(ExtensionServiceTest, ProcessSyncDataVersionCheck) {
5885 InitializeExtensionServiceWithUpdater();
5886 InitializeExtensionSyncService();
5887 TestSyncProcessorStub processor;
5888 extension_sync_service_->MergeDataAndStartSyncing(
5889 syncer::EXTENSIONS, syncer::SyncDataList(),
5890 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5891 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5892
5893 InstallCRX(data_dir_.AppendASCII("good.crx"), INSTALL_NEW);
5894 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5895 EXPECT_FALSE(extension_util::IsIncognitoEnabled(good_crx, service_));
5896
5897 sync_pb::EntitySpecifics specifics;
5898 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5899 ext_specifics->set_id(good_crx);
5900 ext_specifics->set_enabled(true);
5901
5902 {
5903 ext_specifics->set_version(
5904 service_->GetInstalledExtension(good_crx)->version()->GetString());
5905 syncer::SyncData sync_data =
5906 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5907 syncer::SyncChange sync_change(FROM_HERE,
5908 syncer::SyncChange::ACTION_UPDATE,
5909 sync_data);
5910 syncer::SyncChangeList list(1);
5911 list[0] = sync_change;
5912
5913 // Should do nothing if extension version == sync version.
5914 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5915 EXPECT_FALSE(service_->updater()->WillCheckSoon());
5916 }
5917
5918 // Should do nothing if extension version > sync version (but see
5919 // the TODO in ProcessExtensionSyncData).
5920 {
5921 ext_specifics->set_version("0.0.0.0");
5922 syncer::SyncData sync_data =
5923 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5924 syncer::SyncChange sync_change(FROM_HERE,
5925 syncer::SyncChange::ACTION_UPDATE,
5926 sync_data);
5927 syncer::SyncChangeList list(1);
5928 list[0] = sync_change;
5929
5930 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5931 EXPECT_FALSE(service_->updater()->WillCheckSoon());
5932 }
5933
5934 // Should kick off an update if extension version < sync version.
5935 {
5936 ext_specifics->set_version("9.9.9.9");
5937 syncer::SyncData sync_data =
5938 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5939 syncer::SyncChange sync_change(FROM_HERE,
5940 syncer::SyncChange::ACTION_UPDATE,
5941 sync_data);
5942 syncer::SyncChangeList list(1);
5943 list[0] = sync_change;
5944
5945 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5946 EXPECT_TRUE(service_->updater()->WillCheckSoon());
5947 }
5948
5949 EXPECT_FALSE(service_->pending_extension_manager()->IsIdPending(good_crx));
5950 }
5951
TEST_F(ExtensionServiceTest,ProcessSyncDataNotInstalled)5952 TEST_F(ExtensionServiceTest, ProcessSyncDataNotInstalled) {
5953 InitializeExtensionServiceWithUpdater();
5954 InitializeExtensionSyncService();
5955 TestSyncProcessorStub processor;
5956 extension_sync_service_->MergeDataAndStartSyncing(
5957 syncer::EXTENSIONS, syncer::SyncDataList(),
5958 scoped_ptr<syncer::SyncChangeProcessor>(new TestSyncProcessorStub),
5959 scoped_ptr<syncer::SyncErrorFactory>(new syncer::SyncErrorFactoryMock()));
5960
5961 sync_pb::EntitySpecifics specifics;
5962 sync_pb::ExtensionSpecifics* ext_specifics = specifics.mutable_extension();
5963 ext_specifics->set_id(good_crx);
5964 ext_specifics->set_enabled(false);
5965 ext_specifics->set_incognito_enabled(true);
5966 ext_specifics->set_update_url("http://www.google.com/");
5967 ext_specifics->set_version("1.2.3.4");
5968 syncer::SyncData sync_data =
5969 syncer::SyncData::CreateLocalData(good_crx, "Name", specifics);
5970 syncer::SyncChange sync_change(FROM_HERE,
5971 syncer::SyncChange::ACTION_UPDATE,
5972 sync_data);
5973 syncer::SyncChangeList list(1);
5974 list[0] = sync_change;
5975
5976
5977 EXPECT_TRUE(service_->IsExtensionEnabled(good_crx));
5978 EXPECT_FALSE(extension_util::IsIncognitoEnabled(good_crx, service_));
5979 extension_sync_service_->ProcessSyncChanges(FROM_HERE, list);
5980 EXPECT_TRUE(service_->updater()->WillCheckSoon());
5981 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
5982 EXPECT_TRUE(extension_util::IsIncognitoEnabled(good_crx, service_));
5983
5984 const extensions::PendingExtensionInfo* info;
5985 EXPECT_TRUE((info = service_->pending_extension_manager()->
5986 GetById(good_crx)));
5987 EXPECT_EQ(ext_specifics->update_url(), info->update_url().spec());
5988 EXPECT_TRUE(info->is_from_sync());
5989 EXPECT_TRUE(info->install_silently());
5990 EXPECT_EQ(Manifest::INTERNAL, info->install_source());
5991 // TODO(akalin): Figure out a way to test |info.ShouldAllowInstall()|.
5992 }
5993
TEST_F(ExtensionServiceTest,InstallPriorityExternalUpdateUrl)5994 TEST_F(ExtensionServiceTest, InstallPriorityExternalUpdateUrl) {
5995 InitializeEmptyExtensionService();
5996
5997 base::FilePath path = data_dir_.AppendASCII("good.crx");
5998 InstallCRX(path, INSTALL_NEW);
5999 ValidatePrefKeyCount(1u);
6000 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
6001 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
6002
6003 extensions::PendingExtensionManager* pending =
6004 service_->pending_extension_manager();
6005 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6006
6007 // Skip install when the location is the same.
6008 EXPECT_FALSE(
6009 service_->OnExternalExtensionUpdateUrlFound(
6010 kGoodId, GURL(kGoodUpdateURL), Manifest::INTERNAL,
6011 Extension::NO_FLAGS, false));
6012 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6013
6014 // Install when the location has higher priority.
6015 EXPECT_TRUE(
6016 service_->OnExternalExtensionUpdateUrlFound(
6017 kGoodId, GURL(kGoodUpdateURL), Manifest::EXTERNAL_POLICY_DOWNLOAD,
6018 Extension::NO_FLAGS, false));
6019 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6020
6021 // Try the low priority again. Should be rejected.
6022 EXPECT_FALSE(
6023 service_->OnExternalExtensionUpdateUrlFound(
6024 kGoodId, GURL(kGoodUpdateURL), Manifest::EXTERNAL_PREF_DOWNLOAD,
6025 Extension::NO_FLAGS, false));
6026 // The existing record should still be present in the pending extension
6027 // manager.
6028 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6029
6030 pending->Remove(kGoodId);
6031
6032 // Skip install when the location has the same priority as the installed
6033 // location.
6034 EXPECT_FALSE(service_->OnExternalExtensionUpdateUrlFound(
6035 kGoodId, GURL(kGoodUpdateURL), Manifest::INTERNAL,
6036 Extension::NO_FLAGS, false));
6037
6038 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6039 }
6040
TEST_F(ExtensionServiceTest,InstallPriorityExternalLocalFile)6041 TEST_F(ExtensionServiceTest, InstallPriorityExternalLocalFile) {
6042 Version older_version("0.1.0.0");
6043 Version newer_version("2.0.0.0");
6044
6045 // We don't want the extension to be installed. A path that doesn't
6046 // point to a valid CRX ensures this.
6047 const base::FilePath kInvalidPathToCrx = base::FilePath();
6048
6049 const int kCreationFlags = 0;
6050 const bool kDontMarkAcknowledged = false;
6051
6052 InitializeEmptyExtensionService();
6053
6054 // The test below uses install source constants to test that
6055 // priority is enforced. It assumes a specific ranking of install
6056 // sources: Registry (EXTERNAL_REGISTRY) overrides external pref
6057 // (EXTERNAL_PREF), and external pref overrides user install (INTERNAL).
6058 // The following assertions verify these assumptions:
6059 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
6060 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
6061 Manifest::EXTERNAL_PREF));
6062 ASSERT_EQ(Manifest::EXTERNAL_REGISTRY,
6063 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_REGISTRY,
6064 Manifest::INTERNAL));
6065 ASSERT_EQ(Manifest::EXTERNAL_PREF,
6066 Manifest::GetHigherPriorityLocation(Manifest::EXTERNAL_PREF,
6067 Manifest::INTERNAL));
6068
6069 extensions::PendingExtensionManager* pending =
6070 service_->pending_extension_manager();
6071 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6072
6073 {
6074 // Simulate an external source adding the extension as INTERNAL.
6075 content::WindowedNotificationObserver observer(
6076 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6077 content::NotificationService::AllSources());
6078 EXPECT_TRUE(
6079 service_->OnExternalExtensionFileFound(
6080 kGoodId, &older_version, kInvalidPathToCrx,
6081 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6082 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6083 observer.Wait();
6084 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6085 }
6086
6087 {
6088 // Simulate an external source adding the extension as EXTERNAL_PREF.
6089 content::WindowedNotificationObserver observer(
6090 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6091 content::NotificationService::AllSources());
6092 EXPECT_TRUE(
6093 service_->OnExternalExtensionFileFound(
6094 kGoodId, &older_version, kInvalidPathToCrx,
6095 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6096 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6097 observer.Wait();
6098 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6099 }
6100
6101 // Simulate an external source adding as EXTERNAL_PREF again.
6102 // This is rejected because the version and the location are the same as
6103 // the previous installation, which is still pending.
6104 EXPECT_FALSE(
6105 service_->OnExternalExtensionFileFound(
6106 kGoodId, &older_version, kInvalidPathToCrx,
6107 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6108 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6109
6110 // Try INTERNAL again. Should fail.
6111 EXPECT_FALSE(
6112 service_->OnExternalExtensionFileFound(
6113 kGoodId, &older_version, kInvalidPathToCrx,
6114 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6115 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6116
6117 {
6118 // Now the registry adds the extension.
6119 content::WindowedNotificationObserver observer(
6120 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6121 content::NotificationService::AllSources());
6122 EXPECT_TRUE(
6123 service_->OnExternalExtensionFileFound(kGoodId,
6124 &older_version,
6125 kInvalidPathToCrx,
6126 Manifest::EXTERNAL_REGISTRY,
6127 kCreationFlags,
6128 kDontMarkAcknowledged));
6129 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6130 observer.Wait();
6131 VerifyCrxInstall(kInvalidPathToCrx, INSTALL_FAILED);
6132 }
6133
6134 // Registry outranks both external pref and internal, so both fail.
6135 EXPECT_FALSE(
6136 service_->OnExternalExtensionFileFound(
6137 kGoodId, &older_version, kInvalidPathToCrx,
6138 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6139 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6140
6141 EXPECT_FALSE(
6142 service_->OnExternalExtensionFileFound(
6143 kGoodId, &older_version, kInvalidPathToCrx,
6144 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6145 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6146
6147 pending->Remove(kGoodId);
6148
6149 // Install the extension.
6150 base::FilePath path = data_dir_.AppendASCII("good.crx");
6151 const Extension* ext = InstallCRX(path, INSTALL_NEW);
6152 ValidatePrefKeyCount(1u);
6153 ValidateIntegerPref(good_crx, "state", Extension::ENABLED);
6154 ValidateIntegerPref(good_crx, "location", Manifest::INTERNAL);
6155
6156 // Now test the logic of OnExternalExtensionFileFound() when the extension
6157 // being added is already installed.
6158
6159 // Tests assume |older_version| is less than the installed version, and
6160 // |newer_version| is greater. Verify this:
6161 ASSERT_TRUE(older_version.IsOlderThan(ext->VersionString()));
6162 ASSERT_TRUE(ext->version()->IsOlderThan(newer_version.GetString()));
6163
6164 // An external install for the same location should fail if the version is
6165 // older, or the same, and succeed if the version is newer.
6166
6167 // Older than the installed version...
6168 EXPECT_FALSE(
6169 service_->OnExternalExtensionFileFound(
6170 kGoodId, &older_version, kInvalidPathToCrx,
6171 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6172 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6173
6174 // Same version as the installed version...
6175 EXPECT_FALSE(
6176 service_->OnExternalExtensionFileFound(
6177 kGoodId, ext->version(), kInvalidPathToCrx,
6178 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6179 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6180
6181 // Newer than the installed version...
6182 EXPECT_TRUE(
6183 service_->OnExternalExtensionFileFound(
6184 kGoodId, &newer_version, kInvalidPathToCrx,
6185 Manifest::INTERNAL, kCreationFlags, kDontMarkAcknowledged));
6186 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6187
6188 // An external install for a higher priority install source should succeed
6189 // if the version is greater. |older_version| is not...
6190 EXPECT_FALSE(
6191 service_->OnExternalExtensionFileFound(
6192 kGoodId, &older_version, kInvalidPathToCrx,
6193 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6194 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6195
6196 // |newer_version| is newer.
6197 EXPECT_TRUE(
6198 service_->OnExternalExtensionFileFound(
6199 kGoodId, &newer_version, kInvalidPathToCrx,
6200 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6201 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6202
6203 // An external install for an even higher priority install source should
6204 // succeed if the version is greater.
6205 EXPECT_TRUE(
6206 service_->OnExternalExtensionFileFound(
6207 kGoodId, &newer_version, kInvalidPathToCrx,
6208 Manifest::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
6209 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6210
6211 // Because EXTERNAL_PREF is a lower priority source than EXTERNAL_REGISTRY,
6212 // adding from external pref will now fail.
6213 EXPECT_FALSE(
6214 service_->OnExternalExtensionFileFound(
6215 kGoodId, &newer_version, kInvalidPathToCrx,
6216 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6217 EXPECT_TRUE(pending->IsIdPending(kGoodId));
6218 }
6219
TEST_F(ExtensionServiceTest,ConcurrentExternalLocalFile)6220 TEST_F(ExtensionServiceTest, ConcurrentExternalLocalFile) {
6221 Version kVersion123("1.2.3");
6222 Version kVersion124("1.2.4");
6223 Version kVersion125("1.2.5");
6224 const base::FilePath kInvalidPathToCrx = base::FilePath();
6225 const int kCreationFlags = 0;
6226 const bool kDontMarkAcknowledged = false;
6227
6228 InitializeEmptyExtensionService();
6229
6230 extensions::PendingExtensionManager* pending =
6231 service_->pending_extension_manager();
6232 EXPECT_FALSE(pending->IsIdPending(kGoodId));
6233
6234 // An external provider starts installing from a local crx.
6235 EXPECT_TRUE(
6236 service_->OnExternalExtensionFileFound(
6237 kGoodId, &kVersion123, kInvalidPathToCrx,
6238 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6239 const extensions::PendingExtensionInfo* info;
6240 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6241 EXPECT_TRUE(info->version().IsValid());
6242 EXPECT_TRUE(info->version().Equals(kVersion123));
6243
6244 // Adding a newer version overrides the currently pending version.
6245 EXPECT_TRUE(
6246 service_->OnExternalExtensionFileFound(
6247 kGoodId, &kVersion124, kInvalidPathToCrx,
6248 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6249 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6250 EXPECT_TRUE(info->version().IsValid());
6251 EXPECT_TRUE(info->version().Equals(kVersion124));
6252
6253 // Adding an older version fails.
6254 EXPECT_FALSE(
6255 service_->OnExternalExtensionFileFound(
6256 kGoodId, &kVersion123, kInvalidPathToCrx,
6257 Manifest::EXTERNAL_PREF, kCreationFlags, kDontMarkAcknowledged));
6258 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6259 EXPECT_TRUE(info->version().IsValid());
6260 EXPECT_TRUE(info->version().Equals(kVersion124));
6261
6262 // Adding an older version fails even when coming from a higher-priority
6263 // location.
6264 EXPECT_FALSE(
6265 service_->OnExternalExtensionFileFound(
6266 kGoodId, &kVersion123, kInvalidPathToCrx,
6267 Manifest::EXTERNAL_REGISTRY, kCreationFlags, kDontMarkAcknowledged));
6268 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6269 EXPECT_TRUE(info->version().IsValid());
6270 EXPECT_TRUE(info->version().Equals(kVersion124));
6271
6272 // Adding the latest version from the webstore overrides a specific version.
6273 GURL kUpdateUrl("http://example.com/update");
6274 EXPECT_TRUE(
6275 service_->OnExternalExtensionUpdateUrlFound(
6276 kGoodId, kUpdateUrl, Manifest::EXTERNAL_POLICY_DOWNLOAD,
6277 Extension::NO_FLAGS, false));
6278 EXPECT_TRUE((info = pending->GetById(kGoodId)));
6279 EXPECT_FALSE(info->version().IsValid());
6280 }
6281
6282 // This makes sure we can package and install CRX files that use whitelisted
6283 // permissions.
TEST_F(ExtensionServiceTest,InstallWhitelistedExtension)6284 TEST_F(ExtensionServiceTest, InstallWhitelistedExtension) {
6285 std::string test_id = "hdkklepkcpckhnpgjnmbdfhehckloojk";
6286 CommandLine::ForCurrentProcess()->AppendSwitchASCII(
6287 switches::kWhitelistedExtensionID, test_id);
6288
6289 InitializeEmptyExtensionService();
6290 base::FilePath path = data_dir_
6291 .AppendASCII("permissions");
6292 base::FilePath pem_path = path
6293 .AppendASCII("whitelist.pem");
6294 path = path
6295 .AppendASCII("whitelist");
6296
6297 const Extension* extension = PackAndInstallCRX(path, pem_path, INSTALL_NEW);
6298 EXPECT_EQ(0u, GetErrors().size());
6299 ASSERT_EQ(1u, service_->extensions()->size());
6300 EXPECT_EQ(test_id, extension->id());
6301 }
6302
6303 // Test that when multiple sources try to install an extension,
6304 // we consistently choose the right one. To make tests easy to read,
6305 // methods that fake requests to install crx files in several ways
6306 // are provided.
6307 class ExtensionSourcePriorityTest : public ExtensionServiceTest {
6308 public:
SetUp()6309 virtual void SetUp() {
6310 ExtensionServiceTest::SetUp();
6311
6312 // All tests use a single extension. Put the id and path in member vars
6313 // that all methods can read.
6314 crx_id_ = kGoodId;
6315 crx_path_ = data_dir_.AppendASCII("good.crx");
6316 }
6317
6318 // Fake an external source adding a URL to fetch an extension from.
AddPendingExternalPrefUrl()6319 bool AddPendingExternalPrefUrl() {
6320 return service_->pending_extension_manager()->AddFromExternalUpdateUrl(
6321 crx_id_, GURL(), Manifest::EXTERNAL_PREF_DOWNLOAD,
6322 Extension::NO_FLAGS, false);
6323 }
6324
6325 // Fake an external file from external_extensions.json.
AddPendingExternalPrefFileInstall()6326 bool AddPendingExternalPrefFileInstall() {
6327 Version version("1.0.0.0");
6328
6329 return service_->OnExternalExtensionFileFound(
6330 crx_id_, &version, crx_path_, Manifest::EXTERNAL_PREF,
6331 Extension::NO_FLAGS, false);
6332 }
6333
6334 // Fake a request from sync to install an extension.
AddPendingSyncInstall()6335 bool AddPendingSyncInstall() {
6336 return service_->pending_extension_manager()->AddFromSync(
6337 crx_id_, GURL(kGoodUpdateURL), &IsExtension, kGoodInstallSilently);
6338 }
6339
6340 // Fake a policy install.
AddPendingPolicyInstall()6341 bool AddPendingPolicyInstall() {
6342 // Get path to the CRX with id |kGoodId|.
6343 return service_->OnExternalExtensionUpdateUrlFound(
6344 crx_id_, GURL(), Manifest::EXTERNAL_POLICY_DOWNLOAD,
6345 Extension::NO_FLAGS, false);
6346 }
6347
6348 // Get the install source of a pending extension.
GetPendingLocation()6349 Manifest::Location GetPendingLocation() {
6350 const extensions::PendingExtensionInfo* info;
6351 EXPECT_TRUE((info = service_->pending_extension_manager()->
6352 GetById(crx_id_)));
6353 return info->install_source();
6354 }
6355
6356 // Is an extension pending from a sync request?
GetPendingIsFromSync()6357 bool GetPendingIsFromSync() {
6358 const extensions::PendingExtensionInfo* info;
6359 EXPECT_TRUE((info = service_->pending_extension_manager()->
6360 GetById(crx_id_)));
6361 return info->is_from_sync();
6362 }
6363
6364 // Is the CRX id these tests use pending?
IsCrxPending()6365 bool IsCrxPending() {
6366 return service_->pending_extension_manager()->IsIdPending(crx_id_);
6367 }
6368
6369 // Is an extension installed?
IsCrxInstalled()6370 bool IsCrxInstalled() {
6371 return (service_->GetExtensionById(crx_id_, true) != NULL);
6372 }
6373
6374 protected:
6375 // All tests use a single extension. Making the id and path member
6376 // vars avoids pasing the same argument to every method.
6377 std::string crx_id_;
6378 base::FilePath crx_path_;
6379 };
6380
6381 // Test that a pending request for installation of an external CRX from
6382 // an update URL overrides a pending request to install the same extension
6383 // from sync.
TEST_F(ExtensionSourcePriorityTest,PendingExternalFileOverSync)6384 TEST_F(ExtensionSourcePriorityTest, PendingExternalFileOverSync) {
6385 InitializeEmptyExtensionService();
6386
6387 ASSERT_FALSE(IsCrxInstalled());
6388
6389 // Install pending extension from sync.
6390 content::WindowedNotificationObserver observer(
6391 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6392 content::NotificationService::AllSources());
6393 EXPECT_TRUE(AddPendingSyncInstall());
6394 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
6395 EXPECT_TRUE(GetPendingIsFromSync());
6396 ASSERT_FALSE(IsCrxInstalled());
6397
6398 // Install pending as external prefs json would.
6399 AddPendingExternalPrefFileInstall();
6400 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
6401 ASSERT_FALSE(IsCrxInstalled());
6402
6403 // Another request from sync should be ignored.
6404 EXPECT_FALSE(AddPendingSyncInstall());
6405 ASSERT_EQ(Manifest::EXTERNAL_PREF, GetPendingLocation());
6406 ASSERT_FALSE(IsCrxInstalled());
6407
6408 observer.Wait();
6409 VerifyCrxInstall(crx_path_, INSTALL_NEW);
6410 ASSERT_TRUE(IsCrxInstalled());
6411 }
6412
6413 // Test that an install of an external CRX from an update overrides
6414 // an install of the same extension from sync.
TEST_F(ExtensionSourcePriorityTest,PendingExternalUrlOverSync)6415 TEST_F(ExtensionSourcePriorityTest, PendingExternalUrlOverSync) {
6416 InitializeEmptyExtensionService();
6417 ASSERT_FALSE(IsCrxInstalled());
6418
6419 EXPECT_TRUE(AddPendingSyncInstall());
6420 ASSERT_EQ(Manifest::INTERNAL, GetPendingLocation());
6421 EXPECT_TRUE(GetPendingIsFromSync());
6422 ASSERT_FALSE(IsCrxInstalled());
6423
6424 ASSERT_TRUE(AddPendingExternalPrefUrl());
6425 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
6426 EXPECT_FALSE(GetPendingIsFromSync());
6427 ASSERT_FALSE(IsCrxInstalled());
6428
6429 EXPECT_FALSE(AddPendingSyncInstall());
6430 ASSERT_EQ(Manifest::EXTERNAL_PREF_DOWNLOAD, GetPendingLocation());
6431 EXPECT_FALSE(GetPendingIsFromSync());
6432 ASSERT_FALSE(IsCrxInstalled());
6433 }
6434
6435 // Test that an external install request stops sync from installing
6436 // the same extension.
TEST_F(ExtensionSourcePriorityTest,InstallExternalBlocksSyncRequest)6437 TEST_F(ExtensionSourcePriorityTest, InstallExternalBlocksSyncRequest) {
6438 InitializeEmptyExtensionService();
6439 ASSERT_FALSE(IsCrxInstalled());
6440
6441 // External prefs starts an install.
6442 AddPendingExternalPrefFileInstall();
6443
6444 // Crx installer was made, but has not yet run.
6445 ASSERT_FALSE(IsCrxInstalled());
6446
6447 // Before the CRX installer runs, Sync requests that the same extension
6448 // be installed. Should fail, because an external source is pending.
6449 content::WindowedNotificationObserver observer(
6450 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6451 content::NotificationService::AllSources());
6452 ASSERT_FALSE(AddPendingSyncInstall());
6453
6454 // Wait for the external source to install.
6455 observer.Wait();
6456 VerifyCrxInstall(crx_path_, INSTALL_NEW);
6457 ASSERT_TRUE(IsCrxInstalled());
6458
6459 // Now that the extension is installed, sync request should fail
6460 // because the extension is already installed.
6461 ASSERT_FALSE(AddPendingSyncInstall());
6462 }
6463
6464 // Test that installing an external extension displays a GlobalError.
TEST_F(ExtensionServiceTest,ExternalInstallGlobalError)6465 TEST_F(ExtensionServiceTest, ExternalInstallGlobalError) {
6466 FeatureSwitch::ScopedOverride prompt(
6467 FeatureSwitch::prompt_for_external_extensions(), true);
6468
6469 InitializeEmptyExtensionService();
6470 MockExtensionProvider* provider =
6471 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
6472 AddMockExternalProvider(provider);
6473
6474 service_->UpdateExternalExtensionAlert();
6475 // Should return false, meaning there aren't any extensions that the user
6476 // needs to know about.
6477 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
6478
6479 // This is a normal extension, installed normally.
6480 // This should NOT trigger an alert.
6481 set_extensions_enabled(true);
6482 base::FilePath path = data_dir_.AppendASCII("good.crx");
6483 InstallCRX(path, INSTALL_NEW);
6484
6485 service_->CheckForExternalUpdates();
6486 base::RunLoop().RunUntilIdle();
6487 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
6488
6489 // A hosted app, installed externally.
6490 // This should NOT trigger an alert.
6491 provider->UpdateOrAddExtension(hosted_app, "1.0.0.0",
6492 data_dir_.AppendASCII("hosted_app.crx"));
6493
6494 content::WindowedNotificationObserver observer(
6495 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6496 content::NotificationService::AllSources());
6497 service_->CheckForExternalUpdates();
6498 observer.Wait();
6499 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
6500
6501 // Another normal extension, but installed externally.
6502 // This SHOULD trigger an alert.
6503 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
6504 data_dir_.AppendASCII("page_action.crx"));
6505
6506 content::WindowedNotificationObserver observer2(
6507 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6508 content::NotificationService::AllSources());
6509 service_->CheckForExternalUpdates();
6510 observer2.Wait();
6511 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6512 }
6513
6514 // Test that external extensions are initially disabled, and that enabling
6515 // them clears the prompt.
TEST_F(ExtensionServiceTest,ExternalInstallInitiallyDisabled)6516 TEST_F(ExtensionServiceTest, ExternalInstallInitiallyDisabled) {
6517 FeatureSwitch::ScopedOverride prompt(
6518 FeatureSwitch::prompt_for_external_extensions(), true);
6519
6520 InitializeEmptyExtensionService();
6521 MockExtensionProvider* provider =
6522 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
6523 AddMockExternalProvider(provider);
6524
6525 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
6526 data_dir_.AppendASCII("page_action.crx"));
6527
6528 content::WindowedNotificationObserver observer(
6529 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6530 content::NotificationService::AllSources());
6531 service_->CheckForExternalUpdates();
6532 observer.Wait();
6533 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6534 EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
6535
6536 const Extension* extension =
6537 service_->disabled_extensions()->GetByID(page_action);
6538 EXPECT_TRUE(extension);
6539 EXPECT_EQ(page_action, extension->id());
6540
6541 service_->EnableExtension(page_action);
6542 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
6543 EXPECT_TRUE(service_->IsExtensionEnabled(page_action));
6544 }
6545
6546 // Test that installing multiple external extensions works.
6547 // Flaky on windows; http://crbug.com/295757 .
6548 #if defined(OS_WIN)
6549 #define MAYBE_ExternalInstallMultiple DISABLED_ExternalInstallMultiple
6550 #else
6551 #define MAYBE_ExternalInstallMultiple ExternalInstallMultiple
6552 #endif
TEST_F(ExtensionServiceTest,MAYBE_ExternalInstallMultiple)6553 TEST_F(ExtensionServiceTest, MAYBE_ExternalInstallMultiple) {
6554 FeatureSwitch::ScopedOverride prompt(
6555 FeatureSwitch::prompt_for_external_extensions(), true);
6556
6557 InitializeEmptyExtensionService();
6558 MockExtensionProvider* provider =
6559 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
6560 AddMockExternalProvider(provider);
6561
6562 provider->UpdateOrAddExtension(page_action, "1.0.0.0",
6563 data_dir_.AppendASCII("page_action.crx"));
6564 provider->UpdateOrAddExtension(good_crx, "1.0.0.0",
6565 data_dir_.AppendASCII("good.crx"));
6566 provider->UpdateOrAddExtension(theme_crx, "2.0",
6567 data_dir_.AppendASCII("theme.crx"));
6568
6569 int count = 3;
6570 content::WindowedNotificationObserver observer(
6571 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6572 base::Bind(&WaitForCountNotificationsCallback, &count));
6573 service_->CheckForExternalUpdates();
6574 observer.Wait();
6575 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6576 EXPECT_FALSE(service_->IsExtensionEnabled(page_action));
6577 EXPECT_FALSE(service_->IsExtensionEnabled(good_crx));
6578 EXPECT_FALSE(service_->IsExtensionEnabled(theme_crx));
6579
6580 service_->EnableExtension(page_action);
6581 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6582 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
6583 service_->EnableExtension(theme_crx);
6584 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6585 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
6586 service_->EnableExtension(good_crx);
6587 EXPECT_FALSE(extensions::HasExternalInstallError(service_));
6588 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
6589 }
6590
6591 // Test that there is a bubble for external extensions that update
6592 // from the webstore if the profile is not new.
TEST_F(ExtensionServiceTest,ExternalInstallUpdatesFromWebstoreOldProfile)6593 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreOldProfile) {
6594 FeatureSwitch::ScopedOverride prompt(
6595 FeatureSwitch::prompt_for_external_extensions(), true);
6596
6597 // This sets up the ExtensionPrefs used by our ExtensionService to be
6598 // post-first run.
6599 ExtensionServiceInitParams params = CreateDefaultInitParams();
6600 params.is_first_run = false;
6601 InitializeExtensionService(params);
6602
6603 base::FilePath crx_path = temp_dir_.path().AppendASCII("webstore.crx");
6604 PackCRX(data_dir_.AppendASCII("update_from_webstore"),
6605 data_dir_.AppendASCII("update_from_webstore.pem"),
6606 crx_path);
6607
6608 MockExtensionProvider* provider =
6609 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
6610 AddMockExternalProvider(provider);
6611 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
6612
6613 content::WindowedNotificationObserver observer(
6614 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6615 content::NotificationService::AllSources());
6616 service_->CheckForExternalUpdates();
6617 observer.Wait();
6618 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6619 EXPECT_TRUE(extensions::HasExternalInstallBubble(service_));
6620 EXPECT_FALSE(service_->IsExtensionEnabled(updates_from_webstore));
6621 }
6622
6623 // Test that there is no bubble for external extensions if the profile is new.
TEST_F(ExtensionServiceTest,ExternalInstallUpdatesFromWebstoreNewProfile)6624 TEST_F(ExtensionServiceTest, ExternalInstallUpdatesFromWebstoreNewProfile) {
6625 FeatureSwitch::ScopedOverride prompt(
6626 FeatureSwitch::prompt_for_external_extensions(), true);
6627
6628 InitializeEmptyExtensionService();
6629
6630 base::FilePath crx_path = temp_dir_.path().AppendASCII("webstore.crx");
6631 PackCRX(data_dir_.AppendASCII("update_from_webstore"),
6632 data_dir_.AppendASCII("update_from_webstore.pem"),
6633 crx_path);
6634
6635 MockExtensionProvider* provider =
6636 new MockExtensionProvider(service_, Manifest::EXTERNAL_PREF);
6637 AddMockExternalProvider(provider);
6638 provider->UpdateOrAddExtension(updates_from_webstore, "1", crx_path);
6639
6640 content::WindowedNotificationObserver observer(
6641 chrome::NOTIFICATION_CRX_INSTALLER_DONE,
6642 content::NotificationService::AllSources());
6643 service_->CheckForExternalUpdates();
6644 observer.Wait();
6645 EXPECT_TRUE(extensions::HasExternalInstallError(service_));
6646 EXPECT_FALSE(extensions::HasExternalInstallBubble(service_));
6647 EXPECT_FALSE(service_->IsExtensionEnabled(updates_from_webstore));
6648 }
6649
TEST_F(ExtensionServiceTest,InstallBlacklistedExtension)6650 TEST_F(ExtensionServiceTest, InstallBlacklistedExtension) {
6651 InitializeEmptyExtensionService();
6652
6653 scoped_refptr<Extension> extension = extensions::ExtensionBuilder()
6654 .SetManifest(extensions::DictionaryBuilder()
6655 .Set("name", "extension")
6656 .Set("version", "1.0")
6657 .Set("manifest_version", 2).Build())
6658 .Build();
6659 ASSERT_TRUE(extension.get());
6660 const std::string& id = extension->id();
6661
6662 std::set<std::string> id_set;
6663 id_set.insert(id);
6664 extensions::ExtensionNotificationObserver notifications(
6665 content::NotificationService::AllSources(), id_set);
6666
6667 // Installation should be allowed but the extension should never have been
6668 // loaded and it should be blacklisted in prefs.
6669 service_->OnExtensionInstalled(
6670 extension.get(),
6671 syncer::StringOrdinal(),
6672 false /* has requirement errors */,
6673 extensions::Blacklist::BLACKLISTED_MALWARE,
6674 false /* wait for idle */);
6675 base::RunLoop().RunUntilIdle();
6676
6677 // Extension was installed but not loaded.
6678 EXPECT_TRUE(notifications.CheckNotifications(
6679 chrome::NOTIFICATION_EXTENSION_INSTALLED));
6680
6681 EXPECT_TRUE(service_->GetInstalledExtension(id));
6682 EXPECT_FALSE(service_->extensions()->Contains(id));
6683 EXPECT_TRUE(service_->blacklisted_extensions()->Contains(id));
6684 EXPECT_TRUE(service_->extension_prefs()->IsExtensionBlacklisted(id));
6685 EXPECT_TRUE(
6686 service_->extension_prefs()->IsBlacklistedExtensionAcknowledged(id));
6687 }
6688
TEST_F(ExtensionServiceTest,ReconcileKnownDisabledNoneDisabled)6689 TEST_F(ExtensionServiceTest, ReconcileKnownDisabledNoneDisabled) {
6690 // A profile with 3 extensions installed: good0, good1, and good2.
6691 InitializeGoodInstalledExtensionService();
6692
6693 // Initializing shouldn't disable any extensions if none are known to be
6694 // disabled.
6695 service_->Init();
6696
6697 extensions::ExtensionIdSet expected_extensions;
6698 expected_extensions.insert(good0);
6699 expected_extensions.insert(good1);
6700 expected_extensions.insert(good2);
6701
6702 extensions::ExtensionIdSet expected_disabled_extensions;
6703
6704 EXPECT_EQ(expected_extensions, service_->extensions()->GetIDs());
6705 EXPECT_EQ(expected_disabled_extensions,
6706 service_->disabled_extensions()->GetIDs());
6707 }
6708
TEST_F(ExtensionServiceTest,ReconcileKnownDisabledWithSideEnable)6709 TEST_F(ExtensionServiceTest, ReconcileKnownDisabledWithSideEnable) {
6710 // A profile with 3 extensions installed: good0, good1, and good2.
6711 InitializeGoodInstalledExtensionService();
6712
6713 ExtensionPrefs* extension_prefs = service_->extension_prefs();
6714
6715 // Disable good1.
6716 extension_prefs->SetExtensionState(good1, Extension::DISABLED);
6717
6718 // Mark both good1 and good2 as "known_disabled" (effectively making good2
6719 // look as if it had been side-enabled).
6720 extensions::ExtensionIdSet known_disabled;
6721 known_disabled.insert(good1);
6722 known_disabled.insert(good2);
6723 extension_prefs->SetKnownDisabled(known_disabled);
6724
6725 // Initialize the service (which should disable good2 since it's known to be
6726 // disabled).
6727 service_->Init();
6728
6729 extensions::ExtensionIdSet expected_extensions;
6730 expected_extensions.insert(good0);
6731
6732 extensions::ExtensionIdSet expected_disabled_extensions;
6733 expected_disabled_extensions.insert(good1);
6734 expected_disabled_extensions.insert(good2);
6735
6736 EXPECT_EQ(expected_extensions, service_->extensions()->GetIDs());
6737 EXPECT_EQ(expected_disabled_extensions,
6738 service_->disabled_extensions()->GetIDs());
6739
6740 // Make sure that re-enabling an extension sticks across calls to
6741 // ReconcileKnownDisabled().
6742 service_->EnableExtension(good2);
6743 service_->ReconcileKnownDisabled();
6744 expected_extensions.insert(good2);
6745 expected_disabled_extensions.erase(good2);
6746
6747 EXPECT_EQ(expected_extensions, service_->extensions()->GetIDs());
6748 EXPECT_EQ(expected_disabled_extensions,
6749 service_->disabled_extensions()->GetIDs());
6750 }
6751