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