1 // Copyright 2024 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 #ifndef COMPONENTS_PREFS_WRAP_WITH_PREFIX_PREF_STORE_H_ 6 #define COMPONENTS_PREFS_WRAP_WITH_PREFIX_PREF_STORE_H_ 7 8 #include <optional> 9 #include <string> 10 #include <string_view> 11 12 #include "base/observer_list.h" 13 #include "components/prefs/persistent_pref_store.h" 14 15 // This is a wrapper over another PersistentPrefStore. 16 // This can be used to implement a pref store over a dictionary in the 17 // PersistentPrefStore. 18 // For example, consider the following JSON being handled by a JsonPrefStore: 19 // { 20 // "foo": "Hello World", 21 // "bar": { 22 // "foobar": "Goodbye World" 23 // } 24 // } 25 // 26 // A WrapWithPrefixPrefStore can help operate on the dict for "bar", directly. 27 // That is, any query for "foobar" on this store will correspond to a query for 28 // "bar.foobar" in the JsonPrefStore. 29 // 30 // This is achieved by prefixing all the queries with the provided prefix. 31 // 32 // This can be used to merge separate pref stores into one single storage under 33 // separate dictionary items. 34 // 35 // NOTE: Users are responsible for ensuring the prefix is not an existing pref. 36 class COMPONENTS_PREFS_EXPORT WrapWithPrefixPrefStore 37 : public PersistentPrefStore, 38 public PrefStore::Observer { 39 public: 40 WrapWithPrefixPrefStore(scoped_refptr<PersistentPrefStore> target_pref_store, 41 std::string_view path_prefix); 42 43 WrapWithPrefixPrefStore(const WrapWithPrefixPrefStore&) = delete; 44 WrapWithPrefixPrefStore& operator=(const WrapWithPrefixPrefStore&) = delete; 45 46 // PrefStore implementation. 47 bool GetValue(std::string_view key, 48 const base::Value** result) const override; 49 base::Value::Dict GetValues() const override; 50 void AddObserver(PrefStore::Observer* observer) override; 51 void RemoveObserver(PrefStore::Observer* observer) override; 52 bool HasObservers() const override; 53 bool IsInitializationComplete() const override; 54 55 // PersistentPrefStore implementation. 56 bool GetMutableValue(std::string_view key, base::Value** result) override; 57 void ReportValueChanged(std::string_view key, uint32_t flags) override; 58 void SetValue(std::string_view key, 59 base::Value value, 60 uint32_t flags) override; 61 void SetValueSilently(std::string_view key, 62 base::Value value, 63 uint32_t flags) override; 64 void RemoveValue(std::string_view key, uint32_t flags) override; 65 bool ReadOnly() const override; 66 PrefReadError GetReadError() const override; 67 PersistentPrefStore::PrefReadError ReadPrefs() override; 68 void ReadPrefsAsync(ReadErrorDelegate* error_delegate) override; 69 void SchedulePendingLossyWrites() override; 70 void OnStoreDeletionFromDisk() override; 71 void RemoveValuesByPrefixSilently(std::string_view prefix) override; 72 bool HasReadErrorDelegate() const override; 73 74 // PrefStore::Observer implementation. 75 void OnPrefValueChanged(std::string_view key) override; 76 void OnInitializationCompleted(bool succeeded) override; 77 78 protected: 79 ~WrapWithPrefixPrefStore() override; 80 81 private: 82 std::string AddDottedPrefix(std::string_view path) const; 83 std::string_view RemoveDottedPrefix(std::string_view path) const; 84 bool HasDottedPrefix(std::string_view path) const; 85 86 scoped_refptr<PersistentPrefStore> target_pref_store_; 87 const std::string dotted_prefix_; 88 89 base::ObserverList<PrefStore::Observer, true> observers_; 90 91 // Optional so we can differentiate `nullopt` from `nullptr`. 92 std::optional<std::unique_ptr<PersistentPrefStore::ReadErrorDelegate>> 93 read_error_delegate_; 94 }; 95 96 #endif // COMPONENTS_PREFS_WRAP_WITH_PREFIX_PREF_STORE_H_ 97