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