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