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