17f5b447eb4a6f3a1f58985b6e7be0b7dc718c5c
[platform/framework/web/crosswalk.git] / src / base / prefs / pref_member.h
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_PREF_MEMBER_H_
25 #define BASE_PREFS_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/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_.get(); }
275   virtual void CreateInternal() const OVERRIDE { internal_ = new Internal(); }
276
277   // This method is used to do the actual sync with pref of the specified type.
278   void BASE_PREFS_EXPORT UpdatePref(const ValueType& value);
279
280   mutable scoped_refptr<Internal> internal_;
281
282   DISALLOW_COPY_AND_ASSIGN(PrefMember);
283 };
284
285 // Declaration of template specialization need to be repeated here
286 // specifically for each specialization (rather than just once above)
287 // or at least one of our compilers won't be happy in all cases.
288 // Specifically, it was failing on ChromeOS with a complaint about
289 // PrefMember<FilePath>::UpdateValueInternal not being defined when
290 // built in a chroot with the following parameters:
291 //
292 // FEATURES="noclean nostrip" USE="-chrome_debug -chrome_remoting
293 // -chrome_internal -chrome_pdf component_build"
294 // ~/trunk/goma/goma-wrapper cros_chrome_make --board=${BOARD}
295 // --install --runhooks
296
297 template <>
298 BASE_PREFS_EXPORT void PrefMember<bool>::UpdatePref(const bool& value);
299
300 template <>
301 BASE_PREFS_EXPORT bool PrefMember<bool>::Internal::UpdateValueInternal(
302     const base::Value& value) const;
303
304 template <>
305 BASE_PREFS_EXPORT void PrefMember<int>::UpdatePref(const int& value);
306
307 template <>
308 BASE_PREFS_EXPORT bool PrefMember<int>::Internal::UpdateValueInternal(
309     const base::Value& value) const;
310
311 template <>
312 BASE_PREFS_EXPORT void PrefMember<double>::UpdatePref(const double& value);
313
314 template <>
315 BASE_PREFS_EXPORT bool PrefMember<double>::Internal::UpdateValueInternal(
316     const base::Value& value) const;
317
318 template <>
319 BASE_PREFS_EXPORT void PrefMember<std::string>::UpdatePref(
320     const std::string& value);
321
322 template <>
323 BASE_PREFS_EXPORT bool PrefMember<std::string>::Internal::UpdateValueInternal(
324     const base::Value& value) const;
325
326 template <>
327 BASE_PREFS_EXPORT void PrefMember<base::FilePath>::UpdatePref(
328     const base::FilePath& value);
329
330 template <>
331 BASE_PREFS_EXPORT bool
332 PrefMember<base::FilePath>::Internal::UpdateValueInternal(
333     const base::Value& value) const;
334
335 template <>
336 BASE_PREFS_EXPORT void PrefMember<std::vector<std::string> >::UpdatePref(
337     const std::vector<std::string>& value);
338
339 template <>
340 BASE_PREFS_EXPORT bool
341 PrefMember<std::vector<std::string> >::Internal::UpdateValueInternal(
342     const base::Value& value) const;
343
344 typedef PrefMember<bool> BooleanPrefMember;
345 typedef PrefMember<int> IntegerPrefMember;
346 typedef PrefMember<double> DoublePrefMember;
347 typedef PrefMember<std::string> StringPrefMember;
348 typedef PrefMember<base::FilePath> FilePathPrefMember;
349 // This preference member is expensive for large string arrays.
350 typedef PrefMember<std::vector<std::string> > StringListPrefMember;
351
352 #endif  // BASE_PREFS_PREF_MEMBER_H_