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