• 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 #include "components/prefs/wrap_with_prefix_pref_store.h"
6 
7 #include <string>
8 #include <string_view>
9 
10 #include "base/strings/strcat.h"
11 #include "base/strings/string_util.h"
12 
WrapWithPrefixPrefStore(scoped_refptr<PersistentPrefStore> target_pref_store,std::string_view path_prefix)13 WrapWithPrefixPrefStore::WrapWithPrefixPrefStore(
14     scoped_refptr<PersistentPrefStore> target_pref_store,
15     std::string_view path_prefix)
16     : target_pref_store_(std::move(target_pref_store)),
17       dotted_prefix_(base::StrCat({path_prefix, "."})) {
18   target_pref_store_->AddObserver(this);
19 }
20 
~WrapWithPrefixPrefStore()21 WrapWithPrefixPrefStore::~WrapWithPrefixPrefStore() {
22   target_pref_store_->RemoveObserver(this);
23 }
24 
GetValue(std::string_view key,const base::Value ** value) const25 bool WrapWithPrefixPrefStore::GetValue(std::string_view key,
26                                        const base::Value** value) const {
27   return target_pref_store_->GetValue(AddDottedPrefix(key), value);
28 }
29 
GetValues() const30 base::Value::Dict WrapWithPrefixPrefStore::GetValues() const {
31   base::Value::Dict values = target_pref_store_->GetValues();
32   std::string_view prefix(dotted_prefix_.c_str(), dotted_prefix_.size() - 1);
33   if (base::Value::Dict* values_with_prefix =
34           values.FindDictByDottedPath(prefix)) {
35     return std::move(*values_with_prefix);
36   }
37   return {};
38 }
39 
GetMutableValue(std::string_view key,base::Value ** value)40 bool WrapWithPrefixPrefStore::GetMutableValue(std::string_view key,
41                                               base::Value** value) {
42   return target_pref_store_->GetMutableValue(AddDottedPrefix(key), value);
43 }
44 
AddObserver(PrefStore::Observer * observer)45 void WrapWithPrefixPrefStore::AddObserver(PrefStore::Observer* observer) {
46   observers_.AddObserver(observer);
47 }
48 
RemoveObserver(PrefStore::Observer * observer)49 void WrapWithPrefixPrefStore::RemoveObserver(PrefStore::Observer* observer) {
50   observers_.RemoveObserver(observer);
51 }
52 
HasObservers() const53 bool WrapWithPrefixPrefStore::HasObservers() const {
54   return !observers_.empty();
55 }
56 
IsInitializationComplete() const57 bool WrapWithPrefixPrefStore::IsInitializationComplete() const {
58   return target_pref_store_->IsInitializationComplete();
59 }
60 
SetValue(std::string_view key,base::Value value,uint32_t flags)61 void WrapWithPrefixPrefStore::SetValue(std::string_view key,
62                                        base::Value value,
63                                        uint32_t flags) {
64   target_pref_store_->SetValue(AddDottedPrefix(key), std::move(value), flags);
65 }
66 
SetValueSilently(std::string_view key,base::Value value,uint32_t flags)67 void WrapWithPrefixPrefStore::SetValueSilently(std::string_view key,
68                                                base::Value value,
69                                                uint32_t flags) {
70   target_pref_store_->SetValueSilently(AddDottedPrefix(key), std::move(value),
71                                        flags);
72 }
73 
RemoveValue(std::string_view key,uint32_t flags)74 void WrapWithPrefixPrefStore::RemoveValue(std::string_view key,
75                                           uint32_t flags) {
76   target_pref_store_->RemoveValue(AddDottedPrefix(key), flags);
77 }
78 
RemoveValuesByPrefixSilently(std::string_view prefix)79 void WrapWithPrefixPrefStore::RemoveValuesByPrefixSilently(
80     std::string_view prefix) {
81   target_pref_store_->RemoveValuesByPrefixSilently(AddDottedPrefix(prefix));
82 }
83 
ReadOnly() const84 bool WrapWithPrefixPrefStore::ReadOnly() const {
85   return target_pref_store_->ReadOnly();
86 }
87 
GetReadError() const88 PersistentPrefStore::PrefReadError WrapWithPrefixPrefStore::GetReadError()
89     const {
90   return target_pref_store_->GetReadError();
91 }
92 
ReadPrefs()93 PersistentPrefStore::PrefReadError WrapWithPrefixPrefStore::ReadPrefs() {
94   // The target pref store should have been initialized prior to calling
95   // ReadPrefs() on this store.
96   CHECK(target_pref_store_->IsInitializationComplete() ||
97         // To catch case where target pref store initialization failed.
98         target_pref_store_->GetReadError() !=
99             PersistentPrefStore::PREF_READ_ERROR_NONE);
100   return target_pref_store_->GetReadError();
101 }
102 
ReadPrefsAsync(ReadErrorDelegate * error_delegate)103 void WrapWithPrefixPrefStore::ReadPrefsAsync(
104     ReadErrorDelegate* error_delegate) {
105   // The target pref store should either have been initialized or should have an
106   // ongoing read.
107   CHECK(IsInitializationComplete() ||
108         // To catch case where target pref store initialization failed.
109         GetReadError() != PersistentPrefStore::PREF_READ_ERROR_NONE ||
110         // ReadPrefsAsync() was called but it's still ongoing.
111         target_pref_store_->HasReadErrorDelegate());
112   read_error_delegate_.emplace(error_delegate);
113   if (PersistentPrefStore::PrefReadError read_error = GetReadError();
114       read_error != PersistentPrefStore::PREF_READ_ERROR_NONE &&
115       error_delegate) {
116     error_delegate->OnError(read_error);
117   }
118 }
119 
SchedulePendingLossyWrites()120 void WrapWithPrefixPrefStore::SchedulePendingLossyWrites() {
121   // This store is only a wrapper and relies on the target pref store being
122   // independently notified of this.
123 }
124 
OnStoreDeletionFromDisk()125 void WrapWithPrefixPrefStore::OnStoreDeletionFromDisk() {
126   // This store is only a wrapper and relies on the target pref store being
127   // independently notified of this.
128 }
129 
ReportValueChanged(std::string_view key,uint32_t flags)130 void WrapWithPrefixPrefStore::ReportValueChanged(std::string_view key,
131                                                  uint32_t flags) {
132   return target_pref_store_->ReportValueChanged(AddDottedPrefix(key), flags);
133 }
134 
OnPrefValueChanged(std::string_view key)135 void WrapWithPrefixPrefStore::OnPrefValueChanged(std::string_view key) {
136   if (!HasDottedPrefix(key)) {
137     return;
138   }
139   std::string_view original_key(RemoveDottedPrefix(key));
140   for (PrefStore::Observer& observer : observers_) {
141     observer.OnPrefValueChanged(original_key);
142   }
143 }
144 
OnInitializationCompleted(bool succeeded)145 void WrapWithPrefixPrefStore::OnInitializationCompleted(bool succeeded) {
146   if (PersistentPrefStore::PrefReadError read_error = GetReadError();
147       read_error != PersistentPrefStore::PREF_READ_ERROR_NONE &&
148       read_error_delegate_.has_value() && read_error_delegate_.value()) {
149     read_error_delegate_.value()->OnError(read_error);
150   }
151   for (PrefStore::Observer& observer : observers_) {
152     observer.OnInitializationCompleted(succeeded);
153   }
154 }
155 
AddDottedPrefix(std::string_view path) const156 std::string WrapWithPrefixPrefStore::AddDottedPrefix(
157     std::string_view path) const {
158   return base::StrCat({dotted_prefix_, path});
159 }
160 
RemoveDottedPrefix(std::string_view path) const161 std::string_view WrapWithPrefixPrefStore::RemoveDottedPrefix(
162     std::string_view path) const {
163   CHECK(HasDottedPrefix(path));
164   path.remove_prefix(dotted_prefix_.size());
165   return path;
166 }
167 
HasDottedPrefix(std::string_view path) const168 bool WrapWithPrefixPrefStore::HasDottedPrefix(std::string_view path) const {
169   return base::StartsWith(path, dotted_prefix_);
170 }
171 
HasReadErrorDelegate() const172 bool WrapWithPrefixPrefStore::HasReadErrorDelegate() const {
173   return read_error_delegate_.has_value();
174 }
175