brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 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 | |
brettw | 06650868 | 2016-02-03 08:22:02 | [diff] [blame] | 5 | #ifndef COMPONENTS_PREFS_PREF_VALUE_STORE_H_ |
| 6 | #define COMPONENTS_PREFS_PREF_VALUE_STORE_H_ |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 7 | |
Lei Zhang | 2cdf35c | 2019-03-29 01:33:07 | [diff] [blame] | 8 | #include <functional> |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 9 | #include <map> |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 10 | #include <memory> |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 11 | #include <string> |
danakj | 6d0446e5 | 2017-04-05 16:22:29 | [diff] [blame] | 12 | #include <type_traits> |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 13 | #include <vector> |
| 14 | |
| 15 | #include "base/callback.h" |
| 16 | #include "base/macros.h" |
| 17 | #include "base/memory/ref_counted.h" |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 18 | #include "base/values.h" |
brettw | f00b9b4 | 2016-02-01 22:11:38 | [diff] [blame] | 19 | #include "components/prefs/pref_store.h" |
Brett Wilson | 5c6cf26 | 2017-09-09 02:05:54 | [diff] [blame] | 20 | #include "components/prefs/prefs_export.h" |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 21 | |
Sam McNally | 538fca1e | 2017-07-14 03:10:43 | [diff] [blame] | 22 | class PersistentPrefStore; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 23 | class PrefNotifier; |
Sam McNally | 538fca1e | 2017-07-14 03:10:43 | [diff] [blame] | 24 | class PrefRegistry; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 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. |
brettw | 06650868 | 2016-02-03 08:22:02 | [diff] [blame] | 34 | class COMPONENTS_PREFS_EXPORT PrefValueStore { |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 35 | public: |
danakj | edfd5d7 | 2019-12-13 21:14:34 | [diff] [blame] | 36 | using PrefChangedCallback = base::RepeatingCallback<void(const std::string&)>; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 37 | |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 38 | // Delegate used to observe certain events in the |PrefValueStore|'s lifetime. |
| 39 | class Delegate { |
| 40 | public: |
| 41 | virtual ~Delegate() {} |
| 42 | |
| 43 | // Called by the PrefValueStore constructor with the PrefStores passed to |
| 44 | // it. |
| 45 | virtual void Init(PrefStore* managed_prefs, |
| 46 | PrefStore* supervised_user_prefs, |
| 47 | PrefStore* extension_prefs, |
| 48 | PrefStore* command_line_prefs, |
| 49 | PrefStore* user_prefs, |
| 50 | PrefStore* recommended_prefs, |
| 51 | PrefStore* default_prefs, |
| 52 | PrefNotifier* pref_notifier) = 0; |
| 53 | |
Sam McNally | aa67d7f2 | 2017-09-04 03:34:06 | [diff] [blame] | 54 | virtual void InitIncognitoUserPrefs( |
| 55 | scoped_refptr<PersistentPrefStore> incognito_user_prefs_overlay, |
| 56 | scoped_refptr<PersistentPrefStore> incognito_user_prefs_underlay, |
| 57 | const std::vector<const char*>& overlay_pref_names) = 0; |
Sam McNally | 538fca1e | 2017-07-14 03:10:43 | [diff] [blame] | 58 | |
| 59 | virtual void InitPrefRegistry(PrefRegistry* pref_registry) = 0; |
| 60 | |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 61 | // Called whenever PrefValueStore::UpdateCommandLinePrefStore is called, |
| 62 | // with the same argument. |
| 63 | virtual void UpdateCommandLinePrefStore(PrefStore* command_line_prefs) = 0; |
| 64 | }; |
| 65 | |
tibell | 11141bd | 2017-03-10 00:16:29 | [diff] [blame] | 66 | // PrefStores must be listed here in order from highest to lowest priority. |
| 67 | // MANAGED contains all managed preference values that are provided by |
| 68 | // mandatory policies (e.g. Windows Group Policy or cloud policy). |
| 69 | // SUPERVISED_USER contains preferences that are valid for supervised users. |
| 70 | // EXTENSION contains preference values set by extensions. |
| 71 | // COMMAND_LINE contains preference values set by command-line switches. |
| 72 | // USER contains all user-set preference values. |
| 73 | // RECOMMENDED contains all preferences that are provided by recommended |
| 74 | // policies. |
| 75 | // DEFAULT contains all application default preference values. |
| 76 | enum PrefStoreType { |
| 77 | // INVALID_STORE is not associated with an actual PrefStore but used as |
| 78 | // an invalid marker, e.g. as a return value. |
| 79 | INVALID_STORE = -1, |
| 80 | MANAGED_STORE = 0, |
| 81 | SUPERVISED_USER_STORE, |
| 82 | EXTENSION_STORE, |
| 83 | COMMAND_LINE_STORE, |
| 84 | USER_STORE, |
| 85 | RECOMMENDED_STORE, |
| 86 | DEFAULT_STORE, |
| 87 | PREF_STORE_TYPE_MAX = DEFAULT_STORE |
| 88 | }; |
| 89 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 90 | // In decreasing order of precedence: |
| 91 | // |managed_prefs| contains all preferences from mandatory policies. |
| 92 | // |supervised_user_prefs| contains all preferences from supervised user |
| 93 | // settings, i.e. settings configured for a supervised user by their |
| 94 | // custodian. |
| 95 | // |extension_prefs| contains preference values set by extensions. |
| 96 | // |command_line_prefs| contains preference values set by command-line |
| 97 | // switches. |
| 98 | // |user_prefs| contains all user-set preference values. |
| 99 | // |recommended_prefs| contains all preferences from recommended policies. |
| 100 | // |default_prefs| contains application-default preference values. It must |
| 101 | // be non-null if any preferences are to be registered. |
| 102 | // |
| 103 | // |pref_notifier| facilitates broadcasting preference change notifications |
| 104 | // to the world. |
| 105 | PrefValueStore(PrefStore* managed_prefs, |
| 106 | PrefStore* supervised_user_prefs, |
| 107 | PrefStore* extension_prefs, |
| 108 | PrefStore* command_line_prefs, |
| 109 | PrefStore* user_prefs, |
| 110 | PrefStore* recommended_prefs, |
| 111 | PrefStore* default_prefs, |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 112 | PrefNotifier* pref_notifier, |
| 113 | std::unique_ptr<Delegate> delegate = nullptr); |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 114 | virtual ~PrefValueStore(); |
| 115 | |
| 116 | // Creates a clone of this PrefValueStore with PrefStores overwritten |
| 117 | // by the parameters passed, if unequal NULL. |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 118 | // |
| 119 | // The new PrefValueStore is passed the |delegate| in its constructor. |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 120 | std::unique_ptr<PrefValueStore> CloneAndSpecialize( |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 121 | PrefStore* managed_prefs, |
| 122 | PrefStore* supervised_user_prefs, |
| 123 | PrefStore* extension_prefs, |
| 124 | PrefStore* command_line_prefs, |
| 125 | PrefStore* user_prefs, |
| 126 | PrefStore* recommended_prefs, |
| 127 | PrefStore* default_prefs, |
| 128 | PrefNotifier* pref_notifier, |
| 129 | std::unique_ptr<Delegate> delegate = nullptr); |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 130 | |
| 131 | // A PrefValueStore can have exactly one callback that is directly |
| 132 | // notified of preferences changing in the store. This does not |
| 133 | // filter through the PrefNotifier mechanism, which may not forward |
| 134 | // certain changes (e.g. unregistered prefs). |
danakj | edfd5d7 | 2019-12-13 21:14:34 | [diff] [blame] | 135 | void set_callback(PrefChangedCallback callback) { |
| 136 | pref_changed_callback_ = std::move(callback); |
| 137 | } |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 138 | |
| 139 | // Gets the value for the given preference name that has the specified value |
| 140 | // type. Values stored in a PrefStore that have the matching |name| but |
| 141 | // a non-matching |type| are silently skipped. Returns true if a valid value |
| 142 | // was found in any of the available PrefStores. Most callers should use |
| 143 | // Preference::GetValue() instead of calling this method directly. |
| 144 | bool GetValue(const std::string& name, |
| 145 | base::Value::Type type, |
| 146 | const base::Value** out_value) const; |
| 147 | |
| 148 | // Gets the recommended value for the given preference name that has the |
| 149 | // specified value type. A value stored in the recommended PrefStore that has |
| 150 | // the matching |name| but a non-matching |type| is silently ignored. Returns |
| 151 | // true if a valid value was found. Most callers should use |
| 152 | // Preference::GetRecommendedValue() instead of calling this method directly. |
| 153 | bool GetRecommendedValue(const std::string& name, |
| 154 | base::Value::Type type, |
| 155 | const base::Value** out_value) const; |
| 156 | |
| 157 | // These methods return true if a preference with the given name is in the |
| 158 | // indicated pref store, even if that value is currently being overridden by |
| 159 | // a higher-priority source. |
| 160 | bool PrefValueInManagedStore(const std::string& name) const; |
| 161 | bool PrefValueInSupervisedStore(const std::string& name) const; |
| 162 | bool PrefValueInExtensionStore(const std::string& name) const; |
| 163 | bool PrefValueInUserStore(const std::string& name) const; |
| 164 | |
| 165 | // These methods return true if a preference with the given name is actually |
| 166 | // being controlled by the indicated pref store and not being overridden by |
| 167 | // a higher-priority source. |
| 168 | bool PrefValueFromExtensionStore(const std::string& name) const; |
| 169 | bool PrefValueFromUserStore(const std::string& name) const; |
| 170 | bool PrefValueFromRecommendedStore(const std::string& name) const; |
| 171 | bool PrefValueFromDefaultStore(const std::string& name) const; |
| 172 | |
| 173 | // Check whether a Preference value is modifiable by the user, i.e. whether |
| 174 | // there is no higher-priority source controlling it. |
| 175 | bool PrefValueUserModifiable(const std::string& name) const; |
| 176 | |
| 177 | // Check whether a Preference value is modifiable by an extension, i.e. |
| 178 | // whether there is no higher-priority source controlling it. |
| 179 | bool PrefValueExtensionModifiable(const std::string& name) const; |
| 180 | |
| 181 | // Update the command line PrefStore with |command_line_prefs|. |
| 182 | void UpdateCommandLinePrefStore(PrefStore* command_line_prefs); |
| 183 | |
Sam McNally | f4dab61 | 2017-08-16 03:06:33 | [diff] [blame] | 184 | bool IsInitializationComplete() const; |
| 185 | |
Min Qin | caa1e2e | 2018-09-14 20:56:48 | [diff] [blame] | 186 | // Check whether a particular type of PrefStore exists. |
| 187 | bool HasPrefStore(PrefStoreType type) const; |
| 188 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 189 | private: |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 190 | // Keeps a PrefStore reference on behalf of the PrefValueStore and monitors |
| 191 | // the PrefStore for changes, forwarding notifications to PrefValueStore. This |
| 192 | // indirection is here for the sake of disambiguating notifications from the |
| 193 | // individual PrefStores. |
| 194 | class PrefStoreKeeper : public PrefStore::Observer { |
| 195 | public: |
| 196 | PrefStoreKeeper(); |
| 197 | ~PrefStoreKeeper() override; |
| 198 | |
| 199 | // Takes ownership of |pref_store|. |
| 200 | void Initialize(PrefValueStore* store, |
| 201 | PrefStore* pref_store, |
| 202 | PrefStoreType type); |
| 203 | |
| 204 | PrefStore* store() { return pref_store_.get(); } |
| 205 | const PrefStore* store() const { return pref_store_.get(); } |
| 206 | |
| 207 | private: |
| 208 | // PrefStore::Observer implementation. |
| 209 | void OnPrefValueChanged(const std::string& key) override; |
| 210 | void OnInitializationCompleted(bool succeeded) override; |
| 211 | |
| 212 | // PrefValueStore this keeper is part of. |
| 213 | PrefValueStore* pref_value_store_; |
| 214 | |
| 215 | // The PrefStore managed by this keeper. |
| 216 | scoped_refptr<PrefStore> pref_store_; |
| 217 | |
| 218 | // Type of the pref store. |
| 219 | PrefStoreType type_; |
| 220 | |
| 221 | DISALLOW_COPY_AND_ASSIGN(PrefStoreKeeper); |
| 222 | }; |
| 223 | |
| 224 | typedef std::map<std::string, base::Value::Type> PrefTypeMap; |
| 225 | |
| 226 | // Returns true if the preference with the given name has a value in the |
| 227 | // given PrefStoreType, of the same value type as the preference was |
| 228 | // registered with. |
| 229 | bool PrefValueInStore(const std::string& name, PrefStoreType store) const; |
| 230 | |
| 231 | // Returns true if a preference has an explicit value in any of the |
| 232 | // stores in the range specified by |first_checked_store| and |
| 233 | // |last_checked_store|, even if that value is currently being |
| 234 | // overridden by a higher-priority store. |
| 235 | bool PrefValueInStoreRange(const std::string& name, |
| 236 | PrefStoreType first_checked_store, |
| 237 | PrefStoreType last_checked_store) const; |
| 238 | |
| 239 | // Returns the pref store type identifying the source that controls the |
| 240 | // Preference identified by |name|. If none of the sources has a value, |
| 241 | // INVALID_STORE is returned. In practice, the default PrefStore |
| 242 | // should always have a value for any registered preferencem, so INVALID_STORE |
| 243 | // indicates an error. |
| 244 | PrefStoreType ControllingPrefStoreForPref(const std::string& name) const; |
| 245 | |
| 246 | // Get a value from the specified |store|. |
| 247 | bool GetValueFromStore(const std::string& name, |
| 248 | PrefStoreType store, |
| 249 | const base::Value** out_value) const; |
| 250 | |
| 251 | // Get a value from the specified |store| if its |type| matches. |
| 252 | bool GetValueFromStoreWithType(const std::string& name, |
| 253 | base::Value::Type type, |
| 254 | PrefStoreType store, |
| 255 | const base::Value** out_value) const; |
| 256 | |
| 257 | // Called upon changes in individual pref stores in order to determine whether |
| 258 | // the user-visible pref value has changed. Triggers the change notification |
| 259 | // if the effective value of the preference has changed, or if the store |
| 260 | // controlling the pref has changed. |
| 261 | void NotifyPrefChanged(const std::string& path, PrefStoreType new_store); |
| 262 | |
| 263 | // Called from the PrefStoreKeeper implementation when a pref value for |key| |
| 264 | // changed in the pref store for |type|. |
| 265 | void OnPrefValueChanged(PrefStoreType type, const std::string& key); |
| 266 | |
| 267 | // Handle the event that the store for |type| has completed initialization. |
| 268 | void OnInitializationCompleted(PrefStoreType type, bool succeeded); |
| 269 | |
| 270 | // Initializes a pref store keeper. Sets up a PrefStoreKeeper that will take |
| 271 | // ownership of the passed |pref_store|. |
| 272 | void InitPrefStore(PrefStoreType type, PrefStore* pref_store); |
| 273 | |
| 274 | // Checks whether initialization is completed and tells the notifier if that |
| 275 | // is the case. |
| 276 | void CheckInitializationCompleted(); |
| 277 | |
| 278 | // Get the PrefStore pointer for the given type. May return NULL if there is |
| 279 | // no PrefStore for that type. |
| 280 | PrefStore* GetPrefStore(PrefStoreType type) { |
| 281 | return pref_stores_[type].store(); |
| 282 | } |
| 283 | const PrefStore* GetPrefStore(PrefStoreType type) const { |
| 284 | return pref_stores_[type].store(); |
| 285 | } |
| 286 | |
| 287 | // Keeps the PrefStore references in order of precedence. |
| 288 | PrefStoreKeeper pref_stores_[PREF_STORE_TYPE_MAX + 1]; |
| 289 | |
| 290 | PrefChangedCallback pref_changed_callback_; |
| 291 | |
| 292 | // Used for generating notifications. This is a weak reference, |
| 293 | // since the notifier is owned by the corresponding PrefService. |
| 294 | PrefNotifier* pref_notifier_; |
| 295 | |
| 296 | // A mapping of preference names to their registered types. |
| 297 | PrefTypeMap pref_types_; |
| 298 | |
| 299 | // True if not all of the PrefStores were initialized successfully. |
| 300 | bool initialization_failed_; |
| 301 | |
Johan Tibell | 26b550b | 2017-06-20 04:59:13 | [diff] [blame] | 302 | // Might be null. |
| 303 | std::unique_ptr<Delegate> delegate_; |
| 304 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 305 | DISALLOW_COPY_AND_ASSIGN(PrefValueStore); |
| 306 | }; |
| 307 | |
tibell | 11141bd | 2017-03-10 00:16:29 | [diff] [blame] | 308 | namespace std { |
| 309 | |
| 310 | template <> |
| 311 | struct hash<PrefValueStore::PrefStoreType> { |
| 312 | size_t operator()(PrefValueStore::PrefStoreType type) const { |
| 313 | return std::hash< |
danakj | 6d0446e5 | 2017-04-05 16:22:29 | [diff] [blame] | 314 | std::underlying_type<PrefValueStore::PrefStoreType>::type>()(type); |
tibell | 11141bd | 2017-03-10 00:16:29 | [diff] [blame] | 315 | } |
| 316 | }; |
| 317 | |
| 318 | } // namespace std |
| 319 | |
brettw | 06650868 | 2016-02-03 08:22:02 | [diff] [blame] | 320 | #endif // COMPONENTS_PREFS_PREF_VALUE_STORE_H_ |