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