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 | |
| 5 | // This provides a way to access the application's current preferences. |
| 6 | |
| 7 | // Chromium settings and storage represent user-selected preferences and |
| 8 | // information and MUST not be extracted, overwritten or modified except |
| 9 | // through Chromium defined APIs. |
| 10 | |
brettw | 06650868 | 2016-02-03 08:22:02 | [diff] [blame] | 11 | #ifndef COMPONENTS_PREFS_PREF_SERVICE_H_ |
| 12 | #define COMPONENTS_PREFS_PREF_SERVICE_H_ |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 13 | |
| 14 | #include <stdint.h> |
| 15 | |
dcheng | 5f043bc | 2016-04-22 19:09:06 | [diff] [blame] | 16 | #include <memory> |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 17 | #include <set> |
| 18 | #include <string> |
Takuto Ikuta | adf31eb | 2019-01-05 00:32:48 | [diff] [blame] | 19 | #include <unordered_map> |
Sky Malice | aff2af14 | 2018-06-18 18:37:29 | [diff] [blame] | 20 | #include <vector> |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 21 | |
| 22 | #include "base/callback.h" |
| 23 | #include "base/compiler_specific.h" |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 24 | #include "base/macros.h" |
| 25 | #include "base/memory/ref_counted.h" |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 26 | #include "base/observer_list.h" |
gab | 6e1fb535 | 2017-05-31 18:27:12 | [diff] [blame] | 27 | #include "base/sequence_checker.h" |
Ilya Sherman | 557b2de7 | 2018-01-18 20:57:17 | [diff] [blame] | 28 | #include "base/time/time.h" |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 29 | #include "base/values.h" |
brettw | f00b9b4 | 2016-02-01 22:11:38 | [diff] [blame] | 30 | #include "components/prefs/persistent_pref_store.h" |
Min Qin | caa1e2e | 2018-09-14 20:56:48 | [diff] [blame] | 31 | #include "components/prefs/pref_value_store.h" |
Brett Wilson | 5c6cf26 | 2017-09-09 02:05:54 | [diff] [blame] | 32 | #include "components/prefs/prefs_export.h" |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 33 | |
| 34 | class PrefNotifier; |
| 35 | class PrefNotifierImpl; |
| 36 | class PrefObserver; |
| 37 | class PrefRegistry; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 38 | class PrefStore; |
| 39 | |
| 40 | namespace base { |
| 41 | class FilePath; |
| 42 | } |
| 43 | |
Sam McNally | 6957232 | 2017-05-01 00:41:38 | [diff] [blame] | 44 | namespace prefs { |
| 45 | class ScopedDictionaryPrefUpdate; |
| 46 | } |
| 47 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 48 | namespace subtle { |
| 49 | class PrefMemberBase; |
| 50 | class ScopedUserPrefUpdateBase; |
| 51 | } |
| 52 | |
| 53 | // Base class for PrefServices. You can use the base class to read and |
| 54 | // interact with preferences, but not to register new preferences; for |
| 55 | // that see e.g. PrefRegistrySimple. |
| 56 | // |
| 57 | // Settings and storage accessed through this class represent |
| 58 | // user-selected preferences and information and MUST not be |
| 59 | // extracted, overwritten or modified except through the defined APIs. |
gab | 6e1fb535 | 2017-05-31 18:27:12 | [diff] [blame] | 60 | class COMPONENTS_PREFS_EXPORT PrefService { |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 61 | public: |
| 62 | enum PrefInitializationStatus { |
| 63 | INITIALIZATION_STATUS_WAITING, |
| 64 | INITIALIZATION_STATUS_SUCCESS, |
| 65 | INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE, |
| 66 | INITIALIZATION_STATUS_ERROR |
| 67 | }; |
| 68 | |
brettw | ebf7184f | 2017-04-18 21:10:53 | [diff] [blame] | 69 | enum IncludeDefaults { |
| 70 | INCLUDE_DEFAULTS, |
| 71 | EXCLUDE_DEFAULTS, |
| 72 | }; |
| 73 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 74 | // A helper class to store all the information associated with a preference. |
brettw | 06650868 | 2016-02-03 08:22:02 | [diff] [blame] | 75 | class COMPONENTS_PREFS_EXPORT Preference { |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 76 | public: |
| 77 | // The type of the preference is determined by the type with which it is |
| 78 | // registered. This type needs to be a boolean, integer, double, string, |
| 79 | // dictionary (a branch), or list. You shouldn't need to construct this on |
| 80 | // your own; use the PrefService::Register*Pref methods instead. |
| 81 | Preference(const PrefService* service, |
François Degros | 484a133 | 2017-11-29 00:47:48 | [diff] [blame] | 82 | std::string name, |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 83 | base::Value::Type type); |
| 84 | ~Preference() {} |
| 85 | |
| 86 | // Returns the name of the Preference (i.e., the key, e.g., |
| 87 | // browser.window_placement). |
François Degros | 484a133 | 2017-11-29 00:47:48 | [diff] [blame] | 88 | std::string name() const { return name_; } |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 89 | |
| 90 | // Returns the registered type of the preference. |
François Degros | 484a133 | 2017-11-29 00:47:48 | [diff] [blame] | 91 | base::Value::Type GetType() const { return type_; } |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 92 | |
| 93 | // Returns the value of the Preference, falling back to the registered |
| 94 | // default value if no other has been set. |
| 95 | const base::Value* GetValue() const; |
| 96 | |
| 97 | // Returns the value recommended by the admin, if any. |
| 98 | const base::Value* GetRecommendedValue() const; |
| 99 | |
| 100 | // Returns true if the Preference is managed, i.e. set by an admin policy. |
| 101 | // Since managed prefs have the highest priority, this also indicates |
| 102 | // whether the pref is actually being controlled by the policy setting. |
| 103 | bool IsManaged() const; |
| 104 | |
| 105 | // Returns true if the Preference is controlled by the custodian of the |
| 106 | // supervised user. Since a supervised user is not expected to have an admin |
| 107 | // policy, this is the controlling pref if set. |
| 108 | bool IsManagedByCustodian() const; |
| 109 | |
Greg Thompson | ce973d0 | 2018-06-14 22:34:32 | [diff] [blame] | 110 | // Returns true if the Preference's current value is one recommended by |
| 111 | // admin policy. Note that this will be false if any other higher-priority |
| 112 | // source overrides the value (e.g., the user has set a value). |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 113 | bool IsRecommended() const; |
| 114 | |
| 115 | // Returns true if the Preference has a value set by an extension, even if |
| 116 | // that value is being overridden by a higher-priority source. |
| 117 | bool HasExtensionSetting() const; |
| 118 | |
| 119 | // Returns true if the Preference has a user setting, even if that value is |
| 120 | // being overridden by a higher-priority source. |
| 121 | bool HasUserSetting() const; |
| 122 | |
| 123 | // Returns true if the Preference value is currently being controlled by an |
| 124 | // extension, and not by any higher-priority source. |
| 125 | bool IsExtensionControlled() const; |
| 126 | |
| 127 | // Returns true if the Preference value is currently being controlled by a |
| 128 | // user setting, and not by any higher-priority source. |
| 129 | bool IsUserControlled() const; |
| 130 | |
| 131 | // Returns true if the Preference is currently using its default value, |
| 132 | // and has not been set by any higher-priority source (even with the same |
| 133 | // value). |
| 134 | bool IsDefaultValue() const; |
| 135 | |
| 136 | // Returns true if the user can change the Preference value, which is the |
| 137 | // case if no higher-priority source than the user store controls the |
| 138 | // Preference. |
| 139 | bool IsUserModifiable() const; |
| 140 | |
| 141 | // Returns true if an extension can change the Preference value, which is |
| 142 | // the case if no higher-priority source than the extension store controls |
| 143 | // the Preference. |
| 144 | bool IsExtensionModifiable() const; |
| 145 | |
| 146 | // Return the registration flags for this pref as a bitmask of |
| 147 | // PrefRegistry::PrefRegistrationFlags. |
| 148 | uint32_t registration_flags() const { return registration_flags_; } |
| 149 | |
| 150 | private: |
| 151 | friend class PrefService; |
| 152 | |
| 153 | PrefValueStore* pref_value_store() const { |
| 154 | return pref_service_->pref_value_store_.get(); |
| 155 | } |
| 156 | |
| 157 | const std::string name_; |
| 158 | |
| 159 | const base::Value::Type type_; |
| 160 | |
François Degros | 484a133 | 2017-11-29 00:47:48 | [diff] [blame] | 161 | const uint32_t registration_flags_; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 162 | |
| 163 | // Reference to the PrefService in which this pref was created. |
François Degros | 484a133 | 2017-11-29 00:47:48 | [diff] [blame] | 164 | const PrefService* const pref_service_; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 165 | }; |
| 166 | |
| 167 | // You may wish to use PrefServiceFactory or one of its subclasses |
| 168 | // for simplified construction. |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 169 | PrefService(std::unique_ptr<PrefNotifierImpl> pref_notifier, |
| 170 | std::unique_ptr<PrefValueStore> pref_value_store, |
François Degros | e39cf535e | 2018-02-07 02:08:30 | [diff] [blame] | 171 | scoped_refptr<PersistentPrefStore> user_prefs, |
| 172 | scoped_refptr<PrefRegistry> pref_registry, |
| 173 | base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)> |
François Degros | ee2f030d | 2017-12-04 00:29:01 | [diff] [blame] | 174 | read_error_callback, |
| 175 | bool async); |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 176 | virtual ~PrefService(); |
| 177 | |
| 178 | // Lands pending writes to disk. This should only be used if we need to save |
Gabriel Charette | 788eaf6 | 2018-08-07 20:11:46 | [diff] [blame] | 179 | // immediately (basically, during shutdown). |reply_callback| will be posted |
| 180 | // to the current sequence when changes have been written. |
| 181 | // |synchronous_done_callback| on the other hand will be invoked right away |
| 182 | // wherever the writes complete (could even be invoked synchronously if no |
| 183 | // writes need to occur); this is useful when the current thread cannot pump |
| 184 | // messages to observe the reply (e.g. nested loops banned on main thread |
| 185 | // during shutdown). |synchronous_done_callback| must be thread-safe. |
| 186 | void CommitPendingWrite( |
| 187 | base::OnceClosure reply_callback = base::OnceClosure(), |
| 188 | base::OnceClosure synchronous_done_callback = base::OnceClosure()); |
Pavol Marko | e1f238f | 2017-09-05 18:58:42 | [diff] [blame] | 189 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 190 | // Schedule a write if there is any lossy data pending. Unlike |
| 191 | // CommitPendingWrite() this does not immediately sync to disk, instead it |
| 192 | // triggers an eventual write if there is lossy data pending and if there |
| 193 | // isn't one scheduled already. |
| 194 | void SchedulePendingLossyWrites(); |
| 195 | |
| 196 | // Returns true if the preference for the given preference name is available |
| 197 | // and is managed. |
| 198 | bool IsManagedPreference(const std::string& pref_name) const; |
| 199 | |
| 200 | // Returns true if the preference for the given preference name is available |
| 201 | // and is controlled by the parent/guardian of the child Account. |
| 202 | bool IsPreferenceManagedByCustodian(const std::string& pref_name) const; |
| 203 | |
| 204 | // Returns |true| if a preference with the given name is available and its |
| 205 | // value can be changed by the user. |
| 206 | bool IsUserModifiablePreference(const std::string& pref_name) const; |
| 207 | |
| 208 | // Look up a preference. Returns NULL if the preference is not |
| 209 | // registered. |
| 210 | const PrefService::Preference* FindPreference(const std::string& path) const; |
| 211 | |
| 212 | // If the path is valid and the value at the end of the path matches the type |
| 213 | // specified, it will return the specified value. Otherwise, the default |
| 214 | // value (set when the pref was registered) will be returned. |
| 215 | bool GetBoolean(const std::string& path) const; |
| 216 | int GetInteger(const std::string& path) const; |
| 217 | double GetDouble(const std::string& path) const; |
| 218 | std::string GetString(const std::string& path) const; |
| 219 | base::FilePath GetFilePath(const std::string& path) const; |
| 220 | |
| 221 | // Returns the branch if it exists, or the registered default value otherwise. |
| 222 | // Note that |path| must point to a registered preference. In that case, these |
| 223 | // functions will never return NULL. |
Steven Bennetts | ca10851 | 2018-05-02 11:05:03 | [diff] [blame] | 224 | const base::Value* Get(const std::string& path) const; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 225 | const base::DictionaryValue* GetDictionary(const std::string& path) const; |
| 226 | const base::ListValue* GetList(const std::string& path) const; |
| 227 | |
| 228 | // Removes a user pref and restores the pref to its default value. |
| 229 | void ClearPref(const std::string& path); |
| 230 | |
| 231 | // If the path is valid (i.e., registered), update the pref value in the user |
| 232 | // prefs. |
| 233 | // To set the value of dictionary or list values in the pref tree use |
| 234 | // Set(), but to modify the value of a dictionary or list use either |
| 235 | // ListPrefUpdate or DictionaryPrefUpdate from scoped_user_pref_update.h. |
| 236 | void Set(const std::string& path, const base::Value& value); |
| 237 | void SetBoolean(const std::string& path, bool value); |
| 238 | void SetInteger(const std::string& path, int value); |
| 239 | void SetDouble(const std::string& path, double value); |
| 240 | void SetString(const std::string& path, const std::string& value); |
| 241 | void SetFilePath(const std::string& path, const base::FilePath& value); |
| 242 | |
| 243 | // Int64 helper methods that actually store the given value as a string. |
| 244 | // Note that if obtaining the named value via GetDictionary or GetList, the |
jdoerrie | dc72ee94 | 2016-12-07 15:43:28 | [diff] [blame] | 245 | // Value type will be Type::STRING. |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 246 | void SetInt64(const std::string& path, int64_t value); |
| 247 | int64_t GetInt64(const std::string& path) const; |
| 248 | |
| 249 | // As above, but for unsigned values. |
| 250 | void SetUint64(const std::string& path, uint64_t value); |
| 251 | uint64_t GetUint64(const std::string& path) const; |
| 252 | |
Ilya Sherman | 557b2de7 | 2018-01-18 20:57:17 | [diff] [blame] | 253 | // Time helper methods that actually store the given value as a string, which |
Sky Malice | aff2af14 | 2018-06-18 18:37:29 | [diff] [blame] | 254 | // represents the number of microseconds elapsed (absolute for TimeDelta and |
| 255 | // relative to Windows epoch for Time variants). Note that if obtaining the |
| 256 | // named value via GetDictionary or GetList, the Value type will be |
| 257 | // Type::STRING. |
Ilya Sherman | 557b2de7 | 2018-01-18 20:57:17 | [diff] [blame] | 258 | void SetTime(const std::string& path, base::Time value); |
| 259 | base::Time GetTime(const std::string& path) const; |
Sky Malice | aff2af14 | 2018-06-18 18:37:29 | [diff] [blame] | 260 | void SetTimeDelta(const std::string& path, base::TimeDelta value); |
| 261 | base::TimeDelta GetTimeDelta(const std::string& path) const; |
Ilya Sherman | 557b2de7 | 2018-01-18 20:57:17 | [diff] [blame] | 262 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 263 | // Returns the value of the given preference, from the user pref store. If |
| 264 | // the preference is not set in the user pref store, returns NULL. |
| 265 | const base::Value* GetUserPrefValue(const std::string& path) const; |
| 266 | |
Lei Zhang | c3d77b6 | 2017-10-19 03:30:28 | [diff] [blame] | 267 | // Changes the default value for a preference. |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 268 | // |
| 269 | // Will cause a pref change notification to be fired if this causes |
| 270 | // the effective value to change. |
Lei Zhang | c3d77b6 | 2017-10-19 03:30:28 | [diff] [blame] | 271 | void SetDefaultPrefValue(const std::string& path, base::Value value); |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 272 | |
| 273 | // Returns the default value of the given preference. |path| must point to a |
Lei Zhang | 9e22c843 | 2017-10-17 20:54:28 | [diff] [blame] | 274 | // registered preference. In that case, will never return nullptr, so callers |
| 275 | // do not need to check this. |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 276 | const base::Value* GetDefaultPrefValue(const std::string& path) const; |
| 277 | |
| 278 | // Returns true if a value has been set for the specified path. |
| 279 | // NOTE: this is NOT the same as FindPreference. In particular |
| 280 | // FindPreference returns whether RegisterXXX has been invoked, where as |
| 281 | // this checks if a value exists for the path. |
| 282 | bool HasPrefPath(const std::string& path) const; |
| 283 | |
brettw | ebf7184f | 2017-04-18 21:10:53 | [diff] [blame] | 284 | // Issues a callback for every preference value. The preferences must not be |
| 285 | // mutated during iteration. |
| 286 | void IteratePreferenceValues( |
| 287 | base::RepeatingCallback<void(const std::string& key, |
| 288 | const base::Value& value)> callback) const; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 289 | |
brettw | ebf7184f | 2017-04-18 21:10:53 | [diff] [blame] | 290 | // Returns a dictionary with effective preference values. This is an expensive |
| 291 | // operation which does a deep copy. Use only if you really need the results |
| 292 | // in a base::Value (for example, for JSON serialization). Otherwise use |
| 293 | // IteratePreferenceValues above to avoid the copies. |
| 294 | // |
| 295 | // If INCLUDE_DEFAULTS is requested, preferences set to their default values |
| 296 | // will be included. Otherwise, these will be omitted from the returned |
| 297 | // dictionary. |
| 298 | std::unique_ptr<base::DictionaryValue> GetPreferenceValues( |
| 299 | IncludeDefaults include_defaults) const; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 300 | |
| 301 | bool ReadOnly() const; |
| 302 | |
Sam McNally | f4dab61 | 2017-08-16 03:06:33 | [diff] [blame] | 303 | // Returns the initialization state, taking only user prefs into account. |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 304 | PrefInitializationStatus GetInitializationStatus() const; |
| 305 | |
Sam McNally | f4dab61 | 2017-08-16 03:06:33 | [diff] [blame] | 306 | // Returns the initialization state, taking all pref stores into account. |
| 307 | PrefInitializationStatus GetAllPrefStoresInitializationStatus() const; |
| 308 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 309 | // Tell our PrefValueStore to update itself to |command_line_store|. |
| 310 | // Takes ownership of the store. |
| 311 | virtual void UpdateCommandLinePrefStore(PrefStore* command_line_store); |
| 312 | |
| 313 | // We run the callback once, when initialization completes. The bool |
| 314 | // parameter will be set to true for successful initialization, |
| 315 | // false for unsuccessful. |
Kenichi Ishibashi | f958ad6 | 2017-12-19 02:43:14 | [diff] [blame] | 316 | void AddPrefInitObserver(base::OnceCallback<void(bool)> callback); |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 317 | |
| 318 | // Returns the PrefRegistry object for this service. You should not |
| 319 | // use this; the intent is for no registrations to take place after |
| 320 | // PrefService has been constructed. |
| 321 | // |
| 322 | // Instead of using this method, the recommended approach is to |
| 323 | // register all preferences for a class Xyz up front in a static |
| 324 | // Xyz::RegisterPrefs function, which gets invoked early in the |
| 325 | // application's start-up, before a PrefService is created. |
| 326 | // |
| 327 | // As an example, prefs registration in Chrome is triggered by the |
| 328 | // functions chrome::RegisterPrefs (for global preferences) and |
| 329 | // chrome::RegisterProfilePrefs (for user-specific preferences) |
| 330 | // implemented in chrome/browser/prefs/browser_prefs.cc. |
| 331 | PrefRegistry* DeprecatedGetPrefRegistry(); |
| 332 | |
dvadym | 53fc0d4 | 2016-02-05 13:34:57 | [diff] [blame] | 333 | // Clears mutable values. |
| 334 | void ClearMutableValues(); |
| 335 | |
proberge | 45e34728 | 2017-08-16 21:24:05 | [diff] [blame] | 336 | // Invoked when the store is deleted from disk. Allows this PrefService |
| 337 | // to tangentially cleanup data it may have saved outside the store. |
| 338 | void OnStoreDeletionFromDisk(); |
| 339 | |
Min Qin | caa1e2e | 2018-09-14 20:56:48 | [diff] [blame] | 340 | // Add new pref stores to the existing PrefValueStore. Only adding new |
| 341 | // stores are allowed. If a corresponding store already exists, calling this |
| 342 | // will cause DCHECK failures. If the newly added stores already contain |
| 343 | // values, PrefNotifier associated with this object will be notified with |
| 344 | // these values. |delegate| can be passed to observe events of the new |
| 345 | // PrefValueStore. |
| 346 | // TODO(qinmin): packaging all the input params in a struct, and do the same |
| 347 | // for the constructor. |
| 348 | void ChangePrefValueStore( |
| 349 | PrefStore* managed_prefs, |
| 350 | PrefStore* supervised_user_prefs, |
| 351 | PrefStore* extension_prefs, |
| 352 | PrefStore* recommended_prefs, |
| 353 | std::unique_ptr<PrefValueStore::Delegate> delegate = nullptr); |
| 354 | |
Brett Wilson | 21cf626a | 2017-09-07 00:30:20 | [diff] [blame] | 355 | // A low level function for registering an observer for every single |
| 356 | // preference changed notification. The caller must ensure that the observer |
| 357 | // remains valid as long as it is registered. Pointer ownership is not |
| 358 | // transferred. |
| 359 | // |
| 360 | // Almost all calling code should use a PrefChangeRegistrar instead. |
| 361 | // |
| 362 | // AVOID ADDING THESE. These are low-level observer notifications that are |
| 363 | // called for every pref change. This can lead to inefficiency, and the lack |
| 364 | // of a "registrar" model makes it easy to forget to undregister. It is |
| 365 | // really designed for integrating other notification systems, not for normal |
| 366 | // observation. |
| 367 | void AddPrefObserverAllPrefs(PrefObserver* obs); |
| 368 | void RemovePrefObserverAllPrefs(PrefObserver* obs); |
| 369 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 370 | protected: |
| 371 | // The PrefNotifier handles registering and notifying preference observers. |
| 372 | // It is created and owned by this PrefService. Subclasses may access it for |
| 373 | // unit testing. |
François Degros | 6783125f | 2018-02-07 22:43:24 | [diff] [blame] | 374 | const std::unique_ptr<PrefNotifierImpl> pref_notifier_; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 375 | |
| 376 | // The PrefValueStore provides prioritized preference values. It is owned by |
| 377 | // this PrefService. Subclasses may access it for unit testing. |
Min Qin | caa1e2e | 2018-09-14 20:56:48 | [diff] [blame] | 378 | std::unique_ptr<PrefValueStore> pref_value_store_; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 379 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 380 | // Pref Stores and profile that we passed to the PrefValueStore. |
François Degros | 6783125f | 2018-02-07 22:43:24 | [diff] [blame] | 381 | const scoped_refptr<PersistentPrefStore> user_pref_store_; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 382 | |
Gabriel Charette | 7176aed | 2018-04-05 18:53:36 | [diff] [blame] | 383 | // Callback to call when a read error occurs. Always invoked on the sequence |
| 384 | // this PrefService was created own. |
François Degros | e39cf535e | 2018-02-07 02:08:30 | [diff] [blame] | 385 | const base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)> |
| 386 | read_error_callback_; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 387 | |
| 388 | private: |
| 389 | // Hash map expected to be fastest here since it minimises expensive |
| 390 | // string comparisons. Order is unimportant, and deletions are rare. |
| 391 | // Confirmed on Android where this speeded Chrome startup by roughly 50ms |
| 392 | // vs. std::map, and by roughly 180ms vs. std::set of Preference pointers. |
Takuto Ikuta | adf31eb | 2019-01-05 00:32:48 | [diff] [blame] | 393 | typedef std::unordered_map<std::string, Preference> PreferenceMap; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 394 | |
| 395 | // Give access to ReportUserPrefChanged() and GetMutableUserPref(). |
| 396 | friend class subtle::ScopedUserPrefUpdateBase; |
| 397 | friend class PrefServiceTest_WriteablePrefStoreFlags_Test; |
Sam McNally | 6957232 | 2017-05-01 00:41:38 | [diff] [blame] | 398 | friend class prefs::ScopedDictionaryPrefUpdate; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 399 | |
| 400 | // Registration of pref change observers must be done using the |
| 401 | // PrefChangeRegistrar, which is declared as a friend here to grant it |
| 402 | // access to the otherwise protected members Add/RemovePrefObserver. |
| 403 | // PrefMember registers for preferences changes notification directly to |
| 404 | // avoid the storage overhead of the registrar, so its base class must be |
| 405 | // declared as a friend, too. |
| 406 | friend class PrefChangeRegistrar; |
| 407 | friend class subtle::PrefMemberBase; |
| 408 | |
| 409 | // These are protected so they can only be accessed by the friend |
| 410 | // classes listed above. |
| 411 | // |
| 412 | // If the pref at the given path changes, we call the observer's |
| 413 | // OnPreferenceChanged method. Note that observers should not call |
| 414 | // these methods directly but rather use a PrefChangeRegistrar to |
| 415 | // make sure the observer gets cleaned up properly. |
| 416 | // |
| 417 | // Virtual for testing. |
| 418 | virtual void AddPrefObserver(const std::string& path, PrefObserver* obs); |
| 419 | virtual void RemovePrefObserver(const std::string& path, PrefObserver* obs); |
| 420 | |
| 421 | // Sends notification of a changed preference. This needs to be called by |
Sam McNally | 6957232 | 2017-05-01 00:41:38 | [diff] [blame] | 422 | // a ScopedUserPrefUpdate or ScopedDictionaryPrefUpdate if a DictionaryValue |
| 423 | // or ListValue is changed. |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 424 | void ReportUserPrefChanged(const std::string& key); |
Sam McNally | 6957232 | 2017-05-01 00:41:38 | [diff] [blame] | 425 | void ReportUserPrefChanged( |
| 426 | const std::string& key, |
| 427 | std::set<std::vector<std::string>> path_components); |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 428 | |
| 429 | // Sets the value for this pref path in the user pref store and informs the |
| 430 | // PrefNotifier of the change. |
Lei Zhang | 97a70e4 | 2019-10-11 20:59:12 | [diff] [blame] | 431 | void SetUserPrefValue(const std::string& path, base::Value new_value); |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 432 | |
| 433 | // Load preferences from storage, attempting to diagnose and handle errors. |
| 434 | // This should only be called from the constructor. |
| 435 | void InitFromStorage(bool async); |
| 436 | |
| 437 | // Used to set the value of dictionary or list values in the user pref store. |
| 438 | // This will create a dictionary or list if one does not exist in the user |
| 439 | // pref store. This method returns NULL only if you're requesting an |
| 440 | // unregistered pref or a non-dict/non-list pref. |
jdoerrie | dc72ee94 | 2016-12-07 15:43:28 | [diff] [blame] | 441 | // |type| may only be Values::Type::DICTIONARY or Values::Type::LIST and |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 442 | // |path| must point to a registered preference of type |type|. |
| 443 | // Ownership of the returned value remains at the user pref store. |
| 444 | base::Value* GetMutableUserPref(const std::string& path, |
| 445 | base::Value::Type type); |
| 446 | |
| 447 | // GetPreferenceValue is the equivalent of FindPreference(path)->GetValue(), |
Alan Cutter | 8acc872 | 2019-05-07 02:24:09 | [diff] [blame] | 448 | // it has been added for performance. It is faster because it does |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 449 | // not need to find or create a Preference object to get the |
| 450 | // value (GetValue() calls back though the preference service to |
| 451 | // actually get the value.). |
| 452 | const base::Value* GetPreferenceValue(const std::string& path) const; |
Alan Cutter | 8acc872 | 2019-05-07 02:24:09 | [diff] [blame] | 453 | const base::Value* GetPreferenceValueChecked(const std::string& path) const; |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 454 | |
Tim Schumann | 13ef1e8 | 2018-05-30 01:37:15 | [diff] [blame] | 455 | const scoped_refptr<PrefRegistry> pref_registry_; |
| 456 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 457 | // Local cache of registered Preference objects. The pref_registry_ |
| 458 | // is authoritative with respect to what the types and default values |
| 459 | // of registered preferences are. |
| 460 | mutable PreferenceMap prefs_map_; |
| 461 | |
gab | 6e1fb535 | 2017-05-31 18:27:12 | [diff] [blame] | 462 | SEQUENCE_CHECKER(sequence_checker_); |
| 463 | |
brettw | 58cd1f1 | 2016-01-30 05:56:05 | [diff] [blame] | 464 | DISALLOW_COPY_AND_ASSIGN(PrefService); |
| 465 | }; |
| 466 | |
brettw | 06650868 | 2016-02-03 08:22:02 | [diff] [blame] | 467 | #endif // COMPONENTS_PREFS_PREF_SERVICE_H_ |