blob: 20913591bb71a0167e6c18673682a9437f37ae7b [file] [log] [blame]
[email protected]a52c0e92012-03-23 06:02:241// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]63c64d12010-04-27 21:21:342// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/extensions/test_extension_prefs.h"
6
dchengc963c7142016-04-08 03:55:227#include <memory>
dcheng1fc00f12015-12-26 22:18:038#include <utility>
9
[email protected]406af392011-11-25 18:19:3810#include "base/bind.h"
11#include "base/bind_helpers.h"
thestig18dfb7a52014-08-26 10:44:0412#include "base/files/file_util.h"
avia2f4804a2015-12-24 23:11:1313#include "base/macros.h"
[email protected]0de615a2012-11-08 04:40:5914#include "base/run_loop.h"
[email protected]fb441962013-05-08 05:35:2415#include "base/sequenced_task_runner.h"
[email protected]6cad5bf2011-03-10 21:21:5516#include "base/synchronization/waitable_event.h"
gabb15e19072016-05-11 20:45:4117#include "base/threading/thread_task_runner_handle.h"
Devlin Cronin4a3c38f2017-09-21 02:32:0018#include "base/time/clock.h"
[email protected]c38831a12011-10-28 12:44:4919#include "base/values.h"
treib926ee2d2015-08-06 10:55:4220#include "chrome/browser/extensions/chrome_app_sorting.h"
21#include "chrome/browser/extensions/test_extension_system.h"
Minh X. Nguyen3aa40692018-03-28 01:15:5922#include "chrome/browser/prefs/browser_prefs.h"
sdefresne0b1722f02015-09-14 18:12:1223#include "chrome/browser/prefs/pref_service_syncable_util.h"
[email protected]e96a0602014-02-15 08:27:4224#include "chrome/common/chrome_constants.h"
[email protected]fdd28372014-08-21 02:27:2625#include "components/crx_file/id_util.h"
[email protected]f0c8c4992014-05-15 17:37:2626#include "components/pref_registry/pref_registry_syncable.h"
brettwb1fc1b82016-02-02 00:19:0827#include "components/prefs/json_pref_store.h"
28#include "components/prefs/pref_value_store.h"
skym71603842016-10-10 18:17:3129#include "components/sync/model/string_ordinal.h"
maxbogueea16ff412016-10-28 16:35:2930#include "components/sync_preferences/pref_service_mock_factory.h"
31#include "components/sync_preferences/pref_service_syncable.h"
[email protected]c38831a12011-10-28 12:44:4932#include "content/public/browser/browser_thread.h"
[email protected]489db0842014-01-22 18:20:0333#include "extensions/browser/extension_pref_store.h"
34#include "extensions/browser/extension_pref_value_map.h"
35#include "extensions/browser/extension_prefs.h"
treib926ee2d2015-08-06 10:55:4236#include "extensions/browser/extension_prefs_factory.h"
37#include "extensions/browser/extension_system.h"
[email protected]bf5ee7cc2013-11-23 20:48:4438#include "extensions/browser/extensions_browser_client.h"
[email protected]e4452d32013-11-15 23:07:4139#include "extensions/common/extension.h"
[email protected]6bf90612013-08-15 00:36:2740#include "extensions/common/manifest_constants.h"
[email protected]63c64d12010-04-27 21:21:3441#include "testing/gtest/include/gtest/gtest.h"
42
[email protected]631bb742011-11-02 11:29:3943using content::BrowserThread;
[email protected]45759612012-07-10 17:21:2344
45namespace extensions {
[email protected]631bb742011-11-02 11:29:3946
Devlin Cronin4a3c38f2017-09-21 02:32:0047// A Clock which returns an incrementally later time each time Now() is called.
tzik9a2f9c02018-03-22 04:37:3148class TestExtensionPrefs::IncrementalClock : public base::Clock {
[email protected]73c47932010-12-06 18:13:4349 public:
Devlin Cronin4a3c38f2017-09-21 02:32:0050 IncrementalClock() : current_time_(base::Time::Now()) {}
[email protected]fdd679b2012-11-15 20:49:3951
Devlin Cronin4a3c38f2017-09-21 02:32:0052 ~IncrementalClock() override {}
[email protected]fdd679b2012-11-15 20:49:3953
tzikee78e4962018-04-13 12:25:4654 base::Time Now() const override {
[email protected]fdd679b2012-11-15 20:49:3955 current_time_ += base::TimeDelta::FromSeconds(10);
56 return current_time_;
57 }
58
59 private:
tzikee78e4962018-04-13 12:25:4660 mutable base::Time current_time_;
[email protected]fdd679b2012-11-15 20:49:3961
Devlin Cronin4a3c38f2017-09-21 02:32:0062 DISALLOW_COPY_AND_ASSIGN(IncrementalClock);
[email protected]73c47932010-12-06 18:13:4363};
64
dcheng605ef8d2014-08-28 18:29:4465TestExtensionPrefs::TestExtensionPrefs(
66 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
tzik9a2f9c02018-03-22 04:37:3167 : task_runner_(task_runner),
68 clock_(std::make_unique<IncrementalClock>()),
69 extensions_disabled_(false) {
[email protected]63c64d12010-04-27 21:21:3470 EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
vabr9142fe22016-09-08 13:19:2271 preferences_file_ = temp_dir_.GetPath().Append(chrome::kPreferencesFilename);
72 extensions_dir_ = temp_dir_.GetPath().AppendASCII("Extensions");
[email protected]426d1c92013-12-03 20:08:5473 EXPECT_TRUE(base::CreateDirectory(extensions_dir_));
[email protected]63c64d12010-04-27 21:21:3474
[email protected]c753f142013-02-10 13:14:0475 ResetPrefRegistry();
[email protected]63c64d12010-04-27 21:21:3476 RecreateExtensionPrefs();
77}
78
[email protected]0de615a2012-11-08 04:40:5979TestExtensionPrefs::~TestExtensionPrefs() {
80}
[email protected]63c64d12010-04-27 21:21:3481
treib926ee2d2015-08-06 10:55:4282ExtensionPrefs* TestExtensionPrefs::prefs() {
83 return ExtensionPrefs::Get(&profile_);
84}
85
Minh X. Nguyen3aa40692018-03-28 01:15:5986TestingProfile* TestExtensionPrefs::profile() {
87 return &profile_;
88}
89
[email protected]c753f142013-02-10 13:14:0490PrefService* TestExtensionPrefs::pref_service() {
91 return pref_service_.get();
92}
93
[email protected]443e9312013-05-06 06:17:3494const scoped_refptr<user_prefs::PrefRegistrySyncable>&
95TestExtensionPrefs::pref_registry() {
[email protected]c753f142013-02-10 13:14:0496 return pref_registry_;
97}
98
99void TestExtensionPrefs::ResetPrefRegistry() {
[email protected]443e9312013-05-06 06:17:34100 pref_registry_ = new user_prefs::PrefRegistrySyncable;
Minh X. Nguyen3aa40692018-03-28 01:15:59101 RegisterUserProfilePrefs(pref_registry_.get());
[email protected]c753f142013-02-10 13:14:04102}
103
[email protected]63c64d12010-04-27 21:21:34104void TestExtensionPrefs::RecreateExtensionPrefs() {
[email protected]73c47932010-12-06 18:13:43105 // We persist and reload the PrefService's PrefStores because this process
106 // deletes all empty dictionaries. The ExtensionPrefs implementation
107 // needs to be able to handle this situation.
[email protected]3eeddd892013-04-17 17:00:11108 if (pref_service_) {
[email protected]0de615a2012-11-08 04:40:59109 // Commit a pending write (which posts a task to task_runner_) and wait for
110 // it to finish.
111 pref_service_->CommitPendingWrite();
112 base::RunLoop run_loop;
Peter Kasting341e1fb2018-02-24 00:03:01113 ASSERT_TRUE(task_runner_->PostTaskAndReply(FROM_HERE, base::DoNothing(),
114 run_loop.QuitClosure()));
[email protected]0de615a2012-11-08 04:40:59115 run_loop.Run();
[email protected]63c64d12010-04-27 21:21:34116 }
117
[email protected]9a8c4022011-01-25 14:25:33118 extension_pref_value_map_.reset(new ExtensionPrefValueMap);
maxbogueea16ff412016-10-28 16:35:29119 sync_preferences::PrefServiceMockFactory factory;
[email protected]e90a01f2013-11-19 04:22:12120 factory.SetUserPrefsFile(preferences_file_, task_runner_.get());
121 factory.set_extension_prefs(
[email protected]9a8c4022011-01-25 14:25:33122 new ExtensionPrefStore(extension_pref_value_map_.get(), false));
dcheng1fc00f12015-12-26 22:18:03123 pref_service_ = factory.CreateSyncable(pref_registry_.get());
dchengc963c7142016-04-08 03:55:22124 std::unique_ptr<ExtensionPrefs> prefs(ExtensionPrefs::Create(
vabr9142fe22016-09-08 13:19:22125 &profile_, pref_service_.get(), temp_dir_.GetPath(),
dchengc963c7142016-04-08 03:55:22126 extension_pref_value_map_.get(), extensions_disabled_,
Nigel Tao650b7312019-04-27 00:18:32127 std::vector<EarlyExtensionPrefsObserver*>(),
[email protected]fdd679b2012-11-15 20:49:39128 // Guarantee that no two extensions get the same installation time
129 // stamp and we can reliably assert the installation order in the tests.
tzik9a2f9c02018-03-22 04:37:31130 clock_.get()));
treib926ee2d2015-08-06 10:55:42131 ExtensionPrefsFactory::GetInstance()->SetInstanceForTesting(&profile_,
dcheng1fc00f12015-12-26 22:18:03132 std::move(prefs));
treib926ee2d2015-08-06 10:55:42133 // Hack: After recreating ExtensionPrefs, the AppSorting also needs to be
134 // recreated. (ExtensionPrefs is never recreated in non-test code.)
135 static_cast<TestExtensionSystem*>(ExtensionSystem::Get(&profile_))
136 ->RecreateAppSorting();
[email protected]63c64d12010-04-27 21:21:34137}
138
[email protected]0bb29bd2014-04-30 21:39:18139scoped_refptr<Extension> TestExtensionPrefs::AddExtension(
140 const std::string& name) {
[email protected]cb1078de2013-12-23 20:04:22141 base::DictionaryValue dictionary;
[email protected]6bf90612013-08-15 00:36:27142 dictionary.SetString(manifest_keys::kName, name);
143 dictionary.SetString(manifest_keys::kVersion, "0.1");
Devlin Cronin1fa235b62018-04-12 14:04:07144 dictionary.SetInteger(manifest_keys::kManifestVersion, 2);
[email protected]1d5e58b2013-01-31 08:41:40145 return AddExtensionWithManifest(dictionary, Manifest::INTERNAL);
[email protected]63c64d12010-04-27 21:21:34146}
147
[email protected]0bb29bd2014-04-30 21:39:18148scoped_refptr<Extension> TestExtensionPrefs::AddApp(const std::string& name) {
[email protected]cb1078de2013-12-23 20:04:22149 base::DictionaryValue dictionary;
[email protected]6bf90612013-08-15 00:36:27150 dictionary.SetString(manifest_keys::kName, name);
151 dictionary.SetString(manifest_keys::kVersion, "0.1");
152 dictionary.SetString(manifest_keys::kApp, "true");
153 dictionary.SetString(manifest_keys::kLaunchWebURL, "http://example.com");
[email protected]1d5e58b2013-01-31 08:41:40154 return AddExtensionWithManifest(dictionary, Manifest::INTERNAL);
[email protected]f1b66652011-08-25 23:30:58155
156}
157
[email protected]66e4eb32010-10-27 20:37:41158scoped_refptr<Extension> TestExtensionPrefs::AddExtensionWithManifest(
[email protected]cb1078de2013-12-23 20:04:22159 const base::DictionaryValue& manifest, Manifest::Location location) {
[email protected]e805baf2011-07-26 18:23:05160 return AddExtensionWithManifestAndFlags(manifest, location,
[email protected]ed3b9b12012-05-31 18:37:51161 Extension::NO_FLAGS);
[email protected]e805baf2011-07-26 18:23:05162}
163
164scoped_refptr<Extension> TestExtensionPrefs::AddExtensionWithManifestAndFlags(
[email protected]cb1078de2013-12-23 20:04:22165 const base::DictionaryValue& manifest,
[email protected]1d5e58b2013-01-31 08:41:40166 Manifest::Location location,
[email protected]e805baf2011-07-26 18:23:05167 int extra_flags) {
[email protected]63c64d12010-04-27 21:21:34168 std::string name;
[email protected]6bf90612013-08-15 00:36:27169 EXPECT_TRUE(manifest.GetString(manifest_keys::kName, &name));
[email protected]650b2d52013-02-10 03:41:45170 base::FilePath path = extensions_dir_.AppendASCII(name);
[email protected]63c64d12010-04-27 21:21:34171 std::string errors;
[email protected]66e4eb32010-10-27 20:37:41172 scoped_refptr<Extension> extension = Extension::Create(
[email protected]e805baf2011-07-26 18:23:05173 path, location, manifest, extra_flags, &errors);
[email protected]dc24976f2013-06-02 21:15:09174 EXPECT_TRUE(extension.get()) << errors;
175 if (!extension.get())
[email protected]66e4eb32010-10-27 20:37:41176 return NULL;
177
[email protected]fdd28372014-08-21 02:27:26178 EXPECT_TRUE(crx_file::id_util::IdIsValid(extension->id()));
treib926ee2d2015-08-06 10:55:42179 prefs()->OnExtensionInstalled(extension.get(),
180 Extension::ENABLED,
181 syncer::StringOrdinal::CreateInitialOrdinal(),
182 std::string());
[email protected]63c64d12010-04-27 21:21:34183 return extension;
184}
185
[email protected]0bb29bd2014-04-30 21:39:18186std::string TestExtensionPrefs::AddExtensionAndReturnId(
187 const std::string& name) {
[email protected]66e4eb32010-10-27 20:37:41188 scoped_refptr<Extension> extension(AddExtension(name));
[email protected]63c64d12010-04-27 21:21:34189 return extension->id();
190}
[email protected]9a8c4022011-01-25 14:25:33191
Devlin Cronin8e5892f2018-10-04 00:13:43192void TestExtensionPrefs::AddExtension(const Extension* extension) {
treib926ee2d2015-08-06 10:55:42193 prefs()->OnExtensionInstalled(extension,
194 Extension::ENABLED,
195 syncer::StringOrdinal::CreateInitialOrdinal(),
196 std::string());
deepak.m175277b02015-04-15 06:30:11197}
198
François Degros9d35fc572018-02-05 22:32:45199std::unique_ptr<PrefService> TestExtensionPrefs::CreateIncognitoPrefService()
200 const {
sdefresne0b1722f02015-09-14 18:12:12201 return CreateIncognitoPrefServiceSyncable(
202 pref_service_.get(),
Sam McNally538fca1e2017-07-14 03:10:43203 new ExtensionPrefStore(extension_pref_value_map_.get(), true), nullptr);
[email protected]9a8c4022011-01-25 14:25:33204}
[email protected]9e33d7e2011-09-30 16:43:54205
206void TestExtensionPrefs::set_extensions_disabled(bool extensions_disabled) {
207 extensions_disabled_ = extensions_disabled;
208}
[email protected]45759612012-07-10 17:21:23209
treib926ee2d2015-08-06 10:55:42210ChromeAppSorting* TestExtensionPrefs::app_sorting() {
211 return static_cast<ChromeAppSorting*>(
212 ExtensionSystem::Get(&profile_)->app_sorting());
213}
214
[email protected]45759612012-07-10 17:21:23215} // namespace extensions