• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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