1 // Copyright 2012 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // This provides a way to access the application's current preferences.
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.
11 #ifndef COMPONENTS_PREFS_PREF_SERVICE_H_
12 #define COMPONENTS_PREFS_PREF_SERVICE_H_
19 #include <unordered_map>
22 #include "base/compiler_specific.h"
23 #include "base/functional/callback.h"
24 #include "base/memory/raw_ptr.h"
25 #include "base/memory/ref_counted.h"
26 #include "base/sequence_checker.h"
27 #include "base/strings/string_piece.h"
28 #include "base/time/time.h"
29 #include "base/values.h"
30 #include "build/build_config.h"
31 #include "build/chromeos_buildflags.h"
32 #include "components/prefs/persistent_pref_store.h"
33 #include "components/prefs/pref_value_store.h"
34 #include "components/prefs/prefs_export.h"
36 #if BUILDFLAG(IS_ANDROID)
37 #include "base/android/scoped_java_ref.h"
41 class PrefNotifierImpl;
45 #if BUILDFLAG(IS_ANDROID)
46 class PrefServiceAndroid;
54 class ScopedDictionaryPrefUpdate;
59 class ScopedUserPrefUpdateBase;
62 // Base class for PrefServices. You can use the base class to read and
63 // interact with preferences, but not to register new preferences; for
64 // that see e.g. PrefRegistrySimple.
66 // Settings and storage accessed through this class represent
67 // user-selected preferences and information and MUST not be
68 // extracted, overwritten or modified except through the defined APIs.
69 class COMPONENTS_PREFS_EXPORT PrefService {
71 enum PrefInitializationStatus {
72 INITIALIZATION_STATUS_WAITING,
73 INITIALIZATION_STATUS_SUCCESS,
74 INITIALIZATION_STATUS_CREATED_NEW_PREF_STORE,
75 INITIALIZATION_STATUS_ERROR
78 enum IncludeDefaults {
83 struct COMPONENTS_PREFS_EXPORT PreferenceValueAndStore {
86 PrefValueStore::PrefStoreType store;
89 // A helper class to store all the information associated with a preference.
90 class COMPONENTS_PREFS_EXPORT Preference {
92 // The type of the preference is determined by the type with which it is
93 // registered. This type needs to be a boolean, integer, double, string,
94 // dictionary (a branch), or list. You shouldn't need to construct this on
95 // your own; use the PrefService::Register*Pref methods instead.
96 Preference(const PrefService* service,
98 base::Value::Type type);
101 // Returns the name of the Preference (i.e., the key, e.g.,
102 // browser.window_placement).
103 std::string name() const { return name_; }
105 // Returns the registered type of the preference.
106 base::Value::Type GetType() const { return type_; }
108 // Returns the value of the Preference, falling back to the registered
109 // default value if no other has been set.
110 const base::Value* GetValue() const;
112 // Returns the value recommended by the admin, if any.
113 const base::Value* GetRecommendedValue() const;
115 // Returns true if the Preference is managed, i.e. set by an admin policy.
116 // Since managed prefs have the highest priority, this also indicates
117 // whether the pref is actually being controlled by the policy setting.
118 bool IsManaged() const;
120 // Returns true if the Preference is controlled by the custodian of the
121 // supervised user. Since a supervised user is not expected to have an admin
122 // policy, this is the controlling pref if set.
123 bool IsManagedByCustodian() const;
125 // Returns true if the Preference's current value is one recommended by
126 // admin policy. Note that this will be false if any other higher-priority
127 // source overrides the value (e.g., the user has set a value).
128 bool IsRecommended() const;
130 // Returns true if the Preference has a value set by an extension, even if
131 // that value is being overridden by a higher-priority source.
132 bool HasExtensionSetting() const;
134 // Returns true if the Preference has a user setting, even if that value is
135 // being overridden by a higher-priority source.
136 bool HasUserSetting() const;
138 // Returns true if the Preference value is currently being controlled by an
139 // extension, and not by any higher-priority source.
140 bool IsExtensionControlled() const;
142 // Returns true if the Preference value is currently being controlled by a
143 // user setting, and not by any higher-priority source.
144 bool IsUserControlled() const;
146 // Returns true if the Preference is currently using its default value,
147 // and has not been set by any higher-priority source (even with the same
149 bool IsDefaultValue() const;
151 // Returns true if the user can change the Preference value, which is the
152 // case if no higher-priority source than the user store controls the
154 bool IsUserModifiable() const;
156 // Returns true if an extension can change the Preference value, which is
157 // the case if no higher-priority source than the extension store controls
159 bool IsExtensionModifiable() const;
161 #if BUILDFLAG(IS_CHROMEOS_ASH)
162 // Returns true if the Preference value is currently being controlled by a
163 // standalone browser (lacros) and not by any higher-priority source.
164 bool IsStandaloneBrowserControlled() const;
166 // Returns true if a standalone browser (lacros) can change the Preference
167 // value, which is the case if no higher-priority source than the standalone
168 // browser store controls the Preference.
169 bool IsStandaloneBrowserModifiable() const;
172 // Return the registration flags for this pref as a bitmask of
173 // PrefRegistry::PrefRegistrationFlags.
174 uint32_t registration_flags() const { return registration_flags_; }
177 friend class PrefService;
179 PrefValueStore* pref_value_store() const {
180 return pref_service_->pref_value_store_.get();
183 const std::string name_;
185 const base::Value::Type type_;
187 const uint32_t registration_flags_;
189 // Reference to the PrefService in which this pref was created.
190 const raw_ptr<const PrefService> pref_service_;
193 // You may wish to use PrefServiceFactory or one of its subclasses
194 // for simplified construction.
195 PrefService(std::unique_ptr<PrefNotifierImpl> pref_notifier,
196 std::unique_ptr<PrefValueStore> pref_value_store,
197 scoped_refptr<PersistentPrefStore> user_prefs,
198 scoped_refptr<PersistentPrefStore> standalone_browser_prefs,
199 scoped_refptr<PrefRegistry> pref_registry,
200 base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)>
204 PrefService(const PrefService&) = delete;
205 PrefService& operator=(const PrefService&) = delete;
207 virtual ~PrefService();
209 // Lands pending writes to disk. This should only be used if we need to save
210 // immediately (basically, during shutdown). |reply_callback| will be posted
211 // to the current sequence when changes have been written.
212 // |synchronous_done_callback| on the other hand will be invoked right away
213 // wherever the writes complete (could even be invoked synchronously if no
214 // writes need to occur); this is useful when the current thread cannot pump
215 // messages to observe the reply (e.g. nested loops banned on main thread
216 // during shutdown). |synchronous_done_callback| must be thread-safe.
217 void CommitPendingWrite(
218 base::OnceClosure reply_callback = base::OnceClosure(),
219 base::OnceClosure synchronous_done_callback = base::OnceClosure());
221 // Schedules a write if there is any lossy data pending. Unlike
222 // CommitPendingWrite() this does not immediately sync to disk, instead it
223 // triggers an eventual write if there is lossy data pending and if there
224 // isn't one scheduled already.
225 void SchedulePendingLossyWrites();
227 // Returns true if the preference for the given preference name is available
229 bool IsManagedPreference(const std::string& pref_name) const;
231 // Returns true if the preference for the given preference name is available
232 // and is controlled by the parent/guardian of the child Account.
233 bool IsPreferenceManagedByCustodian(const std::string& pref_name) const;
235 // Returns |true| if a preference with the given name is available and its
236 // value can be changed by the user.
237 bool IsUserModifiablePreference(const std::string& pref_name) const;
239 // Look up a preference. Returns NULL if the preference is not
241 const PrefService::Preference* FindPreference(const std::string& path) const;
243 // If the path is valid and the value at the end of the path matches the type
244 // specified, it will return the specified value. Otherwise, the default
245 // value (set when the pref was registered) will be returned.
246 bool GetBoolean(base::StringPiece path) const;
247 int GetInteger(base::StringPiece path) const;
248 double GetDouble(base::StringPiece path) const;
249 const std::string& GetString(base::StringPiece path) const;
250 base::FilePath GetFilePath(base::StringPiece path) const;
252 // Returns the branch if it exists, or the registered default value otherwise.
253 // `path` must point to a registered preference (DCHECK).
254 const base::Value& GetValue(base::StringPiece path) const;
256 // Returns the branch if it exists, or the registered default value otherwise.
257 // `path` must point to a registered preference whose value and registered
258 // default are of type `base::Value::Type::DICT (DCHECK).
259 const base::Value::Dict& GetDict(base::StringPiece path) const;
261 // Returns the branch if it exists, or the registered default value otherwise.
262 // `path` must point to a registered preference whose value and registered
263 // default are of type `base::Value::Type::LIST (DCHECK).
264 const base::Value::List& GetList(base::StringPiece path) const;
266 // Removes a user pref and restores the pref to its default value.
267 void ClearPref(const std::string& path);
269 // Removes user prefs that start with |prefix|.
270 void ClearPrefsWithPrefixSilently(const std::string& prefix);
272 // If the path is valid (i.e., registered), update the pref value in the user
275 // To set the value of dictionary or list values in the pref tree, use
276 // SetDict()/SetList(), but to modify the value of a dictionary or list use
277 // either ScopedDictPrefUpdate or ScopedListPrefUpdate from
278 // scoped_user_pref_update.h.
279 void Set(const std::string& path, const base::Value& value);
280 void SetBoolean(const std::string& path, bool value);
281 void SetInteger(const std::string& path, int value);
282 void SetDouble(const std::string& path, double value);
283 void SetString(const std::string& path, base::StringPiece value);
284 void SetDict(const std::string& path, base::Value::Dict dict);
285 void SetList(const std::string& path, base::Value::List list);
286 void SetFilePath(const std::string& path, const base::FilePath& value);
288 // Int64 helper methods that actually store the given value as a string.
289 // Note that if obtaining the named value via GetDictionary or GetList, the
290 // Value type will be Type::STRING.
291 void SetInt64(const std::string& path, int64_t value);
292 int64_t GetInt64(const std::string& path) const;
294 // As above, but for unsigned values.
295 void SetUint64(const std::string& path, uint64_t value);
296 uint64_t GetUint64(const std::string& path) const;
298 // Time helper methods that actually store the given value as a string, which
299 // represents the number of microseconds elapsed (absolute for TimeDelta and
300 // relative to Windows epoch for Time variants). Note that if obtaining the
301 // named value via GetDictionary or GetList, the Value type will be
303 void SetTime(const std::string& path, base::Time value);
304 base::Time GetTime(const std::string& path) const;
305 void SetTimeDelta(const std::string& path, base::TimeDelta value);
306 base::TimeDelta GetTimeDelta(const std::string& path) const;
308 // Returns the value of the given preference, from the user pref store. If
309 // the preference is not set in the user pref store, returns NULL.
310 const base::Value* GetUserPrefValue(const std::string& path) const;
312 // Changes the default value for a preference.
314 // Will cause a pref change notification to be fired if this causes
315 // the effective value to change.
316 void SetDefaultPrefValue(const std::string& path, base::Value value);
318 // Returns the default value of the given preference. |path| must point to a
319 // registered preference. In that case, will never return nullptr, so callers
320 // do not need to check this.
321 const base::Value* GetDefaultPrefValue(const std::string& path) const;
323 // Returns true if a value has been set for the specified path.
324 // NOTE: this is NOT the same as FindPreference. In particular
325 // FindPreference returns whether RegisterXXX has been invoked, where as
326 // this checks if a value exists for the path.
327 bool HasPrefPath(const std::string& path) const;
329 // Issues a callback for every preference value. The preferences must not be
330 // mutated during iteration.
331 void IteratePreferenceValues(
332 base::RepeatingCallback<void(const std::string& key,
333 const base::Value& value)> callback) const;
335 // Returns a dictionary with effective preference values. This is an expensive
336 // operation which does a deep copy. Use only if you really need the results
337 // in a base::Value (for example, for JSON serialization). Otherwise use
338 // IteratePreferenceValues above to avoid the copies.
340 // If INCLUDE_DEFAULTS is requested, preferences set to their default values
341 // will be included. Otherwise, these will be omitted from the returned
343 base::Value::Dict GetPreferenceValues(IncludeDefaults include_defaults) const;
345 // Returns a map of the preference values by their path including prefs that
346 // have their default value.
347 std::vector<PreferenceValueAndStore> GetPreferencesValueAndStore() const;
349 bool ReadOnly() const;
351 // Returns the initialization state, taking only user prefs into account.
352 PrefInitializationStatus GetInitializationStatus() const;
354 // Returns the initialization state, taking all pref stores into account.
355 PrefInitializationStatus GetAllPrefStoresInitializationStatus() const;
357 // Tell our PrefValueStore to update itself to |command_line_store|.
358 // Takes ownership of the store.
359 virtual void UpdateCommandLinePrefStore(PrefStore* command_line_store);
361 // We run the callback once, when initialization completes. The bool
362 // parameter will be set to true for successful initialization,
363 // false for unsuccessful.
364 void AddPrefInitObserver(base::OnceCallback<void(bool)> callback);
366 // Returns the PrefRegistry object for this service. You should not
367 // use this; the intent is for no registrations to take place after
368 // PrefService has been constructed.
370 // Instead of using this method, the recommended approach is to
371 // register all preferences for a class Xyz up front in a static
372 // Xyz::RegisterPrefs function, which gets invoked early in the
373 // application's start-up, before a PrefService is created.
375 // As an example, prefs registration in Chrome is triggered by the
376 // functions chrome::RegisterPrefs (for global preferences) and
377 // chrome::RegisterProfilePrefs (for user-specific preferences)
378 // implemented in chrome/browser/prefs/browser_prefs.cc.
379 PrefRegistry* DeprecatedGetPrefRegistry();
381 // Invoked when the store is deleted from disk. Allows this PrefService
382 // to tangentially cleanup data it may have saved outside the store.
383 void OnStoreDeletionFromDisk();
385 // A low level function for registering an observer for every single
386 // preference changed notification. The caller must ensure that the observer
387 // remains valid as long as it is registered. Pointer ownership is not
390 // Almost all calling code should use a PrefChangeRegistrar instead.
392 // AVOID ADDING THESE. These are low-level observer notifications that are
393 // called for every pref change. This can lead to inefficiency, and the lack
394 // of a "registrar" model makes it easy to forget to unregister. It is
395 // really designed for integrating other notification systems, not for normal
397 void AddPrefObserverAllPrefs(PrefObserver* obs);
398 void RemovePrefObserverAllPrefs(PrefObserver* obs);
400 #if BUILDFLAG(IS_CHROMEOS_ASH)
401 // Write extension-controlled prefs from Lacros in ash.
402 void SetStandaloneBrowserPref(const std::string& path,
403 const base::Value& value);
404 // Clear extension-controlled prefs from Lacros in ash.
405 void RemoveStandaloneBrowserPref(const std::string& path);
408 #if BUILDFLAG(IS_ANDROID)
409 base::android::ScopedJavaLocalRef<jobject> GetJavaObject();
412 // Returns the WriteablePrefStore::PrefWriteFlags for `pref`.
413 static uint32_t GetWriteFlags(const PrefService::Preference* pref);
416 // The PrefNotifier handles registering and notifying preference observers.
417 // It is created and owned by this PrefService. Subclasses may access it for
419 const std::unique_ptr<PrefNotifierImpl> pref_notifier_;
421 // The PrefValueStore provides prioritized preference values. It is owned by
422 // this PrefService. Subclasses may access it for unit testing.
423 std::unique_ptr<PrefValueStore> pref_value_store_;
425 // Pref Stores and profile that we passed to the PrefValueStore.
426 const scoped_refptr<PersistentPrefStore> user_pref_store_;
427 const scoped_refptr<PersistentPrefStore> standalone_browser_pref_store_;
429 // Callback to call when a read error occurs. Always invoked on the sequence
430 // this PrefService was created own.
431 const base::RepeatingCallback<void(PersistentPrefStore::PrefReadError)>
432 read_error_callback_;
435 // Hash map expected to be fastest here since it minimises expensive
436 // string comparisons. Order is unimportant, and deletions are rare.
437 // Confirmed on Android where this speeded Chrome startup by roughly 50ms
438 // vs. std::map, and by roughly 180ms vs. std::set of Preference pointers.
439 typedef std::unordered_map<std::string, Preference> PreferenceMap;
441 // Give access to ReportUserPrefChanged() and GetMutableUserPref().
442 friend class subtle::ScopedUserPrefUpdateBase;
443 friend class PrefServiceTest_WriteablePrefStoreFlags_Test;
444 friend class prefs::ScopedDictionaryPrefUpdate;
446 // Registration of pref change observers must be done using the
447 // PrefChangeRegistrar, which is declared as a friend here to grant it
448 // access to the otherwise protected members Add/RemovePrefObserver.
449 // PrefMember registers for preferences changes notification directly to
450 // avoid the storage overhead of the registrar, so its base class must be
451 // declared as a friend, too.
452 friend class PrefChangeRegistrar;
453 friend class subtle::PrefMemberBase;
455 // These are protected so they can only be accessed by the friend
456 // classes listed above.
458 // If the pref at the given path changes, we call the observer's
459 // OnPreferenceChanged method. Note that observers should not call
460 // these methods directly but rather use a PrefChangeRegistrar to
461 // make sure the observer gets cleaned up properly.
463 // Virtual for testing.
464 virtual void AddPrefObserver(const std::string& path, PrefObserver* obs);
465 virtual void RemovePrefObserver(const std::string& path, PrefObserver* obs);
467 // A PrefStore::Observer which reports loading errors from
468 // PersistentPrefStores after they are loaded. Usually this is only user_prefs
469 // however in ash it additionally includes standalone_browser_prefs. Errors
470 // are only reported once even though multiple files may be loaded.
471 class PersistentPrefStoreLoadingObserver : public PrefStore::Observer {
473 explicit PersistentPrefStoreLoadingObserver(PrefService* pref_service_);
475 // PrefStore::Observer implementation
476 void OnPrefValueChanged(const std::string& key) override {}
477 void OnInitializationCompleted(bool succeeded) override;
480 raw_ptr<PrefService> pref_service_ = nullptr;
483 // Sends notification of a changed preference. This needs to be called by
484 // a ScopedDictPrefUpdate or ScopedListPrefUpdate if a Value::Dict or
485 // Value::List is changed.
486 void ReportUserPrefChanged(const std::string& key);
487 void ReportUserPrefChanged(
488 const std::string& key,
489 std::set<std::vector<std::string>> path_components);
491 // Sets the value for this pref path in the user pref store and informs the
492 // PrefNotifier of the change.
493 void SetUserPrefValue(const std::string& path, base::Value new_value);
495 // Load preferences from storage, attempting to diagnose and handle errors.
496 // This should only be called from the constructor.
497 void InitFromStorage(bool async);
499 // Verifies that prefs are fully loaded from disk, handling errors. This
500 // method may be called multiple times, but no more than once after all prefs
502 void CheckPrefsLoaded();
504 // Used to set the value of dictionary or list values in the user pref store.
505 // This will create a dictionary or list if one does not exist in the user
506 // pref store. This method returns NULL only if you're requesting an
507 // unregistered pref or a non-dict/non-list pref.
508 // |type| may only be Values::Type::DICT or Values::Type::LIST and
509 // |path| must point to a registered preference of type |type|.
510 // Ownership of the returned value remains at the user pref store.
511 base::Value* GetMutableUserPref(const std::string& path,
512 base::Value::Type type);
514 // GetPreferenceValue is the equivalent of FindPreference(path)->GetValue(),
515 // it has been added for performance. It is faster because it does
516 // not need to find or create a Preference object to get the
517 // value (GetValue() calls back though the preference service to
518 // actually get the value.).
519 const base::Value* GetPreferenceValue(base::StringPiece path) const;
520 const base::Value* GetPreferenceValueChecked(base::StringPiece path) const;
522 const scoped_refptr<PrefRegistry> pref_registry_;
524 std::unique_ptr<PrefService::PersistentPrefStoreLoadingObserver>
525 pref_store_observer_;
527 // Local cache of registered Preference objects. The pref_registry_
528 // is authoritative with respect to what the types and default values
529 // of registered preferences are.
530 mutable PreferenceMap prefs_map_;
532 #if BUILDFLAG(IS_ANDROID)
533 // Manage and fetch the java object that wraps this PrefService on
535 std::unique_ptr<PrefServiceAndroid> pref_service_android_;
538 SEQUENCE_CHECKER(sequence_checker_);
541 #endif // COMPONENTS_PREFS_PREF_SERVICE_H_