1// Copyright (c) 2012 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#ifndef BASE_PREFS_TESTING_PREF_SERVICE_H_
6#define BASE_PREFS_TESTING_PREF_SERVICE_H_
7
8#include "base/memory/ref_counted.h"
9#include "base/memory/scoped_ptr.h"
10#include "base/prefs/pref_registry.h"
11#include "base/prefs/pref_service.h"
12#include "base/prefs/testing_pref_store.h"
13
14class PrefNotifierImpl;
15class PrefRegistrySimple;
16class TestingPrefStore;
17
18// A PrefService subclass for testing. It operates totally in memory and
19// provides additional API for manipulating preferences at the different levels
20// (managed, extension, user) conveniently.
21//
22// Use this via its specializations, e.g. TestingPrefServiceSimple.
23template <class SuperPrefService, class ConstructionPrefRegistry>
24class TestingPrefServiceBase : public SuperPrefService {
25 public:
26  virtual ~TestingPrefServiceBase();
27
28  // Read the value of a preference from the managed layer. Returns NULL if the
29  // preference is not defined at the managed layer.
30  const base::Value* GetManagedPref(const char* path) const;
31
32  // Set a preference on the managed layer and fire observers if the preference
33  // changed. Assumes ownership of |value|.
34  void SetManagedPref(const char* path, base::Value* value);
35
36  // Clear the preference on the managed layer and fire observers if the
37  // preference has been defined previously.
38  void RemoveManagedPref(const char* path);
39
40  // Similar to the above, but for user preferences.
41  const base::Value* GetUserPref(const char* path) const;
42  void SetUserPref(const char* path, base::Value* value);
43  void RemoveUserPref(const char* path);
44
45  // Similar to the above, but for recommended policy preferences.
46  const base::Value* GetRecommendedPref(const char* path) const;
47  void SetRecommendedPref(const char* path, base::Value* value);
48  void RemoveRecommendedPref(const char* path);
49
50  // Do-nothing implementation for TestingPrefService.
51  static void HandleReadError(PersistentPrefStore::PrefReadError error) {}
52
53 protected:
54  TestingPrefServiceBase(
55      TestingPrefStore* managed_prefs,
56      TestingPrefStore* user_prefs,
57      TestingPrefStore* recommended_prefs,
58      ConstructionPrefRegistry* pref_registry,
59      PrefNotifierImpl* pref_notifier);
60
61 private:
62  // Reads the value of the preference indicated by |path| from |pref_store|.
63  // Returns NULL if the preference was not found.
64  const base::Value* GetPref(TestingPrefStore* pref_store,
65                             const char* path) const;
66
67  // Sets the value for |path| in |pref_store|.
68  void SetPref(TestingPrefStore* pref_store, const char* path,
69               base::Value* value);
70
71  // Removes the preference identified by |path| from |pref_store|.
72  void RemovePref(TestingPrefStore* pref_store, const char* path);
73
74  // Pointers to the pref stores our value store uses.
75  scoped_refptr<TestingPrefStore> managed_prefs_;
76  scoped_refptr<TestingPrefStore> user_prefs_;
77  scoped_refptr<TestingPrefStore> recommended_prefs_;
78
79  DISALLOW_COPY_AND_ASSIGN(TestingPrefServiceBase);
80};
81
82// Test version of PrefService.
83class TestingPrefServiceSimple
84    : public TestingPrefServiceBase<PrefService, PrefRegistry> {
85 public:
86  TestingPrefServiceSimple();
87  virtual ~TestingPrefServiceSimple();
88
89  // This is provided as a convenience for registering preferences on
90  // an existing TestingPrefServiceSimple instance. On a production
91  // PrefService you would do all registrations before constructing
92  // it, passing it a PrefRegistry via its constructor (or via
93  // e.g. PrefServiceFactory).
94  PrefRegistrySimple* registry();
95
96 private:
97  DISALLOW_COPY_AND_ASSIGN(TestingPrefServiceSimple);
98};
99
100template<>
101TestingPrefServiceBase<PrefService, PrefRegistry>::TestingPrefServiceBase(
102    TestingPrefStore* managed_prefs,
103    TestingPrefStore* user_prefs,
104    TestingPrefStore* recommended_prefs,
105    PrefRegistry* pref_registry,
106    PrefNotifierImpl* pref_notifier);
107
108template<class SuperPrefService, class ConstructionPrefRegistry>
109TestingPrefServiceBase<
110    SuperPrefService, ConstructionPrefRegistry>::~TestingPrefServiceBase() {
111}
112
113template<class SuperPrefService, class ConstructionPrefRegistry>
114const base::Value* TestingPrefServiceBase<
115    SuperPrefService, ConstructionPrefRegistry>::GetManagedPref(
116        const char* path) const {
117  return GetPref(managed_prefs_.get(), path);
118}
119
120template<class SuperPrefService, class ConstructionPrefRegistry>
121void TestingPrefServiceBase<
122    SuperPrefService, ConstructionPrefRegistry>::SetManagedPref(
123        const char* path, base::Value* value) {
124  SetPref(managed_prefs_.get(), path, value);
125}
126
127template<class SuperPrefService, class ConstructionPrefRegistry>
128void TestingPrefServiceBase<
129    SuperPrefService, ConstructionPrefRegistry>::RemoveManagedPref(
130        const char* path) {
131  RemovePref(managed_prefs_.get(), path);
132}
133
134template<class SuperPrefService, class ConstructionPrefRegistry>
135const base::Value* TestingPrefServiceBase<
136    SuperPrefService, ConstructionPrefRegistry>::GetUserPref(
137        const char* path) const {
138  return GetPref(user_prefs_.get(), path);
139}
140
141template<class SuperPrefService, class ConstructionPrefRegistry>
142void TestingPrefServiceBase<
143    SuperPrefService, ConstructionPrefRegistry>::SetUserPref(
144        const char* path, base::Value* value) {
145  SetPref(user_prefs_.get(), path, value);
146}
147
148template<class SuperPrefService, class ConstructionPrefRegistry>
149void TestingPrefServiceBase<
150    SuperPrefService, ConstructionPrefRegistry>::RemoveUserPref(
151        const char* path) {
152  RemovePref(user_prefs_.get(), path);
153}
154
155template<class SuperPrefService, class ConstructionPrefRegistry>
156const base::Value* TestingPrefServiceBase<
157    SuperPrefService, ConstructionPrefRegistry>::GetRecommendedPref(
158        const char* path) const {
159  return GetPref(recommended_prefs_, path);
160}
161
162template<class SuperPrefService, class ConstructionPrefRegistry>
163void TestingPrefServiceBase<
164    SuperPrefService, ConstructionPrefRegistry>::SetRecommendedPref(
165        const char* path, base::Value* value) {
166  SetPref(recommended_prefs_.get(), path, value);
167}
168
169template<class SuperPrefService, class ConstructionPrefRegistry>
170void TestingPrefServiceBase<
171    SuperPrefService, ConstructionPrefRegistry>::RemoveRecommendedPref(
172        const char* path) {
173  RemovePref(recommended_prefs_.get(), path);
174}
175
176template<class SuperPrefService, class ConstructionPrefRegistry>
177const base::Value* TestingPrefServiceBase<
178    SuperPrefService, ConstructionPrefRegistry>::GetPref(
179        TestingPrefStore* pref_store, const char* path) const {
180  const base::Value* res;
181  return pref_store->GetValue(path, &res) ? res : NULL;
182}
183
184template<class SuperPrefService, class ConstructionPrefRegistry>
185void TestingPrefServiceBase<
186    SuperPrefService, ConstructionPrefRegistry>::SetPref(
187        TestingPrefStore* pref_store, const char* path, base::Value* value) {
188  pref_store->SetValue(path, value);
189}
190
191template<class SuperPrefService, class ConstructionPrefRegistry>
192void TestingPrefServiceBase<
193    SuperPrefService, ConstructionPrefRegistry>::RemovePref(
194        TestingPrefStore* pref_store, const char* path) {
195  pref_store->RemoveValue(path);
196}
197
198#endif  // BASE_PREFS_TESTING_PREF_SERVICE_H_
199