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