OLD | NEW |
| (Empty) |
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 CHROME_BROWSER_PREFS_PREF_VALUE_STORE_H_ | |
6 #define CHROME_BROWSER_PREFS_PREF_VALUE_STORE_H_ | |
7 | |
8 #include <map> | |
9 #include <string> | |
10 #include <vector> | |
11 | |
12 #include "base/basictypes.h" | |
13 #include "base/callback.h" | |
14 #include "base/gtest_prod_util.h" | |
15 #include "base/memory/ref_counted.h" | |
16 #include "base/prefs/pref_store.h" | |
17 #include "base/values.h" | |
18 | |
19 class PrefNotifier; | |
20 class PrefStore; | |
21 | |
22 // The PrefValueStore manages various sources of values for Preferences | |
23 // (e.g., configuration policies, extensions, and user settings). It returns | |
24 // the value of a Preference from the source with the highest priority, and | |
25 // allows setting user-defined values for preferences that are not managed. | |
26 // | |
27 // Unless otherwise explicitly noted, all of the methods of this class must | |
28 // be called on the UI thread. | |
29 class PrefValueStore { | |
30 public: | |
31 typedef base::Callback<void(const std::string&)> PrefChangedCallback; | |
32 | |
33 // In decreasing order of precedence: | |
34 // |managed_prefs| contains all preferences from mandatory policies. | |
35 // |extension_prefs| contains preference values set by extensions. | |
36 // |command_line_prefs| contains preference values set by command-line | |
37 // switches. | |
38 // |user_prefs| contains all user-set preference values. | |
39 // |recommended_prefs| contains all preferences from recommended policies. | |
40 // |default_prefs| contains application-default preference values. It must | |
41 // be non-null if any preferences are to be registered. | |
42 // | |
43 // |pref_notifier| facilitates broadcasting preference change notifications | |
44 // to the world. | |
45 PrefValueStore(PrefStore* managed_prefs, | |
46 PrefStore* extension_prefs, | |
47 PrefStore* command_line_prefs, | |
48 PrefStore* user_prefs, | |
49 PrefStore* recommended_prefs, | |
50 PrefStore* default_prefs, | |
51 PrefNotifier* pref_notifier); | |
52 virtual ~PrefValueStore(); | |
53 | |
54 // Creates a clone of this PrefValueStore with PrefStores overwritten | |
55 // by the parameters passed, if unequal NULL. | |
56 PrefValueStore* CloneAndSpecialize(PrefStore* managed_prefs, | |
57 PrefStore* extension_prefs, | |
58 PrefStore* command_line_prefs, | |
59 PrefStore* user_prefs, | |
60 PrefStore* recommended_prefs, | |
61 PrefStore* default_prefs, | |
62 PrefNotifier* pref_notifier); | |
63 | |
64 // A PrefValueStore can have exactly one callback that is directly | |
65 // notified of preferences changing in the store. This does not | |
66 // filter through the PrefNotifier mechanism, which may not forward | |
67 // certain changes (e.g. unregistered prefs). | |
68 void set_callback(const PrefChangedCallback& callback); | |
69 | |
70 // Gets the value for the given preference name that has the specified value | |
71 // type. Values stored in a PrefStore that have the matching |name| but | |
72 // a non-matching |type| are silently skipped. Returns true if a valid value | |
73 // was found in any of the available PrefStores. Most callers should use | |
74 // Preference::GetValue() instead of calling this method directly. | |
75 bool GetValue(const std::string& name, | |
76 base::Value::Type type, | |
77 const Value** out_value) const; | |
78 | |
79 // Gets the recommended value for the given preference name that has the | |
80 // specified value type. A value stored in the recommended PrefStore that has | |
81 // the matching |name| but a non-matching |type| is silently ignored. Returns | |
82 // true if a valid value was found. Most callers should use | |
83 // Preference::GetRecommendedValue() instead of calling this method directly. | |
84 bool GetRecommendedValue(const std::string& name, | |
85 base::Value::Type type, | |
86 const Value** out_value) const; | |
87 | |
88 // These methods return true if a preference with the given name is in the | |
89 // indicated pref store, even if that value is currently being overridden by | |
90 // a higher-priority source. | |
91 bool PrefValueInManagedStore(const char* name) const; | |
92 bool PrefValueInExtensionStore(const char* name) const; | |
93 bool PrefValueInUserStore(const char* name) const; | |
94 | |
95 // These methods return true if a preference with the given name is actually | |
96 // being controlled by the indicated pref store and not being overridden by | |
97 // a higher-priority source. | |
98 bool PrefValueFromExtensionStore(const char* name) const; | |
99 bool PrefValueFromUserStore(const char* name) const; | |
100 bool PrefValueFromRecommendedStore(const char* name) const; | |
101 bool PrefValueFromDefaultStore(const char* name) const; | |
102 | |
103 // Check whether a Preference value is modifiable by the user, i.e. whether | |
104 // there is no higher-priority source controlling it. | |
105 bool PrefValueUserModifiable(const char* name) const; | |
106 | |
107 // Check whether a Preference value is modifiable by an extension, i.e. | |
108 // whether there is no higher-priority source controlling it. | |
109 bool PrefValueExtensionModifiable(const char* name) const; | |
110 | |
111 // Update the command line PrefStore with |command_line_prefs|. | |
112 void UpdateCommandLinePrefStore(PrefStore* command_line_prefs); | |
113 | |
114 private: | |
115 // PrefStores must be listed here in order from highest to lowest priority. | |
116 // MANAGED contains all managed preference values that are provided by | |
117 // mandatory policies (e.g. Windows Group Policy or cloud policy). | |
118 // EXTENSION contains preference values set by extensions. | |
119 // COMMAND_LINE contains preference values set by command-line switches. | |
120 // USER contains all user-set preference values. | |
121 // RECOMMENDED contains all preferences that are provided by recommended | |
122 // policies. | |
123 // DEFAULT contains all application default preference values. | |
124 enum PrefStoreType { | |
125 // INVALID_STORE is not associated with an actual PrefStore but used as | |
126 // an invalid marker, e.g. as a return value. | |
127 INVALID_STORE = -1, | |
128 MANAGED_STORE = 0, | |
129 EXTENSION_STORE, | |
130 COMMAND_LINE_STORE, | |
131 USER_STORE, | |
132 RECOMMENDED_STORE, | |
133 DEFAULT_STORE, | |
134 PREF_STORE_TYPE_MAX = DEFAULT_STORE | |
135 }; | |
136 | |
137 // Keeps a PrefStore reference on behalf of the PrefValueStore and monitors | |
138 // the PrefStore for changes, forwarding notifications to PrefValueStore. This | |
139 // indirection is here for the sake of disambiguating notifications from the | |
140 // individual PrefStores. | |
141 class PrefStoreKeeper : public PrefStore::Observer { | |
142 public: | |
143 PrefStoreKeeper(); | |
144 virtual ~PrefStoreKeeper(); | |
145 | |
146 // Takes ownership of |pref_store|. | |
147 void Initialize(PrefValueStore* store, | |
148 PrefStore* pref_store, | |
149 PrefStoreType type); | |
150 | |
151 PrefStore* store() { return pref_store_.get(); } | |
152 const PrefStore* store() const { return pref_store_.get(); } | |
153 | |
154 private: | |
155 // PrefStore::Observer implementation. | |
156 virtual void OnPrefValueChanged(const std::string& key) OVERRIDE; | |
157 virtual void OnInitializationCompleted(bool succeeded) OVERRIDE; | |
158 | |
159 // PrefValueStore this keeper is part of. | |
160 PrefValueStore* pref_value_store_; | |
161 | |
162 // The PrefStore managed by this keeper. | |
163 scoped_refptr<PrefStore> pref_store_; | |
164 | |
165 // Type of the pref store. | |
166 PrefStoreType type_; | |
167 | |
168 DISALLOW_COPY_AND_ASSIGN(PrefStoreKeeper); | |
169 }; | |
170 | |
171 typedef std::map<std::string, base::Value::Type> PrefTypeMap; | |
172 | |
173 friend class PrefValueStorePolicyRefreshTest; | |
174 FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest, TestPolicyRefresh); | |
175 FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest, | |
176 TestRefreshPolicyPrefsCompletion); | |
177 FRIEND_TEST_ALL_PREFIXES(PrefValueStorePolicyRefreshTest, | |
178 TestConcurrentPolicyRefresh); | |
179 | |
180 // Returns true if the preference with the given name has a value in the | |
181 // given PrefStoreType, of the same value type as the preference was | |
182 // registered with. | |
183 bool PrefValueInStore(const char* name, PrefStoreType store) const; | |
184 | |
185 // Returns true if a preference has an explicit value in any of the | |
186 // stores in the range specified by |first_checked_store| and | |
187 // |last_checked_store|, even if that value is currently being | |
188 // overridden by a higher-priority store. | |
189 bool PrefValueInStoreRange(const char* name, | |
190 PrefStoreType first_checked_store, | |
191 PrefStoreType last_checked_store) const; | |
192 | |
193 // Returns the pref store type identifying the source that controls the | |
194 // Preference identified by |name|. If none of the sources has a value, | |
195 // INVALID_STORE is returned. In practice, the default PrefStore | |
196 // should always have a value for any registered preferencem, so INVALID_STORE | |
197 // indicates an error. | |
198 PrefStoreType ControllingPrefStoreForPref(const char* name) const; | |
199 | |
200 // Get a value from the specified |store|. | |
201 bool GetValueFromStore(const char* name, | |
202 PrefStoreType store, | |
203 const Value** out_value) const; | |
204 | |
205 // Get a value from the specified |store| if its |type| matches. | |
206 bool GetValueFromStoreWithType(const char* name, | |
207 base::Value::Type type, | |
208 PrefStoreType store, | |
209 const Value** out_value) const; | |
210 | |
211 // Called upon changes in individual pref stores in order to determine whether | |
212 // the user-visible pref value has changed. Triggers the change notification | |
213 // if the effective value of the preference has changed, or if the store | |
214 // controlling the pref has changed. | |
215 void NotifyPrefChanged(const char* path, PrefStoreType new_store); | |
216 | |
217 // Called from the PrefStoreKeeper implementation when a pref value for |key| | |
218 // changed in the pref store for |type|. | |
219 void OnPrefValueChanged(PrefStoreType type, const std::string& key); | |
220 | |
221 // Handle the event that the store for |type| has completed initialization. | |
222 void OnInitializationCompleted(PrefStoreType type, bool succeeded); | |
223 | |
224 // Initializes a pref store keeper. Sets up a PrefStoreKeeper that will take | |
225 // ownership of the passed |pref_store|. | |
226 void InitPrefStore(PrefStoreType type, PrefStore* pref_store); | |
227 | |
228 // Checks whether initialization is completed and tells the notifier if that | |
229 // is the case. | |
230 void CheckInitializationCompleted(); | |
231 | |
232 // Get the PrefStore pointer for the given type. May return NULL if there is | |
233 // no PrefStore for that type. | |
234 PrefStore* GetPrefStore(PrefStoreType type) { | |
235 return pref_stores_[type].store(); | |
236 } | |
237 const PrefStore* GetPrefStore(PrefStoreType type) const { | |
238 return pref_stores_[type].store(); | |
239 } | |
240 | |
241 // Keeps the PrefStore references in order of precedence. | |
242 PrefStoreKeeper pref_stores_[PREF_STORE_TYPE_MAX + 1]; | |
243 | |
244 PrefChangedCallback pref_changed_callback_; | |
245 | |
246 // Used for generating notifications. This is a weak reference, | |
247 // since the notifier is owned by the corresponding PrefService. | |
248 PrefNotifier* pref_notifier_; | |
249 | |
250 // A mapping of preference names to their registered types. | |
251 PrefTypeMap pref_types_; | |
252 | |
253 // True if not all of the PrefStores were initialized successfully. | |
254 bool initialization_failed_; | |
255 | |
256 DISALLOW_COPY_AND_ASSIGN(PrefValueStore); | |
257 }; | |
258 | |
259 #endif // CHROME_BROWSER_PREFS_PREF_VALUE_STORE_H_ | |
OLD | NEW |