| 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, NULL /* no observer */); |  | 
|   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 CHROME_BROWSER_PREFS_PREF_MEMBER_H_ |  | 
|   25 #define CHROME_BROWSER_PREFS_PREF_MEMBER_H_ |  | 
|   26  |  | 
|   27 #include <string> |  | 
|   28  |  | 
|   29 #include "base/basictypes.h" |  | 
|   30 #include "base/file_path.h" |  | 
|   31 #include "base/logging.h" |  | 
|   32 #include "base/memory/ref_counted.h" |  | 
|   33 #include "base/values.h" |  | 
|   34 #include "content/public/browser/browser_thread.h" |  | 
|   35 #include "content/public/browser/notification_observer.h" |  | 
|   36  |  | 
|   37 class PrefService; |  | 
|   38  |  | 
|   39 namespace subtle { |  | 
|   40  |  | 
|   41 class PrefMemberBase : public content::NotificationObserver { |  | 
|   42  protected: |  | 
|   43   class Internal : public base::RefCountedThreadSafe<Internal> { |  | 
|   44    public: |  | 
|   45     Internal(); |  | 
|   46  |  | 
|   47     // Update the value, either by calling |UpdateValueInternal| directly |  | 
|   48     // or by dispatching to the right thread. |  | 
|   49     // Takes ownership of |value|. |  | 
|   50     virtual void UpdateValue(base::Value* value, bool is_managed) const; |  | 
|   51  |  | 
|   52     void MoveToThread(content::BrowserThread::ID thread_id); |  | 
|   53  |  | 
|   54     // See PrefMember<> for description. |  | 
|   55     bool IsManaged() const { |  | 
|   56       return is_managed_; |  | 
|   57     } |  | 
|   58  |  | 
|   59    protected: |  | 
|   60     friend class base::RefCountedThreadSafe<Internal>; |  | 
|   61     virtual ~Internal(); |  | 
|   62  |  | 
|   63     void CheckOnCorrectThread() const { |  | 
|   64       DCHECK(IsOnCorrectThread()); |  | 
|   65     } |  | 
|   66  |  | 
|   67    private: |  | 
|   68     // This method actually updates the value. It should only be called from |  | 
|   69     // the thread the PrefMember is on. |  | 
|   70     virtual bool UpdateValueInternal(const base::Value& value) const = 0; |  | 
|   71  |  | 
|   72     bool IsOnCorrectThread() const; |  | 
|   73  |  | 
|   74     content::BrowserThread::ID thread_id_; |  | 
|   75     mutable bool is_managed_; |  | 
|   76  |  | 
|   77     DISALLOW_COPY_AND_ASSIGN(Internal); |  | 
|   78   }; |  | 
|   79  |  | 
|   80   PrefMemberBase(); |  | 
|   81   virtual ~PrefMemberBase(); |  | 
|   82  |  | 
|   83   // See PrefMember<> for description. |  | 
|   84   void Init(const char* pref_name, PrefService* prefs, |  | 
|   85             content::NotificationObserver* observer); |  | 
|   86  |  | 
|   87   virtual void CreateInternal() const = 0; |  | 
|   88  |  | 
|   89   // See PrefMember<> for description. |  | 
|   90   void Destroy(); |  | 
|   91  |  | 
|   92   void MoveToThread(content::BrowserThread::ID thread_id); |  | 
|   93  |  | 
|   94   // content::NotificationObserver |  | 
|   95   virtual void Observe(int type, |  | 
|   96                        const content::NotificationSource& source, |  | 
|   97                        const content::NotificationDetails& details) OVERRIDE; |  | 
|   98  |  | 
|   99   void VerifyValuePrefName() const { |  | 
|  100     DCHECK(!pref_name_.empty()); |  | 
|  101   } |  | 
|  102  |  | 
|  103   // This method is used to do the actual sync with the preference. |  | 
|  104   // Note: it is logically const, because it doesn't modify the state |  | 
|  105   // seen by the outside world. It is just doing a lazy load behind the scenes. |  | 
|  106   virtual void UpdateValueFromPref() const; |  | 
|  107  |  | 
|  108   // Verifies the preference name, and lazily loads the preference value if |  | 
|  109   // it hasn't been loaded yet. |  | 
|  110   void VerifyPref() const; |  | 
|  111  |  | 
|  112   const std::string& pref_name() const { return pref_name_; } |  | 
|  113   PrefService* prefs() { return prefs_; } |  | 
|  114   const PrefService* prefs() const { return prefs_; } |  | 
|  115  |  | 
|  116   virtual Internal* internal() const = 0; |  | 
|  117  |  | 
|  118  private: |  | 
|  119   // Ordered the members to compact the class instance. |  | 
|  120   std::string pref_name_; |  | 
|  121   content::NotificationObserver* observer_; |  | 
|  122   PrefService* prefs_; |  | 
|  123  |  | 
|  124  protected: |  | 
|  125   bool setting_value_; |  | 
|  126 }; |  | 
|  127  |  | 
|  128 }  // namespace subtle |  | 
|  129  |  | 
|  130 template <typename ValueType> |  | 
|  131 class PrefMember : public subtle::PrefMemberBase { |  | 
|  132  public: |  | 
|  133   // Defer initialization to an Init method so it's easy to make this class be |  | 
|  134   // a member variable. |  | 
|  135   PrefMember() {} |  | 
|  136   virtual ~PrefMember() {} |  | 
|  137  |  | 
|  138   // Do the actual initialization of the class.  |observer| may be null if you |  | 
|  139   // don't want any notifications of changes. |  | 
|  140   // This method should only be called on the UI thread. |  | 
|  141   void Init(const char* pref_name, PrefService* prefs, |  | 
|  142             content::NotificationObserver* observer) { |  | 
|  143     subtle::PrefMemberBase::Init(pref_name, prefs, observer); |  | 
|  144   } |  | 
|  145  |  | 
|  146   // Unsubscribes the PrefMember from the PrefService. After calling this |  | 
|  147   // function, the PrefMember may not be used any more. |  | 
|  148   // This method should only be called on the UI thread. |  | 
|  149   void Destroy() { |  | 
|  150     subtle::PrefMemberBase::Destroy(); |  | 
|  151   } |  | 
|  152  |  | 
|  153   // Moves the PrefMember to another thread, allowing read accesses from there. |  | 
|  154   // Changes from the PrefService will be propagated asynchronously |  | 
|  155   // via PostTask. |  | 
|  156   // This method should only be used from the thread the PrefMember is currently |  | 
|  157   // on, which is the UI thread by default. |  | 
|  158   void MoveToThread(content::BrowserThread::ID thread_id) { |  | 
|  159     subtle::PrefMemberBase::MoveToThread(thread_id); |  | 
|  160   } |  | 
|  161  |  | 
|  162   // Check whether the pref is managed, i.e. controlled externally through |  | 
|  163   // enterprise configuration management (e.g. windows group policy). Returns |  | 
|  164   // false for unknown prefs. |  | 
|  165   // This method should only be used from the thread the PrefMember is currently |  | 
|  166   // on, which is the UI thread unless changed by |MoveToThread|. |  | 
|  167   bool IsManaged() const { |  | 
|  168     VerifyPref(); |  | 
|  169     return internal_->IsManaged(); |  | 
|  170   } |  | 
|  171  |  | 
|  172   // Retrieve the value of the member variable. |  | 
|  173   // This method should only be used from the thread the PrefMember is currently |  | 
|  174   // on, which is the UI thread unless changed by |MoveToThread|. |  | 
|  175   ValueType GetValue() const { |  | 
|  176     VerifyPref(); |  | 
|  177     return internal_->value(); |  | 
|  178   } |  | 
|  179  |  | 
|  180   // Provided as a convenience. |  | 
|  181   ValueType operator*() const { |  | 
|  182     return GetValue(); |  | 
|  183   } |  | 
|  184  |  | 
|  185   // Set the value of the member variable. |  | 
|  186   // This method should only be called on the UI thread. |  | 
|  187   void SetValue(const ValueType& value) { |  | 
|  188     VerifyValuePrefName(); |  | 
|  189     setting_value_ = true; |  | 
|  190     UpdatePref(value); |  | 
|  191     setting_value_ = false; |  | 
|  192   } |  | 
|  193  |  | 
|  194   // Set the value of the member variable if it is not managed. |  | 
|  195   // This method should only be called on the UI thread. |  | 
|  196   void SetValueIfNotManaged(const ValueType& value) { |  | 
|  197     if (!IsManaged()) { |  | 
|  198       SetValue(value); |  | 
|  199     } |  | 
|  200   } |  | 
|  201  |  | 
|  202   // Returns the pref name. |  | 
|  203   const std::string& GetPrefName() const { |  | 
|  204     return pref_name(); |  | 
|  205   } |  | 
|  206  |  | 
|  207  private: |  | 
|  208   class Internal : public subtle::PrefMemberBase::Internal { |  | 
|  209    public: |  | 
|  210     Internal() : value_(ValueType()) {} |  | 
|  211  |  | 
|  212     ValueType value() { |  | 
|  213       CheckOnCorrectThread(); |  | 
|  214       return value_; |  | 
|  215     } |  | 
|  216  |  | 
|  217    protected: |  | 
|  218     virtual ~Internal() {} |  | 
|  219  |  | 
|  220     virtual bool UpdateValueInternal(const base::Value& value) const; |  | 
|  221  |  | 
|  222     // We cache the value of the pref so we don't have to keep walking the pref |  | 
|  223     // tree. |  | 
|  224     mutable ValueType value_; |  | 
|  225  |  | 
|  226     DISALLOW_COPY_AND_ASSIGN(Internal); |  | 
|  227   }; |  | 
|  228  |  | 
|  229   virtual Internal* internal() const { return internal_; } |  | 
|  230   virtual void CreateInternal() const { |  | 
|  231     internal_ = new Internal(); |  | 
|  232   } |  | 
|  233  |  | 
|  234   // This method is used to do the actual sync with pref of the specified type. |  | 
|  235   virtual void UpdatePref(const ValueType& value); |  | 
|  236  |  | 
|  237   mutable scoped_refptr<Internal> internal_; |  | 
|  238  |  | 
|  239   DISALLOW_COPY_AND_ASSIGN(PrefMember); |  | 
|  240 }; |  | 
|  241  |  | 
|  242 typedef PrefMember<bool> BooleanPrefMember; |  | 
|  243 typedef PrefMember<int> IntegerPrefMember; |  | 
|  244 typedef PrefMember<double> DoublePrefMember; |  | 
|  245 typedef PrefMember<std::string> StringPrefMember; |  | 
|  246 typedef PrefMember<FilePath> FilePathPrefMember; |  | 
|  247  |  | 
|  248 #endif  // CHROME_BROWSER_PREFS_PREF_MEMBER_H_ |  | 
| OLD | NEW |