1 // Copyright 2013 The Chromium Authors 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 COMPONENTS_PREFS_SCOPED_USER_PREF_UPDATE_H_ 9 #define COMPONENTS_PREFS_SCOPED_USER_PREF_UPDATE_H_ 10 11 #include <string> 12 #include <string_view> 13 14 #include "base/memory/raw_ptr.h" 15 #include "base/memory/raw_ref.h" 16 #include "base/sequence_checker.h" 17 #include "base/values.h" 18 #include "components/prefs/pref_service.h" 19 #include "components/prefs/prefs_export.h" 20 21 class PrefService; 22 23 namespace subtle { 24 25 // Base class for ScopedUserPrefUpdateTemplate that contains the parts 26 // that do not depend on ScopedUserPrefUpdateTemplate's template parameter. 27 // 28 // We need this base class mostly for making it a friend of PrefService 29 // and getting access to PrefService::GetMutableUserPref and 30 // PrefService::ReportUserPrefChanged. 31 class COMPONENTS_PREFS_EXPORT ScopedUserPrefUpdateBase { 32 public: 33 ScopedUserPrefUpdateBase(const ScopedUserPrefUpdateBase&) = delete; 34 ScopedUserPrefUpdateBase& operator=(const ScopedUserPrefUpdateBase&) = delete; 35 36 protected: 37 ScopedUserPrefUpdateBase(PrefService* service, std::string_view path); 38 39 // Calls Notify(). 40 virtual ~ScopedUserPrefUpdateBase(); 41 42 // Sets `value_` to `service_`->GetMutableUserPref and returns it. 43 base::Value* GetValueOfType(base::Value::Type type); 44 45 private: 46 // If `value_` is not null, triggers a notification of PrefObservers and 47 // resets `value_`. 48 void Notify(); 49 50 // Weak pointer. 51 const raw_ref<PrefService> service_; 52 // Path of the preference being updated. 53 const std::string path_; 54 // Cache of value from user pref store (set between Get() and Notify() calls). 55 raw_ptr<base::Value> value_ = nullptr; 56 57 SEQUENCE_CHECKER(sequence_checker_); 58 }; 59 60 } // namespace subtle 61 62 // Class to support modifications to base::Value::Dicts while guaranteeing 63 // that PrefObservers are notified of changed values. 64 // 65 // This class may only be used on the UI thread as it requires access to the 66 // PrefService. 67 class COMPONENTS_PREFS_EXPORT ScopedDictPrefUpdate 68 : public subtle::ScopedUserPrefUpdateBase { 69 public: 70 // The underlying dictionary must not be removed from `service` during 71 // the lifetime of the created ScopedDictPrefUpdate. ScopedDictPrefUpdate(PrefService * service,std::string_view path)72 ScopedDictPrefUpdate(PrefService* service, std::string_view path) 73 : ScopedUserPrefUpdateBase(service, path) {} 74 75 ScopedDictPrefUpdate(const ScopedDictPrefUpdate&) = delete; 76 ScopedDictPrefUpdate& operator=(const ScopedDictPrefUpdate&) = delete; 77 78 // Triggers an update notification if Get() was called. 79 ~ScopedDictPrefUpdate() override = default; 80 81 // Returns a mutable `base::Value::Dict` instance that 82 // - is already in the user pref store, or 83 // - is (silently) created and written to the user pref store if none existed 84 // before. 85 // 86 // Calling Get() will result in an update notification automatically 87 // being triggered at destruction time. 88 // 89 // The ownership of the return value remains with the user pref store. 90 base::Value::Dict& Get(); 91 92 base::Value::Dict& operator*() { return Get(); } 93 94 base::Value::Dict* operator->() { return &Get(); } 95 }; 96 97 // Class to support modifications to base::Value::Lists while guaranteeing 98 // that PrefObservers are notified of changed values. 99 // 100 // This class may only be used on the UI thread as it requires access to the 101 // PrefService. 102 class COMPONENTS_PREFS_EXPORT ScopedListPrefUpdate 103 : public subtle::ScopedUserPrefUpdateBase { 104 public: 105 // The underlying list must not be removed from `service` during 106 // the lifetime of the created ScopedListPrefUpdate. ScopedListPrefUpdate(PrefService * service,std::string_view path)107 ScopedListPrefUpdate(PrefService* service, std::string_view path) 108 : ScopedUserPrefUpdateBase(service, path) {} 109 110 ScopedListPrefUpdate(const ScopedListPrefUpdate&) = delete; 111 ScopedListPrefUpdate& operator=(const ScopedListPrefUpdate&) = delete; 112 113 // Triggers an update notification if Get() was called. 114 ~ScopedListPrefUpdate() override = default; 115 116 // Returns a mutable `base::Value::List` instance that 117 // - is already in the user pref store, or 118 // - is (silently) created and written to the user pref store if none existed 119 // before. 120 // 121 // Calling Get() will result in an update notification automatically 122 // being triggered at destruction time. 123 // 124 // The ownership of the return value remains with the user pref store. 125 base::Value::List& Get(); 126 127 base::Value::List& operator*() { return Get(); } 128 129 base::Value::List* operator->() { return &Get(); } 130 }; 131 132 #endif // COMPONENTS_PREFS_SCOPED_USER_PREF_UPDATE_H_ 133