Fix emulator build error
[platform/framework/web/chromium-efl.git] / components / prefs / overlay_user_pref_store.cc
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 #include "components/prefs/overlay_user_pref_store.h"
6
7 #include <memory>
8 #include <ostream>
9 #include <string>
10 #include <utility>
11
12 #include "base/memory/ptr_util.h"
13 #include "base/memory/raw_ptr.h"
14 #include "base/observer_list.h"
15 #include "base/strings/string_piece.h"
16 #include "base/values.h"
17 #include "components/prefs/in_memory_pref_store.h"
18
19 // Allows us to monitor two pref stores and tell updates from them apart. It
20 // essentially mimics a Callback for the Observer interface (e.g. it allows
21 // binding additional arguments).
22 class OverlayUserPrefStore::ObserverAdapter : public PrefStore::Observer {
23  public:
24   ObserverAdapter(bool ephemeral, OverlayUserPrefStore* parent)
25       : ephemeral_user_pref_store_(ephemeral), parent_(parent) {}
26
27   // Methods of PrefStore::Observer.
28   void OnPrefValueChanged(const std::string& key) override {
29     parent_->OnPrefValueChanged(ephemeral_user_pref_store_, key);
30   }
31   void OnInitializationCompleted(bool succeeded) override {
32     parent_->OnInitializationCompleted(ephemeral_user_pref_store_, succeeded);
33   }
34
35  private:
36   // Is the update for the ephemeral?
37   const bool ephemeral_user_pref_store_;
38   const raw_ptr<OverlayUserPrefStore> parent_;
39 };
40
41 OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* persistent)
42     : OverlayUserPrefStore(new InMemoryPrefStore(), persistent) {}
43
44 OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* ephemeral,
45                                            PersistentPrefStore* persistent)
46     : ephemeral_pref_store_observer_(
47           std::make_unique<OverlayUserPrefStore::ObserverAdapter>(true, this)),
48       persistent_pref_store_observer_(
49           std::make_unique<OverlayUserPrefStore::ObserverAdapter>(false, this)),
50       ephemeral_user_pref_store_(ephemeral),
51       persistent_user_pref_store_(persistent) {
52   DCHECK(ephemeral->IsInitializationComplete());
53   ephemeral_user_pref_store_->AddObserver(ephemeral_pref_store_observer_.get());
54   persistent_user_pref_store_->AddObserver(
55       persistent_pref_store_observer_.get());
56 }
57
58 bool OverlayUserPrefStore::IsSetInOverlay(const std::string& key) const {
59   return ephemeral_user_pref_store_->GetValue(key, nullptr);
60 }
61
62 void OverlayUserPrefStore::AddObserver(PrefStore::Observer* observer) {
63   observers_.AddObserver(observer);
64 }
65
66 void OverlayUserPrefStore::RemoveObserver(PrefStore::Observer* observer) {
67   observers_.RemoveObserver(observer);
68 }
69
70 bool OverlayUserPrefStore::HasObservers() const {
71   return !observers_.empty();
72 }
73
74 bool OverlayUserPrefStore::IsInitializationComplete() const {
75   return persistent_user_pref_store_->IsInitializationComplete() &&
76          ephemeral_user_pref_store_->IsInitializationComplete();
77 }
78
79 bool OverlayUserPrefStore::GetValue(base::StringPiece key,
80                                     const base::Value** result) const {
81   // If the |key| shall NOT be stored in the ephemeral store, there must not
82   // be an entry.
83   DCHECK(!ShallBeStoredInPersistent(key) ||
84          !ephemeral_user_pref_store_->GetValue(key, nullptr));
85
86   if (ephemeral_user_pref_store_->GetValue(key, result))
87     return true;
88   return persistent_user_pref_store_->GetValue(key, result);
89 }
90
91 base::Value::Dict OverlayUserPrefStore::GetValues() const {
92   auto values = ephemeral_user_pref_store_->GetValues();
93   auto persistent_values = persistent_user_pref_store_->GetValues();
94
95   // Output |values| are read from |ephemeral_user_pref_store_| (in-memory
96   // store). Then the values of preferences in |persistent_names_set_| are
97   // overwritten by the content of |persistent_user_pref_store_| (the persistent
98   // store).
99   for (const auto& key : persistent_names_set_) {
100     absl::optional<base::Value> out_value =
101         persistent_values.ExtractByDottedPath(key);
102     if (out_value.has_value()) {
103       values.SetByDottedPath(key, std::move(*out_value));
104     }
105   }
106   return values;
107 }
108
109 bool OverlayUserPrefStore::GetMutableValue(const std::string& key,
110                                            base::Value** result) {
111   if (ShallBeStoredInPersistent(key))
112     return persistent_user_pref_store_->GetMutableValue(key, result);
113
114   if (ephemeral_user_pref_store_->GetMutableValue(key, result))
115     return true;
116
117   // Try to create copy of persistent if the ephemeral does not contain a value.
118   base::Value* persistent_value = nullptr;
119   if (!persistent_user_pref_store_->GetMutableValue(key, &persistent_value))
120     return false;
121
122   ephemeral_user_pref_store_->SetValue(
123       key, persistent_value->Clone(),
124       WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
125   ephemeral_user_pref_store_->GetMutableValue(key, result);
126   return true;
127 }
128
129 void OverlayUserPrefStore::SetValue(const std::string& key,
130                                     base::Value value,
131                                     uint32_t flags) {
132   if (ShallBeStoredInPersistent(key)) {
133     persistent_user_pref_store_->SetValue(key, std::move(value), flags);
134     return;
135   }
136
137   // TODO(https://crbug.com/861722): If we always store in in-memory storage
138   // and conditionally also stored in persistent one, we wouldn't have to do a
139   // complex merge in GetValues().
140   ephemeral_user_pref_store_->SetValue(key, std::move(value), flags);
141 }
142
143 void OverlayUserPrefStore::SetValueSilently(const std::string& key,
144                                             base::Value value,
145                                             uint32_t flags) {
146   if (ShallBeStoredInPersistent(key)) {
147     persistent_user_pref_store_->SetValueSilently(key, std::move(value), flags);
148     return;
149   }
150
151   ephemeral_user_pref_store_->SetValueSilently(key, std::move(value), flags);
152 }
153
154 void OverlayUserPrefStore::RemoveValue(const std::string& key, uint32_t flags) {
155   if (ShallBeStoredInPersistent(key)) {
156     persistent_user_pref_store_->RemoveValue(key, flags);
157     return;
158   }
159
160   ephemeral_user_pref_store_->RemoveValue(key, flags);
161 }
162
163 void OverlayUserPrefStore::RemoveValuesByPrefixSilently(
164     const std::string& prefix) {
165   NOTIMPLEMENTED();
166 }
167
168 bool OverlayUserPrefStore::ReadOnly() const {
169   return false;
170 }
171
172 PersistentPrefStore::PrefReadError OverlayUserPrefStore::GetReadError() const {
173   return PersistentPrefStore::PREF_READ_ERROR_NONE;
174 }
175
176 PersistentPrefStore::PrefReadError OverlayUserPrefStore::ReadPrefs() {
177   // We do not read intentionally.
178   OnInitializationCompleted(/* ephemeral */ false, true);
179   return PersistentPrefStore::PREF_READ_ERROR_NONE;
180 }
181
182 void OverlayUserPrefStore::ReadPrefsAsync(
183     ReadErrorDelegate* error_delegate_raw) {
184   std::unique_ptr<ReadErrorDelegate> error_delegate(error_delegate_raw);
185   // We do not read intentionally.
186   OnInitializationCompleted(/* ephemeral */ false, true);
187 }
188
189 void OverlayUserPrefStore::CommitPendingWrite(
190     base::OnceClosure reply_callback,
191     base::OnceClosure synchronous_done_callback) {
192   persistent_user_pref_store_->CommitPendingWrite(
193       std::move(reply_callback), std::move(synchronous_done_callback));
194   // We do not write our content intentionally.
195 }
196
197 void OverlayUserPrefStore::SchedulePendingLossyWrites() {
198   persistent_user_pref_store_->SchedulePendingLossyWrites();
199 }
200
201 void OverlayUserPrefStore::ReportValueChanged(const std::string& key,
202                                               uint32_t flags) {
203   for (PrefStore::Observer& observer : observers_)
204     observer.OnPrefValueChanged(key);
205 }
206
207 void OverlayUserPrefStore::RegisterPersistentPref(const std::string& key) {
208   DCHECK(!key.empty()) << "Key is empty";
209   DCHECK(persistent_names_set_.find(key) == persistent_names_set_.end())
210       << "Key already registered: " << key;
211   persistent_names_set_.insert(key);
212 }
213
214 void OverlayUserPrefStore::OnStoreDeletionFromDisk() {
215   persistent_user_pref_store_->OnStoreDeletionFromDisk();
216 }
217
218 OverlayUserPrefStore::~OverlayUserPrefStore() {
219   ephemeral_user_pref_store_->RemoveObserver(
220       ephemeral_pref_store_observer_.get());
221   persistent_user_pref_store_->RemoveObserver(
222       persistent_pref_store_observer_.get());
223 }
224
225 void OverlayUserPrefStore::OnPrefValueChanged(bool ephemeral,
226                                               const std::string& key) {
227   if (ephemeral) {
228     ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
229   } else {
230     if (!ephemeral_user_pref_store_->GetValue(key, nullptr))
231       ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
232   }
233 }
234
235 void OverlayUserPrefStore::OnInitializationCompleted(bool ephemeral,
236                                                      bool succeeded) {
237   if (!IsInitializationComplete())
238     return;
239   for (PrefStore::Observer& observer : observers_)
240     observer.OnInitializationCompleted(succeeded);
241 }
242
243 bool OverlayUserPrefStore::ShallBeStoredInPersistent(
244     base::StringPiece key) const {
245   return persistent_names_set_.find(key) != persistent_names_set_.end();
246 }