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