1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef COMPONENTS_PREFS_TESTING_PREF_SERVICE_H_
6 #define COMPONENTS_PREFS_TESTING_PREF_SERVICE_H_
7
8 #include <memory>
9 #include <utility>
10
11 #include "base/memory/ref_counted.h"
12 #include "components/prefs/pref_registry.h"
13 #include "components/prefs/pref_service.h"
14 #include "components/prefs/testing_pref_store.h"
15
16 class PrefNotifierImpl;
17 class PrefRegistrySimple;
18 class TestingPrefStore;
19
20 // A PrefService subclass for testing. It operates totally in memory and
21 // provides additional API for manipulating preferences at the different levels
22 // (managed, extension, user) conveniently.
23 //
24 // Use this via its specializations, e.g. TestingPrefServiceSimple.
25 template <class SuperPrefService, class ConstructionPrefRegistry>
26 class TestingPrefServiceBase : public SuperPrefService {
27 public:
28 TestingPrefServiceBase(const TestingPrefServiceBase&) = delete;
29 TestingPrefServiceBase& operator=(const TestingPrefServiceBase&) = delete;
30
31 virtual ~TestingPrefServiceBase();
32
33 // Reads the value of a preference from the managed layer. Returns NULL if the
34 // preference is not defined at the managed layer.
35 const base::Value* GetManagedPref(const std::string& path) const;
36
37 // Sets a preference on the managed layer and fires observers if the
38 // preference changed.
39 void SetManagedPref(const std::string& path,
40 std::unique_ptr<base::Value> value);
41 void SetManagedPref(const std::string& path, base::Value value);
42 void SetManagedPref(const std::string& path, base::Value::Dict dict);
43 void SetManagedPref(const std::string& path, base::Value::List list);
44
45 // Clears the preference on the managed layer and fire observers if the
46 // preference has been defined previously.
47 void RemoveManagedPref(const std::string& path);
48
49 // Similar to the above, but for supervised user preferences.
50 const base::Value* GetSupervisedUserPref(const std::string& path) const;
51 void SetSupervisedUserPref(const std::string& path,
52 std::unique_ptr<base::Value> value);
53 void SetSupervisedUserPref(const std::string& path, base::Value value);
54 void SetSupervisedUserPref(const std::string& path, base::Value::Dict dict);
55 void SetSupervisedUserPref(const std::string& path, base::Value::List list);
56 void RemoveSupervisedUserPref(const std::string& path);
57
58 // Similar to the above, but for extension preferences.
59 // Does not really know about extensions and their order of installation.
60 // Useful in tests that only check that a preference is overridden by an
61 // extension.
62 const base::Value* GetExtensionPref(const std::string& path) const;
63 void SetExtensionPref(const std::string& path,
64 std::unique_ptr<base::Value> value);
65 void SetExtensionPref(const std::string& path, base::Value value);
66 void SetExtensionPref(const std::string& path, base::Value::Dict dict);
67 void SetExtensionPref(const std::string& path, base::Value::List list);
68 void RemoveExtensionPref(const std::string& path);
69
70 // Similar to the above, but for user preferences.
71 const base::Value* GetUserPref(const std::string& path) const;
72 void SetUserPref(const std::string& path, std::unique_ptr<base::Value> value);
73 void SetUserPref(const std::string& path, base::Value value);
74 void SetUserPref(const std::string& path, base::Value::Dict dict);
75 void SetUserPref(const std::string& path, base::Value::List list);
76 void RemoveUserPref(const std::string& path);
77
78 // Similar to the above, but for recommended policy preferences.
79 const base::Value* GetRecommendedPref(const std::string& path) const;
80 void SetRecommendedPref(const std::string& path,
81 std::unique_ptr<base::Value> value);
82 void SetRecommendedPref(const std::string& path, base::Value value);
83 void SetRecommendedPref(const std::string& path, base::Value::Dict dict);
84 void SetRecommendedPref(const std::string& path, base::Value::List list);
85 void RemoveRecommendedPref(const std::string& path);
86
87 // Do-nothing implementation for TestingPrefService.
HandleReadError(PersistentPrefStore::PrefReadError error)88 static void HandleReadError(PersistentPrefStore::PrefReadError error) {}
89
90 // Set initialization status of pref stores.
91 void SetInitializationCompleted();
92
user_prefs_store()93 scoped_refptr<TestingPrefStore> user_prefs_store() { return user_prefs_; }
94
95 protected:
96 TestingPrefServiceBase(
97 scoped_refptr<TestingPrefStore> managed_prefs,
98 scoped_refptr<TestingPrefStore> supervised_user_prefs,
99 scoped_refptr<TestingPrefStore> extension_prefs,
100 scoped_refptr<TestingPrefStore> standalone_browser_prefs,
101 scoped_refptr<TestingPrefStore> user_prefs,
102 scoped_refptr<TestingPrefStore> recommended_prefs,
103 scoped_refptr<ConstructionPrefRegistry> pref_registry,
104 // Takes ownership.
105 PrefNotifierImpl* pref_notifier);
106
107 private:
108 // Reads the value of the preference indicated by |path| from |pref_store|.
109 // Returns NULL if the preference was not found.
110 const base::Value* GetPref(TestingPrefStore* pref_store,
111 const std::string& path) const;
112
113 // Sets the value for |path| in |pref_store|.
114 void SetPref(TestingPrefStore* pref_store,
115 const std::string& path,
116 std::unique_ptr<base::Value> value);
117
118 // Removes the preference identified by |path| from |pref_store|.
119 void RemovePref(TestingPrefStore* pref_store, const std::string& path);
120
121 // Pointers to the pref stores our value store uses.
122 scoped_refptr<TestingPrefStore> managed_prefs_;
123 scoped_refptr<TestingPrefStore> supervised_user_prefs_;
124 scoped_refptr<TestingPrefStore> extension_prefs_;
125 scoped_refptr<TestingPrefStore> standalone_browser_prefs_;
126 scoped_refptr<TestingPrefStore> user_prefs_;
127 scoped_refptr<TestingPrefStore> recommended_prefs_;
128 };
129
130 // Test version of PrefService.
131 class TestingPrefServiceSimple
132 : public TestingPrefServiceBase<PrefService, PrefRegistry> {
133 public:
134 TestingPrefServiceSimple();
135
136 TestingPrefServiceSimple(const TestingPrefServiceSimple&) = delete;
137 TestingPrefServiceSimple& operator=(const TestingPrefServiceSimple&) = delete;
138
139 ~TestingPrefServiceSimple() override;
140
141 // This is provided as a convenience for registering preferences on
142 // an existing TestingPrefServiceSimple instance. On a production
143 // PrefService you would do all registrations before constructing
144 // it, passing it a PrefRegistry via its constructor (or via
145 // e.g. PrefServiceFactory).
146 PrefRegistrySimple* registry();
147 };
148
149 template <>
150 TestingPrefServiceBase<PrefService, PrefRegistry>::TestingPrefServiceBase(
151 scoped_refptr<TestingPrefStore> managed_prefs,
152 scoped_refptr<TestingPrefStore> supervised_user_prefs,
153 scoped_refptr<TestingPrefStore> extension_prefs,
154 scoped_refptr<TestingPrefStore> standalone_browser_prefs,
155 scoped_refptr<TestingPrefStore> user_prefs,
156 scoped_refptr<TestingPrefStore> recommended_prefs,
157 scoped_refptr<PrefRegistry> pref_registry,
158 PrefNotifierImpl* pref_notifier);
159
160 template<class SuperPrefService, class ConstructionPrefRegistry>
161 TestingPrefServiceBase<
~TestingPrefServiceBase()162 SuperPrefService, ConstructionPrefRegistry>::~TestingPrefServiceBase() {
163 }
164
165 template <class SuperPrefService, class ConstructionPrefRegistry>
166 const base::Value* TestingPrefServiceBase<
167 SuperPrefService,
GetManagedPref(const std::string & path)168 ConstructionPrefRegistry>::GetManagedPref(const std::string& path) const {
169 return GetPref(managed_prefs_.get(), path);
170 }
171
172 template <class SuperPrefService, class ConstructionPrefRegistry>
173 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetManagedPref(const std::string & path,std::unique_ptr<base::Value> value)174 SetManagedPref(const std::string& path,
175 std::unique_ptr<base::Value> value) {
176 SetPref(managed_prefs_.get(), path, std::move(value));
177 }
178
179 template <class SuperPrefService, class ConstructionPrefRegistry>
180 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetManagedPref(const std::string & path,base::Value value)181 SetManagedPref(const std::string& path, base::Value value) {
182 SetManagedPref(path, base::Value::ToUniquePtrValue(std::move(value)));
183 }
184
185 template <class SuperPrefService, class ConstructionPrefRegistry>
186 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetManagedPref(const std::string & path,base::Value::Dict dict)187 SetManagedPref(const std::string& path, base::Value::Dict dict) {
188 SetManagedPref(path, std::make_unique<base::Value>(std::move(dict)));
189 }
190
191 template <class SuperPrefService, class ConstructionPrefRegistry>
192 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetManagedPref(const std::string & path,base::Value::List list)193 SetManagedPref(const std::string& path, base::Value::List list) {
194 SetManagedPref(path, std::make_unique<base::Value>(std::move(list)));
195 }
196
197 template <class SuperPrefService, class ConstructionPrefRegistry>
198 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemoveManagedPref(const std::string & path)199 RemoveManagedPref(const std::string& path) {
200 RemovePref(managed_prefs_.get(), path);
201 }
202
203 template <class SuperPrefService, class ConstructionPrefRegistry>
204 const base::Value*
205 TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
GetSupervisedUserPref(const std::string & path)206 GetSupervisedUserPref(const std::string& path) const {
207 return GetPref(supervised_user_prefs_.get(), path);
208 }
209
210 template <class SuperPrefService, class ConstructionPrefRegistry>
211 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetSupervisedUserPref(const std::string & path,std::unique_ptr<base::Value> value)212 SetSupervisedUserPref(const std::string& path,
213 std::unique_ptr<base::Value> value) {
214 SetPref(supervised_user_prefs_.get(), path, std::move(value));
215 }
216
217 template <class SuperPrefService, class ConstructionPrefRegistry>
218 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetSupervisedUserPref(const std::string & path,base::Value value)219 SetSupervisedUserPref(const std::string& path, base::Value value) {
220 SetSupervisedUserPref(path, base::Value::ToUniquePtrValue(std::move(value)));
221 }
222
223 template <class SuperPrefService, class ConstructionPrefRegistry>
224 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetSupervisedUserPref(const std::string & path,base::Value::Dict dict)225 SetSupervisedUserPref(const std::string& path, base::Value::Dict dict) {
226 SetSupervisedUserPref(path, std::make_unique<base::Value>(std::move(dict)));
227 }
228
229 template <class SuperPrefService, class ConstructionPrefRegistry>
230 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetSupervisedUserPref(const std::string & path,base::Value::List list)231 SetSupervisedUserPref(const std::string& path, base::Value::List list) {
232 SetSupervisedUserPref(path, std::make_unique<base::Value>(std::move(list)));
233 }
234
235 template <class SuperPrefService, class ConstructionPrefRegistry>
236 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemoveSupervisedUserPref(const std::string & path)237 RemoveSupervisedUserPref(const std::string& path) {
238 RemovePref(supervised_user_prefs_.get(), path);
239 }
240
241 template <class SuperPrefService, class ConstructionPrefRegistry>
242 const base::Value* TestingPrefServiceBase<
243 SuperPrefService,
GetExtensionPref(const std::string & path)244 ConstructionPrefRegistry>::GetExtensionPref(const std::string& path) const {
245 return GetPref(extension_prefs_.get(), path);
246 }
247
248 template <class SuperPrefService, class ConstructionPrefRegistry>
249 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetExtensionPref(const std::string & path,std::unique_ptr<base::Value> value)250 SetExtensionPref(const std::string& path,
251 std::unique_ptr<base::Value> value) {
252 SetPref(extension_prefs_.get(), path, std::move(value));
253 }
254
255 template <class SuperPrefService, class ConstructionPrefRegistry>
256 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetExtensionPref(const std::string & path,base::Value value)257 SetExtensionPref(const std::string& path, base::Value value) {
258 SetExtensionPref(path, base::Value::ToUniquePtrValue(std::move(value)));
259 }
260
261 template <class SuperPrefService, class ConstructionPrefRegistry>
262 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetExtensionPref(const std::string & path,base::Value::Dict dict)263 SetExtensionPref(const std::string& path, base::Value::Dict dict) {
264 SetExtensionPref(path, std::make_unique<base::Value>(std::move(dict)));
265 }
266
267 template <class SuperPrefService, class ConstructionPrefRegistry>
268 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetExtensionPref(const std::string & path,base::Value::List list)269 SetExtensionPref(const std::string& path, base::Value::List list) {
270 SetExtensionPref(path, std::make_unique<base::Value>(std::move(list)));
271 }
272
273 template <class SuperPrefService, class ConstructionPrefRegistry>
274 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemoveExtensionPref(const std::string & path)275 RemoveExtensionPref(const std::string& path) {
276 RemovePref(extension_prefs_.get(), path);
277 }
278
279 template <class SuperPrefService, class ConstructionPrefRegistry>
280 const base::Value*
GetUserPref(const std::string & path)281 TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::GetUserPref(
282 const std::string& path) const {
283 return GetPref(user_prefs_.get(), path);
284 }
285
286 template <class SuperPrefService, class ConstructionPrefRegistry>
287 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetUserPref(const std::string & path,std::unique_ptr<base::Value> value)288 SetUserPref(const std::string& path, std::unique_ptr<base::Value> value) {
289 SetPref(user_prefs_.get(), path, std::move(value));
290 }
291
292 template <class SuperPrefService, class ConstructionPrefRegistry>
293 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetUserPref(const std::string & path,base::Value value)294 SetUserPref(const std::string& path, base::Value value) {
295 SetUserPref(path, base::Value::ToUniquePtrValue(std::move(value)));
296 }
297
298 template <class SuperPrefService, class ConstructionPrefRegistry>
299 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetUserPref(const std::string & path,base::Value::Dict dict)300 SetUserPref(const std::string& path, base::Value::Dict dict) {
301 SetUserPref(path, std::make_unique<base::Value>(std::move(dict)));
302 }
303
304 template <class SuperPrefService, class ConstructionPrefRegistry>
305 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetUserPref(const std::string & path,base::Value::List list)306 SetUserPref(const std::string& path, base::Value::List list) {
307 SetUserPref(path, std::make_unique<base::Value>(std::move(list)));
308 }
309
310 template <class SuperPrefService, class ConstructionPrefRegistry>
311 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemoveUserPref(const std::string & path)312 RemoveUserPref(const std::string& path) {
313 RemovePref(user_prefs_.get(), path);
314 }
315
316 template <class SuperPrefService, class ConstructionPrefRegistry>
317 const base::Value*
318 TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
GetRecommendedPref(const std::string & path)319 GetRecommendedPref(const std::string& path) const {
320 return GetPref(recommended_prefs_, path);
321 }
322
323 template <class SuperPrefService, class ConstructionPrefRegistry>
324 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetRecommendedPref(const std::string & path,std::unique_ptr<base::Value> value)325 SetRecommendedPref(const std::string& path,
326 std::unique_ptr<base::Value> value) {
327 SetPref(recommended_prefs_.get(), path, std::move(value));
328 }
329
330 template <class SuperPrefService, class ConstructionPrefRegistry>
331 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetRecommendedPref(const std::string & path,base::Value value)332 SetRecommendedPref(const std::string& path, base::Value value) {
333 SetPref(recommended_prefs_.get(), path,
334 base::Value::ToUniquePtrValue(std::move(value)));
335 }
336
337 template <class SuperPrefService, class ConstructionPrefRegistry>
338 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetRecommendedPref(const std::string & path,base::Value::Dict dict)339 SetRecommendedPref(const std::string& path, base::Value::Dict dict) {
340 SetRecommendedPref(path, std::make_unique<base::Value>(std::move(dict)));
341 }
342
343 template <class SuperPrefService, class ConstructionPrefRegistry>
344 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetRecommendedPref(const std::string & path,base::Value::List list)345 SetRecommendedPref(const std::string& path, base::Value::List list) {
346 SetRecommendedPref(path, std::make_unique<base::Value>(std::move(list)));
347 }
348
349 template <class SuperPrefService, class ConstructionPrefRegistry>
350 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemoveRecommendedPref(const std::string & path)351 RemoveRecommendedPref(const std::string& path) {
352 RemovePref(recommended_prefs_.get(), path);
353 }
354
355 template <class SuperPrefService, class ConstructionPrefRegistry>
356 const base::Value*
GetPref(TestingPrefStore * pref_store,const std::string & path)357 TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::GetPref(
358 TestingPrefStore* pref_store,
359 const std::string& path) const {
360 const base::Value* res;
361 return pref_store->GetValue(path, &res) ? res : NULL;
362 }
363
364 template <class SuperPrefService, class ConstructionPrefRegistry>
365 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetPref(TestingPrefStore * pref_store,const std::string & path,std::unique_ptr<base::Value> value)366 SetPref(TestingPrefStore* pref_store,
367 const std::string& path,
368 std::unique_ptr<base::Value> value) {
369 pref_store->SetValue(path, base::Value::FromUniquePtrValue(std::move(value)),
370 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
371 }
372
373 template <class SuperPrefService, class ConstructionPrefRegistry>
374 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemovePref(TestingPrefStore * pref_store,const std::string & path)375 RemovePref(TestingPrefStore* pref_store, const std::string& path) {
376 pref_store->RemoveValue(path, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
377 }
378
379 template <class SuperPrefService, class ConstructionPrefRegistry>
380 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetInitializationCompleted()381 SetInitializationCompleted() {
382 managed_prefs_->SetInitializationCompleted();
383 supervised_user_prefs_->SetInitializationCompleted();
384 extension_prefs_->SetInitializationCompleted();
385 recommended_prefs_->SetInitializationCompleted();
386 // |user_prefs_| and |standalone_browser_prefs_| are initialized in
387 // PrefService constructor so no need to set initialization status again.
388 }
389
390 #endif // COMPONENTS_PREFS_TESTING_PREF_SERVICE_H_
391