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(TestingPrefStore* managed_prefs,
97 TestingPrefStore* supervised_user_prefs,
98 TestingPrefStore* extension_prefs,
99 TestingPrefStore* standalone_browser_prefs,
100 TestingPrefStore* user_prefs,
101 TestingPrefStore* recommended_prefs,
102 ConstructionPrefRegistry* pref_registry,
103 PrefNotifierImpl* pref_notifier);
104
105 private:
106 // Reads the value of the preference indicated by |path| from |pref_store|.
107 // Returns NULL if the preference was not found.
108 const base::Value* GetPref(TestingPrefStore* pref_store,
109 const std::string& path) const;
110
111 // Sets the value for |path| in |pref_store|.
112 void SetPref(TestingPrefStore* pref_store,
113 const std::string& path,
114 std::unique_ptr<base::Value> value);
115
116 // Removes the preference identified by |path| from |pref_store|.
117 void RemovePref(TestingPrefStore* pref_store, const std::string& path);
118
119 // Pointers to the pref stores our value store uses.
120 scoped_refptr<TestingPrefStore> managed_prefs_;
121 scoped_refptr<TestingPrefStore> supervised_user_prefs_;
122 scoped_refptr<TestingPrefStore> extension_prefs_;
123 scoped_refptr<TestingPrefStore> standalone_browser_prefs_;
124 scoped_refptr<TestingPrefStore> user_prefs_;
125 scoped_refptr<TestingPrefStore> recommended_prefs_;
126 };
127
128 // Test version of PrefService.
129 class TestingPrefServiceSimple
130 : public TestingPrefServiceBase<PrefService, PrefRegistry> {
131 public:
132 TestingPrefServiceSimple();
133
134 TestingPrefServiceSimple(const TestingPrefServiceSimple&) = delete;
135 TestingPrefServiceSimple& operator=(const TestingPrefServiceSimple&) = delete;
136
137 ~TestingPrefServiceSimple() override;
138
139 // This is provided as a convenience for registering preferences on
140 // an existing TestingPrefServiceSimple instance. On a production
141 // PrefService you would do all registrations before constructing
142 // it, passing it a PrefRegistry via its constructor (or via
143 // e.g. PrefServiceFactory).
144 PrefRegistrySimple* registry();
145 };
146
147 template <>
148 TestingPrefServiceBase<PrefService, PrefRegistry>::TestingPrefServiceBase(
149 TestingPrefStore* managed_prefs,
150 TestingPrefStore* supervised_user_prefs,
151 TestingPrefStore* extension_prefs,
152 TestingPrefStore* standalone_browser_prefs,
153 TestingPrefStore* user_prefs,
154 TestingPrefStore* recommended_prefs,
155 PrefRegistry* pref_registry,
156 PrefNotifierImpl* pref_notifier);
157
158 template<class SuperPrefService, class ConstructionPrefRegistry>
159 TestingPrefServiceBase<
~TestingPrefServiceBase()160 SuperPrefService, ConstructionPrefRegistry>::~TestingPrefServiceBase() {
161 }
162
163 template <class SuperPrefService, class ConstructionPrefRegistry>
164 const base::Value* TestingPrefServiceBase<
165 SuperPrefService,
GetManagedPref(const std::string & path)166 ConstructionPrefRegistry>::GetManagedPref(const std::string& path) const {
167 return GetPref(managed_prefs_.get(), path);
168 }
169
170 template <class SuperPrefService, class ConstructionPrefRegistry>
171 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetManagedPref(const std::string & path,std::unique_ptr<base::Value> value)172 SetManagedPref(const std::string& path,
173 std::unique_ptr<base::Value> value) {
174 SetPref(managed_prefs_.get(), path, std::move(value));
175 }
176
177 template <class SuperPrefService, class ConstructionPrefRegistry>
178 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetManagedPref(const std::string & path,base::Value value)179 SetManagedPref(const std::string& path, base::Value value) {
180 SetManagedPref(path, base::Value::ToUniquePtrValue(std::move(value)));
181 }
182
183 template <class SuperPrefService, class ConstructionPrefRegistry>
184 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetManagedPref(const std::string & path,base::Value::Dict dict)185 SetManagedPref(const std::string& path, base::Value::Dict dict) {
186 SetManagedPref(path, std::make_unique<base::Value>(std::move(dict)));
187 }
188
189 template <class SuperPrefService, class ConstructionPrefRegistry>
190 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetManagedPref(const std::string & path,base::Value::List list)191 SetManagedPref(const std::string& path, base::Value::List list) {
192 SetManagedPref(path, std::make_unique<base::Value>(std::move(list)));
193 }
194
195 template <class SuperPrefService, class ConstructionPrefRegistry>
196 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemoveManagedPref(const std::string & path)197 RemoveManagedPref(const std::string& path) {
198 RemovePref(managed_prefs_.get(), path);
199 }
200
201 template <class SuperPrefService, class ConstructionPrefRegistry>
202 const base::Value*
203 TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
GetSupervisedUserPref(const std::string & path)204 GetSupervisedUserPref(const std::string& path) const {
205 return GetPref(supervised_user_prefs_.get(), path);
206 }
207
208 template <class SuperPrefService, class ConstructionPrefRegistry>
209 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetSupervisedUserPref(const std::string & path,std::unique_ptr<base::Value> value)210 SetSupervisedUserPref(const std::string& path,
211 std::unique_ptr<base::Value> value) {
212 SetPref(supervised_user_prefs_.get(), path, std::move(value));
213 }
214
215 template <class SuperPrefService, class ConstructionPrefRegistry>
216 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetSupervisedUserPref(const std::string & path,base::Value value)217 SetSupervisedUserPref(const std::string& path, base::Value value) {
218 SetSupervisedUserPref(path, base::Value::ToUniquePtrValue(std::move(value)));
219 }
220
221 template <class SuperPrefService, class ConstructionPrefRegistry>
222 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetSupervisedUserPref(const std::string & path,base::Value::Dict dict)223 SetSupervisedUserPref(const std::string& path, base::Value::Dict dict) {
224 SetSupervisedUserPref(path, std::make_unique<base::Value>(std::move(dict)));
225 }
226
227 template <class SuperPrefService, class ConstructionPrefRegistry>
228 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetSupervisedUserPref(const std::string & path,base::Value::List list)229 SetSupervisedUserPref(const std::string& path, base::Value::List list) {
230 SetSupervisedUserPref(path, std::make_unique<base::Value>(std::move(list)));
231 }
232
233 template <class SuperPrefService, class ConstructionPrefRegistry>
234 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemoveSupervisedUserPref(const std::string & path)235 RemoveSupervisedUserPref(const std::string& path) {
236 RemovePref(supervised_user_prefs_.get(), path);
237 }
238
239 template <class SuperPrefService, class ConstructionPrefRegistry>
240 const base::Value* TestingPrefServiceBase<
241 SuperPrefService,
GetExtensionPref(const std::string & path)242 ConstructionPrefRegistry>::GetExtensionPref(const std::string& path) const {
243 return GetPref(extension_prefs_.get(), path);
244 }
245
246 template <class SuperPrefService, class ConstructionPrefRegistry>
247 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetExtensionPref(const std::string & path,std::unique_ptr<base::Value> value)248 SetExtensionPref(const std::string& path,
249 std::unique_ptr<base::Value> value) {
250 SetPref(extension_prefs_.get(), path, std::move(value));
251 }
252
253 template <class SuperPrefService, class ConstructionPrefRegistry>
254 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetExtensionPref(const std::string & path,base::Value value)255 SetExtensionPref(const std::string& path, base::Value value) {
256 SetExtensionPref(path, base::Value::ToUniquePtrValue(std::move(value)));
257 }
258
259 template <class SuperPrefService, class ConstructionPrefRegistry>
260 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetExtensionPref(const std::string & path,base::Value::Dict dict)261 SetExtensionPref(const std::string& path, base::Value::Dict dict) {
262 SetExtensionPref(path, std::make_unique<base::Value>(std::move(dict)));
263 }
264
265 template <class SuperPrefService, class ConstructionPrefRegistry>
266 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetExtensionPref(const std::string & path,base::Value::List list)267 SetExtensionPref(const std::string& path, base::Value::List list) {
268 SetExtensionPref(path, std::make_unique<base::Value>(std::move(list)));
269 }
270
271 template <class SuperPrefService, class ConstructionPrefRegistry>
272 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemoveExtensionPref(const std::string & path)273 RemoveExtensionPref(const std::string& path) {
274 RemovePref(extension_prefs_.get(), path);
275 }
276
277 template <class SuperPrefService, class ConstructionPrefRegistry>
278 const base::Value*
GetUserPref(const std::string & path)279 TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::GetUserPref(
280 const std::string& path) const {
281 return GetPref(user_prefs_.get(), path);
282 }
283
284 template <class SuperPrefService, class ConstructionPrefRegistry>
285 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetUserPref(const std::string & path,std::unique_ptr<base::Value> value)286 SetUserPref(const std::string& path, std::unique_ptr<base::Value> value) {
287 SetPref(user_prefs_.get(), path, std::move(value));
288 }
289
290 template <class SuperPrefService, class ConstructionPrefRegistry>
291 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetUserPref(const std::string & path,base::Value value)292 SetUserPref(const std::string& path, base::Value value) {
293 SetUserPref(path, base::Value::ToUniquePtrValue(std::move(value)));
294 }
295
296 template <class SuperPrefService, class ConstructionPrefRegistry>
297 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetUserPref(const std::string & path,base::Value::Dict dict)298 SetUserPref(const std::string& path, base::Value::Dict dict) {
299 SetUserPref(path, std::make_unique<base::Value>(std::move(dict)));
300 }
301
302 template <class SuperPrefService, class ConstructionPrefRegistry>
303 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetUserPref(const std::string & path,base::Value::List list)304 SetUserPref(const std::string& path, base::Value::List list) {
305 SetUserPref(path, std::make_unique<base::Value>(std::move(list)));
306 }
307
308 template <class SuperPrefService, class ConstructionPrefRegistry>
309 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemoveUserPref(const std::string & path)310 RemoveUserPref(const std::string& path) {
311 RemovePref(user_prefs_.get(), path);
312 }
313
314 template <class SuperPrefService, class ConstructionPrefRegistry>
315 const base::Value*
316 TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
GetRecommendedPref(const std::string & path)317 GetRecommendedPref(const std::string& path) const {
318 return GetPref(recommended_prefs_, path);
319 }
320
321 template <class SuperPrefService, class ConstructionPrefRegistry>
322 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetRecommendedPref(const std::string & path,std::unique_ptr<base::Value> value)323 SetRecommendedPref(const std::string& path,
324 std::unique_ptr<base::Value> value) {
325 SetPref(recommended_prefs_.get(), path, std::move(value));
326 }
327
328 template <class SuperPrefService, class ConstructionPrefRegistry>
329 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetRecommendedPref(const std::string & path,base::Value value)330 SetRecommendedPref(const std::string& path, base::Value value) {
331 SetPref(recommended_prefs_.get(), path,
332 base::Value::ToUniquePtrValue(std::move(value)));
333 }
334
335 template <class SuperPrefService, class ConstructionPrefRegistry>
336 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetRecommendedPref(const std::string & path,base::Value::Dict dict)337 SetRecommendedPref(const std::string& path, base::Value::Dict dict) {
338 SetRecommendedPref(path, std::make_unique<base::Value>(std::move(dict)));
339 }
340
341 template <class SuperPrefService, class ConstructionPrefRegistry>
342 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetRecommendedPref(const std::string & path,base::Value::List list)343 SetRecommendedPref(const std::string& path, base::Value::List list) {
344 SetRecommendedPref(path, std::make_unique<base::Value>(std::move(list)));
345 }
346
347 template <class SuperPrefService, class ConstructionPrefRegistry>
348 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemoveRecommendedPref(const std::string & path)349 RemoveRecommendedPref(const std::string& path) {
350 RemovePref(recommended_prefs_.get(), path);
351 }
352
353 template <class SuperPrefService, class ConstructionPrefRegistry>
354 const base::Value*
GetPref(TestingPrefStore * pref_store,const std::string & path)355 TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::GetPref(
356 TestingPrefStore* pref_store,
357 const std::string& path) const {
358 const base::Value* res;
359 return pref_store->GetValue(path, &res) ? res : NULL;
360 }
361
362 template <class SuperPrefService, class ConstructionPrefRegistry>
363 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetPref(TestingPrefStore * pref_store,const std::string & path,std::unique_ptr<base::Value> value)364 SetPref(TestingPrefStore* pref_store,
365 const std::string& path,
366 std::unique_ptr<base::Value> value) {
367 pref_store->SetValue(path, base::Value::FromUniquePtrValue(std::move(value)),
368 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
369 }
370
371 template <class SuperPrefService, class ConstructionPrefRegistry>
372 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
RemovePref(TestingPrefStore * pref_store,const std::string & path)373 RemovePref(TestingPrefStore* pref_store, const std::string& path) {
374 pref_store->RemoveValue(path, WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
375 }
376
377 template <class SuperPrefService, class ConstructionPrefRegistry>
378 void TestingPrefServiceBase<SuperPrefService, ConstructionPrefRegistry>::
SetInitializationCompleted()379 SetInitializationCompleted() {
380 managed_prefs_->SetInitializationCompleted();
381 supervised_user_prefs_->SetInitializationCompleted();
382 extension_prefs_->SetInitializationCompleted();
383 recommended_prefs_->SetInitializationCompleted();
384 // |user_prefs_| and |standalone_browser_prefs_| are initialized in
385 // PrefService constructor so no need to set initialization status again.
386 }
387
388 #endif // COMPONENTS_PREFS_TESTING_PREF_SERVICE_H_
389