1 // Copyright 2012 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 #ifndef COMPONENTS_PREFS_PREF_VALUE_STORE_H_ 6 #define COMPONENTS_PREFS_PREF_VALUE_STORE_H_ 7 8 #include <array> 9 #include <functional> 10 #include <map> 11 #include <memory> 12 #include <string> 13 #include <string_view> 14 #include <type_traits> 15 #include <vector> 16 17 #include "base/functional/callback.h" 18 #include "base/memory/raw_ptr.h" 19 #include "base/memory/ref_counted.h" 20 #include "base/values.h" 21 #include "components/prefs/pref_store.h" 22 #include "components/prefs/prefs_export.h" 23 24 class PrefNotifier; 25 class PrefStore; 26 27 // The PrefValueStore manages various sources of values for Preferences 28 // (e.g., configuration policies, extensions, and user settings). It returns 29 // the value of a Preference from the source with the highest priority, and 30 // allows setting user-defined values for preferences that are not managed. 31 // 32 // Unless otherwise explicitly noted, all of the methods of this class must 33 // be called on the UI thread. 34 class COMPONENTS_PREFS_EXPORT PrefValueStore { 35 public: 36 using PrefChangedCallback = base::RepeatingCallback<void(const std::string&)>; 37 38 // PrefStores must be listed here in order from highest to lowest priority. 39 // MANAGED contains all managed preferences that are provided by 40 // mandatory policies (e.g. Windows Group Policy or cloud policy). 41 // SUPERVISED_USER contains preferences that are valid for supervised users. 42 // EXTENSION contains preferences set by extensions. 43 // STANDALONE_BROWSER contains system preferences inherited from a separate 44 // Chrome instance. One relevant source is extension prefs in lacros 45 // passed to ash, so these prefs have similar precedence to extension 46 // prefs. 47 // COMMAND_LINE contains preferences set by command-line switches. 48 // USER contains all user-set preferences. 49 // RECOMMENDED contains all preferences that are provided by recommended 50 // policies. 51 // DEFAULT contains all application default preferences. 52 enum PrefStoreType { 53 // INVALID_STORE is not associated with an actual PrefStore but used as 54 // an invalid marker, e.g. as a return value. 55 INVALID_STORE = -1, 56 MANAGED_STORE = 0, 57 SUPERVISED_USER_STORE, 58 EXTENSION_STORE, 59 STANDALONE_BROWSER_STORE, 60 COMMAND_LINE_STORE, 61 USER_STORE, 62 RECOMMENDED_STORE, 63 DEFAULT_STORE, 64 PREF_STORE_TYPE_MAX = DEFAULT_STORE 65 }; 66 67 // In decreasing order of precedence: 68 // |managed_prefs| contains all preferences from mandatory policies. 69 // |supervised_user_prefs| contains all preferences from supervised user 70 // settings, i.e. settings configured for a supervised user by their 71 // custodian. 72 // |extension_prefs| contains preference values set by extensions. 73 // |command_line_prefs| contains preference values set by command-line 74 // switches. 75 // |user_prefs| contains all user-set preference values. 76 // |recommended_prefs| contains all preferences from recommended policies. 77 // |default_prefs| contains application-default preference values. It must 78 // be non-null if any preferences are to be registered. 79 // 80 // |pref_notifier| facilitates broadcasting preference change notifications 81 // to the world. 82 PrefValueStore(PrefStore* managed_prefs, 83 PrefStore* supervised_user_prefs, 84 PrefStore* extension_prefs, 85 PrefStore* standalone_browser_prefs, 86 PrefStore* command_line_prefs, 87 PrefStore* user_prefs, 88 PrefStore* recommended_prefs, 89 PrefStore* default_prefs, 90 PrefNotifier* pref_notifier); 91 92 PrefValueStore(const PrefValueStore&) = delete; 93 PrefValueStore& operator=(const PrefValueStore&) = delete; 94 95 virtual ~PrefValueStore(); 96 97 // Creates a clone of this PrefValueStore with PrefStores overwritten 98 // by the parameters passed, if unequal NULL. 99 // 100 // The new PrefValueStore is passed the |delegate| in its constructor. 101 std::unique_ptr<PrefValueStore> CloneAndSpecialize( 102 PrefStore* managed_prefs, 103 PrefStore* supervised_user_prefs, 104 PrefStore* extension_prefs, 105 PrefStore* standalone_browser_prefs, 106 PrefStore* command_line_prefs, 107 PrefStore* user_prefs, 108 PrefStore* recommended_prefs, 109 PrefStore* default_prefs, 110 PrefNotifier* pref_notifier); 111 112 // Returns the pref store type identifying the source that controls the 113 // Preference identified by |name|. If none of the sources has a value, 114 // INVALID_STORE is returned. In practice, the default PrefStore 115 // should always have a value for any registered preferencem, so INVALID_STORE 116 // indicates an error. 117 PrefStoreType ControllingPrefStoreForPref(const std::string& name) const; 118 119 // Gets the value for the given preference name that has the specified value 120 // type. Values stored in a PrefStore that have the matching |name| but 121 // a non-matching |type| are silently skipped. Returns true if a valid value 122 // was found in any of the available PrefStores. Most callers should use 123 // Preference::GetValue() instead of calling this method directly. 124 bool GetValue(std::string_view name, 125 base::Value::Type type, 126 const base::Value** out_value) const; 127 128 // Gets the recommended value for the given preference name that has the 129 // specified value type. A value stored in the recommended PrefStore that has 130 // the matching |name| but a non-matching |type| is silently ignored. Returns 131 // true if a valid value was found. Most callers should use 132 // Preference::GetRecommendedValue() instead of calling this method directly. 133 bool GetRecommendedValue(const std::string& name, 134 base::Value::Type type, 135 const base::Value** out_value) const; 136 137 // These methods return true if a preference with the given name is in the 138 // indicated pref store, even if that value is currently being overridden by 139 // a higher-priority source. 140 bool PrefValueInManagedStore(const std::string& name) const; 141 bool PrefValueInSupervisedStore(const std::string& name) const; 142 bool PrefValueInExtensionStore(const std::string& name) const; 143 bool PrefValueInUserStore(const std::string& name) const; 144 bool PrefValueInStandaloneBrowserStore(const std::string& name) const; 145 146 // These methods return true if a preference with the given name is actually 147 // being controlled by the indicated pref store and not being overridden by 148 // a higher-priority source. 149 bool PrefValueFromExtensionStore(const std::string& name) const; 150 bool PrefValueFromUserStore(const std::string& name) const; 151 bool PrefValueFromRecommendedStore(const std::string& name) const; 152 bool PrefValueFromDefaultStore(const std::string& name) const; 153 bool PrefValueFromStandaloneBrowserStore(const std::string& name) const; 154 155 // Check whether a Preference value is modifiable by the user, i.e. whether 156 // there is no higher-priority source controlling it. 157 bool PrefValueUserModifiable(const std::string& name) const; 158 159 // Check whether a Preference value is modifiable by an extension, i.e. 160 // whether there is no higher-priority source controlling it. 161 bool PrefValueExtensionModifiable(const std::string& name) const; 162 163 // Check whether a Preference value is modifiable by a standalone browser 164 // (lacros), i.e. whether there is no higher-priority source controlling it. 165 bool PrefValueStandaloneBrowserModifiable(const std::string& name) const; 166 167 // Update the command line PrefStore with |command_line_prefs|. 168 void UpdateCommandLinePrefStore(PrefStore* command_line_prefs); 169 170 bool IsInitializationComplete() const; 171 172 private: 173 // Keeps a PrefStore reference on behalf of the PrefValueStore and monitors 174 // the PrefStore for changes, forwarding notifications to PrefValueStore. This 175 // indirection is here for the sake of disambiguating notifications from the 176 // individual PrefStores. 177 class PrefStoreKeeper : public PrefStore::Observer { 178 public: 179 PrefStoreKeeper(); 180 181 PrefStoreKeeper(const PrefStoreKeeper&) = delete; 182 PrefStoreKeeper& operator=(const PrefStoreKeeper&) = delete; 183 184 ~PrefStoreKeeper() override; 185 186 // Takes ownership of |pref_store|. 187 void Initialize(PrefValueStore* store, 188 PrefStore* pref_store, 189 PrefStoreType type); 190 store()191 PrefStore* store() { return pref_store_.get(); } store()192 const PrefStore* store() const { return pref_store_.get(); } 193 194 private: 195 // PrefStore::Observer implementation. 196 void OnPrefValueChanged(std::string_view key) override; 197 void OnInitializationCompleted(bool succeeded) override; 198 199 // PrefValueStore this keeper is part of. 200 raw_ptr<PrefValueStore> pref_value_store_; 201 202 // The PrefStore managed by this keeper. 203 scoped_refptr<PrefStore> pref_store_; 204 205 // Type of the pref store. 206 PrefStoreType type_; 207 }; 208 209 typedef std::map<std::string, base::Value::Type> PrefTypeMap; 210 211 // Returns true if the preference with the given name has a value in the 212 // given PrefStoreType, of the same value type as the preference was 213 // registered with. 214 bool PrefValueInStore(const std::string& name, PrefStoreType store) const; 215 216 // Returns true if a preference has an explicit value in any of the 217 // stores in the range specified by |first_checked_store| and 218 // |last_checked_store|, even if that value is currently being 219 // overridden by a higher-priority store. 220 bool PrefValueInStoreRange(const std::string& name, 221 PrefStoreType first_checked_store, 222 PrefStoreType last_checked_store) const; 223 224 // Get a value from the specified |store|. 225 bool GetValueFromStore(std::string_view name, 226 PrefStoreType store, 227 const base::Value** out_value) const; 228 229 // Get a value from the specified |store| if its |type| matches. 230 bool GetValueFromStoreWithType(std::string_view name, 231 base::Value::Type type, 232 PrefStoreType store, 233 const base::Value** out_value) const; 234 235 // Called upon changes in individual pref stores in order to determine whether 236 // the user-visible pref value has changed. Triggers the change notification 237 // if the effective value of the preference has changed, or if the store 238 // controlling the pref has changed. 239 void NotifyPrefChanged(std::string_view, PrefStoreType new_store); 240 241 // Called from the PrefStoreKeeper implementation when a pref value for |key| 242 // changed in the pref store for |type|. 243 void OnPrefValueChanged(PrefStoreType type, std::string_view key); 244 245 // Handle the event that the store for |type| has completed initialization. 246 void OnInitializationCompleted(PrefStoreType type, bool succeeded); 247 248 // Initializes a pref store keeper. Sets up a PrefStoreKeeper that will take 249 // ownership of the passed |pref_store|. 250 void InitPrefStore(PrefStoreType type, PrefStore* pref_store); 251 252 // Checks whether initialization is completed and tells the notifier if that 253 // is the case. 254 void CheckInitializationCompleted(); 255 256 // Get the PrefStore pointer for the given type. May return NULL if there is 257 // no PrefStore for that type. GetPrefStore(PrefStoreType type)258 PrefStore* GetPrefStore(PrefStoreType type) { 259 return pref_stores_[type].store(); 260 } GetPrefStore(PrefStoreType type)261 const PrefStore* GetPrefStore(PrefStoreType type) const { 262 return pref_stores_[type].store(); 263 } 264 265 // Keeps the PrefStore references in order of precedence. 266 std::array<PrefStoreKeeper, PREF_STORE_TYPE_MAX + 1> pref_stores_; 267 268 // Used for generating notifications. This is a weak reference, 269 // since the notifier is owned by the corresponding PrefService. 270 raw_ptr<PrefNotifier> pref_notifier_; 271 272 // A mapping of preference names to their registered types. 273 PrefTypeMap pref_types_; 274 275 // True if not all of the PrefStores were initialized successfully. 276 bool initialization_failed_; 277 }; 278 279 namespace std { 280 281 template <> 282 struct hash<PrefValueStore::PrefStoreType> { 283 size_t operator()(PrefValueStore::PrefStoreType type) const { 284 return std::hash< 285 std::underlying_type<PrefValueStore::PrefStoreType>::type>()(type); 286 } 287 }; 288 289 } // namespace std 290 291 #endif // COMPONENTS_PREFS_PREF_VALUE_STORE_H_ 292