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