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