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