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