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