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 // A helper class that stays in sync with a preference (bool, int, real, | |
6 // string or filepath). For example: | |
7 // | |
8 // class MyClass { | |
9 // public: | |
10 // MyClass(PrefService* prefs) { | |
11 // my_string_.Init(prefs::kHomePage, prefs); | |
12 // } | |
13 // private: | |
14 // StringPrefMember my_string_; | |
15 // }; | |
16 // | |
17 // my_string_ should stay in sync with the prefs::kHomePage pref and will | |
18 // update if either the pref changes or if my_string_.SetValue is called. | |
19 // | |
20 // An optional observer can be passed into the Init method which can be used to | |
21 // notify MyClass of changes. Note that if you use SetValue(), the observer | |
22 // will not be notified. | |
23 | |
24 #ifndef BASE_PREFS_PUBLIC_PREF_MEMBER_H_ | |
25 #define BASE_PREFS_PUBLIC_PREF_MEMBER_H_ | |
26 | |
27 #include <string> | |
28 #include <vector> | |
29 | |
30 #include "base/basictypes.h" | |
31 #include "base/bind.h" | |
32 #include "base/callback_forward.h" | |
33 #include "base/files/file_path.h" | |
34 #include "base/logging.h" | |
35 #include "base/memory/ref_counted.h" | |
36 #include "base/message_loop_proxy.h" | |
37 #include "base/prefs/base_prefs_export.h" | |
38 #include "base/prefs/pref_observer.h" | |
39 #include "base/values.h" | |
40 | |
41 class PrefService; | |
42 | |
43 namespace subtle { | |
44 | |
45 class BASE_PREFS_EXPORT PrefMemberBase : public PrefObserver { | |
46 public: | |
47 // Type of callback you can register if you need to know the name of | |
48 // the pref that is changing. | |
49 typedef base::Callback<void(const std::string&)> NamedChangeCallback; | |
50 | |
51 PrefService* prefs() { return prefs_; } | |
52 const PrefService* prefs() const { return prefs_; } | |
53 | |
54 protected: | |
55 class BASE_PREFS_EXPORT Internal | |
56 : public base::RefCountedThreadSafe<Internal> { | |
57 public: | |
58 Internal(); | |
59 | |
60 // Update the value, either by calling |UpdateValueInternal| directly | |
61 // or by dispatching to the right thread. | |
62 // Takes ownership of |value|. | |
63 void UpdateValue(base::Value* value, | |
64 bool is_managed, | |
65 bool is_user_modifiable, | |
66 const base::Closure& callback) const; | |
67 | |
68 void MoveToThread( | |
69 const scoped_refptr<base::MessageLoopProxy>& message_loop); | |
70 | |
71 // See PrefMember<> for description. | |
72 bool IsManaged() const { | |
73 return is_managed_; | |
74 } | |
75 | |
76 bool IsUserModifiable() const { | |
77 return is_user_modifiable_; | |
78 } | |
79 | |
80 protected: | |
81 friend class base::RefCountedThreadSafe<Internal>; | |
82 virtual ~Internal(); | |
83 | |
84 void CheckOnCorrectThread() const { | |
85 DCHECK(IsOnCorrectThread()); | |
86 } | |
87 | |
88 private: | |
89 // This method actually updates the value. It should only be called from | |
90 // the thread the PrefMember is on. | |
91 virtual bool UpdateValueInternal(const base::Value& value) const = 0; | |
92 | |
93 bool IsOnCorrectThread() const; | |
94 | |
95 scoped_refptr<base::MessageLoopProxy> thread_loop_; | |
96 mutable bool is_managed_; | |
97 mutable bool is_user_modifiable_; | |
98 | |
99 DISALLOW_COPY_AND_ASSIGN(Internal); | |
100 }; | |
101 | |
102 PrefMemberBase(); | |
103 virtual ~PrefMemberBase(); | |
104 | |
105 // See PrefMember<> for description. | |
106 void Init(const char* pref_name, PrefService* prefs, | |
107 const NamedChangeCallback& observer); | |
108 void Init(const char* pref_name, PrefService* prefs); | |
109 | |
110 virtual void CreateInternal() const = 0; | |
111 | |
112 // See PrefMember<> for description. | |
113 void Destroy(); | |
114 | |
115 void MoveToThread(const scoped_refptr<base::MessageLoopProxy>& message_loop); | |
116 | |
117 // PrefObserver | |
118 virtual void OnPreferenceChanged(PrefService* service, | |
119 const std::string& pref_name) OVERRIDE; | |
120 | |
121 void VerifyValuePrefName() const { | |
122 DCHECK(!pref_name_.empty()); | |
123 } | |
124 | |
125 // This method is used to do the actual sync with the preference. | |
126 // Note: it is logically const, because it doesn't modify the state | |
127 // seen by the outside world. It is just doing a lazy load behind the scenes. | |
128 void UpdateValueFromPref(const base::Closure& callback) const; | |
129 | |
130 // Verifies the preference name, and lazily loads the preference value if | |
131 // it hasn't been loaded yet. | |
132 void VerifyPref() const; | |
133 | |
134 const std::string& pref_name() const { return pref_name_; } | |
135 | |
136 virtual Internal* internal() const = 0; | |
137 | |
138 // Used to allow registering plain base::Closure callbacks. | |
139 static void InvokeUnnamedCallback(const base::Closure& callback, | |
140 const std::string& pref_name); | |
141 | |
142 private: | |
143 // Ordered the members to compact the class instance. | |
144 std::string pref_name_; | |
145 NamedChangeCallback observer_; | |
146 PrefService* prefs_; | |
147 | |
148 protected: | |
149 bool setting_value_; | |
150 }; | |
151 | |
152 // This function implements StringListPrefMember::UpdateValue(). | |
153 // It is exposed here for testing purposes. | |
154 bool BASE_PREFS_EXPORT PrefMemberVectorStringUpdate( | |
155 const base::Value& value, | |
156 std::vector<std::string>* string_vector); | |
157 | |
158 } // namespace subtle | |
159 | |
160 template <typename ValueType> | |
161 class PrefMember : public subtle::PrefMemberBase { | |
162 public: | |
163 // Defer initialization to an Init method so it's easy to make this class be | |
164 // a member variable. | |
165 PrefMember() {} | |
166 virtual ~PrefMember() {} | |
167 | |
168 // Do the actual initialization of the class. Use the two-parameter | |
169 // version if you don't want any notifications of changes. This | |
170 // method should only be called on the UI thread. | |
171 void Init(const char* pref_name, PrefService* prefs, | |
172 const NamedChangeCallback& observer) { | |
173 subtle::PrefMemberBase::Init(pref_name, prefs, observer); | |
174 } | |
175 void Init(const char* pref_name, PrefService* prefs, | |
176 const base::Closure& observer) { | |
177 subtle::PrefMemberBase::Init( | |
178 pref_name, prefs, | |
179 base::Bind(&PrefMemberBase::InvokeUnnamedCallback, observer)); | |
180 } | |
181 void Init(const char* pref_name, PrefService* prefs) { | |
182 subtle::PrefMemberBase::Init(pref_name, prefs); | |
183 } | |
184 | |
185 // Unsubscribes the PrefMember from the PrefService. After calling this | |
186 // function, the PrefMember may not be used any more on the UI thread. | |
187 // Assuming |MoveToThread| was previously called, |GetValue|, |IsManaged|, | |
188 // and |IsUserModifiable| can still be called from the other thread but | |
189 // the results will no longer update from the PrefService. | |
190 // This method should only be called on the UI thread. | |
191 void Destroy() { | |
192 subtle::PrefMemberBase::Destroy(); | |
193 } | |
194 | |
195 // Moves the PrefMember to another thread, allowing read accesses from there. | |
196 // Changes from the PrefService will be propagated asynchronously | |
197 // via PostTask. | |
198 // This method should only be used from the thread the PrefMember is currently | |
199 // on, which is the UI thread by default. | |
200 void MoveToThread(const scoped_refptr<base::MessageLoopProxy>& message_loop) { | |
201 subtle::PrefMemberBase::MoveToThread(message_loop); | |
202 } | |
203 | |
204 // Check whether the pref is managed, i.e. controlled externally through | |
205 // enterprise configuration management (e.g. windows group policy). Returns | |
206 // false for unknown prefs. | |
207 // This method should only be used from the thread the PrefMember is currently | |
208 // on, which is the UI thread unless changed by |MoveToThread|. | |
209 bool IsManaged() const { | |
210 VerifyPref(); | |
211 return internal_->IsManaged(); | |
212 } | |
213 | |
214 // Checks whether the pref can be modified by the user. This returns false | |
215 // when the pref is managed by a policy or an extension, and when a command | |
216 // line flag overrides the pref. | |
217 // This method should only be used from the thread the PrefMember is currently | |
218 // on, which is the UI thread unless changed by |MoveToThread|. | |
219 bool IsUserModifiable() const { | |
220 VerifyPref(); | |
221 return internal_->IsUserModifiable(); | |
222 } | |
223 | |
224 // Retrieve the value of the member variable. | |
225 // This method should only be used from the thread the PrefMember is currently | |
226 // on, which is the UI thread unless changed by |MoveToThread|. | |
227 ValueType GetValue() const { | |
228 VerifyPref(); | |
229 return internal_->value(); | |
230 } | |
231 | |
232 // Provided as a convenience. | |
233 ValueType operator*() const { | |
234 return GetValue(); | |
235 } | |
236 | |
237 // Set the value of the member variable. | |
238 // This method should only be called on the UI thread. | |
239 void SetValue(const ValueType& value) { | |
240 VerifyValuePrefName(); | |
241 setting_value_ = true; | |
242 UpdatePref(value); | |
243 setting_value_ = false; | |
244 } | |
245 | |
246 // Returns the pref name. | |
247 const std::string& GetPrefName() const { | |
248 return pref_name(); | |
249 } | |
250 | |
251 private: | |
252 class Internal : public subtle::PrefMemberBase::Internal { | |
253 public: | |
254 Internal() : value_(ValueType()) {} | |
255 | |
256 ValueType value() { | |
257 CheckOnCorrectThread(); | |
258 return value_; | |
259 } | |
260 | |
261 protected: | |
262 virtual ~Internal() {} | |
263 | |
264 virtual BASE_PREFS_EXPORT bool UpdateValueInternal( | |
265 const base::Value& value) const OVERRIDE; | |
266 | |
267 // We cache the value of the pref so we don't have to keep walking the pref | |
268 // tree. | |
269 mutable ValueType value_; | |
270 | |
271 DISALLOW_COPY_AND_ASSIGN(Internal); | |
272 }; | |
273 | |
274 virtual Internal* internal() const OVERRIDE { return internal_; } | |
275 virtual void CreateInternal() const OVERRIDE { | |
276 internal_ = new Internal(); | |
277 } | |
278 | |
279 // This method is used to do the actual sync with pref of the specified type. | |
280 void BASE_PREFS_EXPORT UpdatePref(const ValueType& value); | |
281 | |
282 mutable scoped_refptr<Internal> internal_; | |
283 | |
284 DISALLOW_COPY_AND_ASSIGN(PrefMember); | |
285 }; | |
286 | |
287 // Declaration of template specialization need to be repeated here | |
288 // specifically for each specialization (rather than just once above) | |
289 // or at least one of our compilers won't be happy in all cases. | |
290 // Specifically, it was failing on ChromeOS with a complaint about | |
291 // PrefMember<FilePath>::UpdateValueInternal not being defined when | |
292 // built in a chroot with the following parameters: | |
293 // | |
294 // FEATURES="noclean nostrip" USE="-chrome_debug -chrome_remoting | |
295 // -chrome_internal -chrome_pdf component_build" | |
296 // ~/trunk/goma/goma-wrapper cros_chrome_make --board=${BOARD} | |
297 // --install --runhooks | |
298 | |
299 template <> | |
300 BASE_PREFS_EXPORT void PrefMember<bool>::UpdatePref(const bool& value); | |
301 | |
302 template <> | |
303 BASE_PREFS_EXPORT bool PrefMember<bool>::Internal::UpdateValueInternal( | |
304 const Value& value) const; | |
305 | |
306 template <> | |
307 BASE_PREFS_EXPORT void PrefMember<int>::UpdatePref(const int& value); | |
308 | |
309 template <> | |
310 BASE_PREFS_EXPORT bool PrefMember<int>::Internal::UpdateValueInternal( | |
311 const Value& value) const; | |
312 | |
313 template <> | |
314 BASE_PREFS_EXPORT void PrefMember<double>::UpdatePref(const double& value); | |
315 | |
316 template <> | |
317 BASE_PREFS_EXPORT bool PrefMember<double>::Internal::UpdateValueInternal( | |
318 const Value& value) const; | |
319 | |
320 template <> | |
321 BASE_PREFS_EXPORT void PrefMember<std::string>::UpdatePref( | |
322 const std::string& value); | |
323 | |
324 template <> | |
325 BASE_PREFS_EXPORT bool PrefMember<std::string>::Internal::UpdateValueInternal( | |
326 const base::Value& value) const; | |
327 | |
328 template <> | |
329 BASE_PREFS_EXPORT void PrefMember<base::FilePath>::UpdatePref( | |
330 const base::FilePath& value); | |
331 | |
332 template <> | |
333 BASE_PREFS_EXPORT bool | |
334 PrefMember<base::FilePath>::Internal::UpdateValueInternal( | |
335 const base::Value& value) const; | |
336 | |
337 template <> | |
338 BASE_PREFS_EXPORT void PrefMember<std::vector<std::string> >::UpdatePref( | |
339 const std::vector<std::string>& value); | |
340 | |
341 template <> | |
342 BASE_PREFS_EXPORT bool | |
343 PrefMember<std::vector<std::string> >::Internal::UpdateValueInternal( | |
344 const base::Value& value) const; | |
345 | |
346 typedef PrefMember<bool> BooleanPrefMember; | |
347 typedef PrefMember<int> IntegerPrefMember; | |
348 typedef PrefMember<double> DoublePrefMember; | |
349 typedef PrefMember<std::string> StringPrefMember; | |
350 typedef PrefMember<base::FilePath> FilePathPrefMember; | |
351 // This preference member is expensive for large string arrays. | |
352 typedef PrefMember<std::vector<std::string> > StringListPrefMember; | |
353 | |
354 #endif // BASE_PREFS_PUBLIC_PREF_MEMBER_H_ | |
OLD | NEW |