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