Home | History | Annotate | Download | only in prefs
      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 assists preferences in firing notifications when lists
      6 // or dictionaries are changed.
      7 
      8 #ifndef CHROME_BROWSER_PREFS_SCOPED_USER_PREF_UPDATE_H_
      9 #define CHROME_BROWSER_PREFS_SCOPED_USER_PREF_UPDATE_H_
     10 
     11 #include <string>
     12 
     13 #include "base/basictypes.h"
     14 #include "base/prefs/pref_service.h"
     15 #include "base/threading/non_thread_safe.h"
     16 #include "base/values.h"
     17 
     18 class PrefService;
     19 
     20 namespace base {
     21 class DictionaryValue;
     22 class ListValue;
     23 }
     24 
     25 namespace subtle {
     26 
     27 // Base class for ScopedUserPrefUpdateTemplate that contains the parts
     28 // that do not depend on ScopedUserPrefUpdateTemplate's template parameter.
     29 //
     30 // We need this base class mostly for making it a friend of PrefService
     31 // and getting access to PrefService::GetMutableUserPref and
     32 // PrefService::ReportUserPrefChanged.
     33 class ScopedUserPrefUpdateBase : public base::NonThreadSafe {
     34  protected:
     35   ScopedUserPrefUpdateBase(PrefService* service, const char* path);
     36 
     37   // Calls Notify().
     38   ~ScopedUserPrefUpdateBase();
     39 
     40   // Sets |value_| to |service_|->GetMutableUserPref and returns it.
     41   base::Value* GetValueOfType(base::Value::Type type);
     42 
     43  private:
     44   // If |value_| is not null, triggers a notification of PrefObservers and
     45   // resets |value_|.
     46   void Notify();
     47 
     48   // Weak pointer.
     49   PrefService* service_;
     50   // Path of the preference being updated.
     51   std::string path_;
     52   // Cache of value from user pref store (set between Get() and Notify() calls).
     53   base::Value* value_;
     54 
     55   DISALLOW_COPY_AND_ASSIGN(ScopedUserPrefUpdateBase);
     56 };
     57 
     58 }  // namespace subtle
     59 
     60 // Class to support modifications to DictionaryValues and ListValues while
     61 // guaranteeing that PrefObservers are notified of changed values.
     62 //
     63 // This class may only be used on the UI thread as it requires access to the
     64 // PrefService.
     65 template <typename T, base::Value::Type type_enum_value>
     66 class ScopedUserPrefUpdate : public subtle::ScopedUserPrefUpdateBase {
     67  public:
     68   ScopedUserPrefUpdate(PrefService* service, const char* path)
     69       : ScopedUserPrefUpdateBase(service, path) {}
     70 
     71   // Triggers an update notification if Get() was called.
     72   virtual ~ScopedUserPrefUpdate() {}
     73 
     74   // Returns a mutable |T| instance that
     75   // - is already in the user pref store, or
     76   // - is (silently) created and written to the user pref store if none existed
     77   //   before.
     78   //
     79   // Calling Get() implies that an update notification is necessary at
     80   // destruction time.
     81   //
     82   // The ownership of the return value remains with the user pref store.
     83   // Virtual so it can be overriden in subclasses that transform the value
     84   // before returning it (for example to return a subelement of a dictionary).
     85   virtual T* Get() {
     86     return static_cast<T*>(GetValueOfType(type_enum_value));
     87   }
     88 
     89   T& operator*() {
     90     return *Get();
     91   }
     92 
     93   T* operator->() {
     94     return Get();
     95   }
     96 
     97  private:
     98   DISALLOW_COPY_AND_ASSIGN(ScopedUserPrefUpdate);
     99 };
    100 
    101 typedef ScopedUserPrefUpdate<base::DictionaryValue,
    102                              base::Value::TYPE_DICTIONARY>
    103     DictionaryPrefUpdate;
    104 typedef ScopedUserPrefUpdate<base::ListValue, base::Value::TYPE_LIST>
    105     ListPrefUpdate;
    106 
    107 #endif  // CHROME_BROWSER_PREFS_SCOPED_USER_PREF_UPDATE_H_
    108