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