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: ScopedUserPrefUpdate(PrefService * service,const char * path)67 ScopedUserPrefUpdate(PrefService* service, const char* path) 68 : ScopedUserPrefUpdateBase(service, path) {} 69 70 // Triggers an update notification if Get() was called. ~ScopedUserPrefUpdate()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. Get()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