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