blob: 3cee7ebd7d5c7b5001051a54d79bc32a722c38e5 [file] [log] [blame]
Avi Drissman8ba1bad2022-09-13 19:22:361// Copyright 2012 The Chromium Authors
[email protected]39565dd2011-11-14 12:09:272// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
brettwf00b9b42016-02-01 22:11:385#include "components/prefs/overlay_user_pref_store.h"
[email protected]39565dd2011-11-14 12:09:276
dcheng5f043bc2016-04-22 19:09:067#include <memory>
Peter Kastingb2777ce2021-07-20 18:28:548#include <ostream>
Roland Bock24a7c862022-09-26 07:29:489#include <string>
Helmut Januschka3ae90002024-05-02 18:42:2810#include <string_view>
danakj0c8d4aa2015-11-25 05:29:5811#include <utility>
12
dcheng5f043bc2016-04-22 19:09:0613#include "base/memory/ptr_util.h"
Keishi Hattori0e45c022021-11-27 09:25:5214#include "base/memory/raw_ptr.h"
David Sanders88b24432022-02-28 01:10:0215#include "base/observer_list.h"
[email protected]39565dd2011-11-14 12:09:2716#include "base/values.h"
Johan Tibell0595f762017-05-25 23:54:5017#include "components/prefs/in_memory_pref_store.h"
[email protected]39565dd2011-11-14 12:09:2718
Johan Tibell0595f762017-05-25 23:54:5019// 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).
22class OverlayUserPrefStore::ObserverAdapter : public PrefStore::Observer {
23 public:
Ramin Halavatif623bafe92018-07-17 12:12:5824 ObserverAdapter(bool ephemeral, OverlayUserPrefStore* parent)
25 : ephemeral_user_pref_store_(ephemeral), parent_(parent) {}
Johan Tibell0595f762017-05-25 23:54:5026
27 // Methods of PrefStore::Observer.
Jan Keitel0523c5e32024-06-28 13:58:5228 void OnPrefValueChanged(std::string_view key) override {
Jan Keitel07b772b2024-06-28 14:34:3029 parent_->OnPrefValueChanged(ephemeral_user_pref_store_, key);
Johan Tibell0595f762017-05-25 23:54:5030 }
31 void OnInitializationCompleted(bool succeeded) override {
Ramin Halavatif623bafe92018-07-17 12:12:5832 parent_->OnInitializationCompleted(ephemeral_user_pref_store_, succeeded);
Johan Tibell0595f762017-05-25 23:54:5033 }
34
35 private:
Ramin Halavatif623bafe92018-07-17 12:12:5836 // Is the update for the ephemeral?
37 const bool ephemeral_user_pref_store_;
Keishi Hattori0e45c022021-11-27 09:25:5238 const raw_ptr<OverlayUserPrefStore> parent_;
Johan Tibell0595f762017-05-25 23:54:5039};
40
Ramin Halavatif623bafe92018-07-17 12:12:5841OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* persistent)
42 : OverlayUserPrefStore(new InMemoryPrefStore(), persistent) {}
Johan Tibell0595f762017-05-25 23:54:5043
Ramin Halavatif623bafe92018-07-17 12:12:5844OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* ephemeral,
45 PersistentPrefStore* persistent)
46 : ephemeral_pref_store_observer_(
Jinho Bang84b58bd2018-01-01 21:44:4847 std::make_unique<OverlayUserPrefStore::ObserverAdapter>(true, this)),
Ramin Halavatif623bafe92018-07-17 12:12:5848 persistent_pref_store_observer_(
Jinho Bang84b58bd2018-01-01 21:44:4849 std::make_unique<OverlayUserPrefStore::ObserverAdapter>(false, this)),
Ramin Halavatif623bafe92018-07-17 12:12:5850 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());
[email protected]39565dd2011-11-14 12:09:2756}
57
Jan Keitel6288ad6b2024-07-26 09:00:1458bool OverlayUserPrefStore::IsSetInOverlay(std::string_view key) const {
Ramin Halavatif623bafe92018-07-17 12:12:5859 return ephemeral_user_pref_store_->GetValue(key, nullptr);
[email protected]39565dd2011-11-14 12:09:2760}
61
62void OverlayUserPrefStore::AddObserver(PrefStore::Observer* observer) {
63 observers_.AddObserver(observer);
64}
65
66void OverlayUserPrefStore::RemoveObserver(PrefStore::Observer* observer) {
67 observers_.RemoveObserver(observer);
68}
69
[email protected]14e0ec62013-08-26 22:01:3970bool OverlayUserPrefStore::HasObservers() const {
Mitsuru Oshima28f9b6812021-01-20 19:33:0771 return !observers_.empty();
[email protected]d3b05ea2012-01-24 22:57:0572}
73
[email protected]39565dd2011-11-14 12:09:2774bool OverlayUserPrefStore::IsInitializationComplete() const {
Ramin Halavatif623bafe92018-07-17 12:12:5875 return persistent_user_pref_store_->IsInitializationComplete() &&
76 ephemeral_user_pref_store_->IsInitializationComplete();
[email protected]39565dd2011-11-14 12:09:2777}
78
Helmut Januschka3ae90002024-05-02 18:42:2879bool OverlayUserPrefStore::GetValue(std::string_view key,
[email protected]a43a667b2013-06-14 17:56:0880 const base::Value** result) const {
Ramin Halavatif623bafe92018-07-17 12:12:5881 // If the |key| shall NOT be stored in the ephemeral store, there must not
[email protected]39565dd2011-11-14 12:09:2782 // be an entry.
Ramin Halavatif623bafe92018-07-17 12:12:5883 DCHECK(!ShallBeStoredInPersistent(key) ||
84 !ephemeral_user_pref_store_->GetValue(key, nullptr));
[email protected]39565dd2011-11-14 12:09:2785
Ramin Halavatif623bafe92018-07-17 12:12:5886 if (ephemeral_user_pref_store_->GetValue(key, result))
[email protected]892f1d62012-11-08 18:24:3487 return true;
Ramin Halavatif623bafe92018-07-17 12:12:5888 return persistent_user_pref_store_->GetValue(key, result);
[email protected]39565dd2011-11-14 12:09:2789}
90
Matt Menke38ac93c2022-08-17 03:12:5991base::Value::Dict OverlayUserPrefStore::GetValues() const {
Ramin Halavatif623bafe92018-07-17 12:12:5892 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_) {
Arthur Sonzognic571efb2024-01-26 20:26:18100 std::optional<base::Value> out_value =
Matt Menke38ac93c2022-08-17 03:12:59101 persistent_values.ExtractByDottedPath(key);
Song Fangzhen61767882021-07-16 04:59:40102 if (out_value.has_value()) {
Matt Menke38ac93c2022-08-17 03:12:59103 values.SetByDottedPath(key, std::move(*out_value));
tibelle23659b42017-02-23 01:44:13104 }
105 }
106 return values;
107}
108
Jan Keitel331cd1692024-06-28 14:30:53109bool OverlayUserPrefStore::GetMutableValue(std::string_view key,
[email protected]a43a667b2013-06-14 17:56:08110 base::Value** result) {
Ramin Halavatif623bafe92018-07-17 12:12:58111 if (ShallBeStoredInPersistent(key))
112 return persistent_user_pref_store_->GetMutableValue(key, result);
[email protected]39565dd2011-11-14 12:09:27113
Ramin Halavatif623bafe92018-07-17 12:12:58114 if (ephemeral_user_pref_store_->GetMutableValue(key, result))
[email protected]892f1d62012-11-08 18:24:34115 return true;
[email protected]39565dd2011-11-14 12:09:27116
Ramin Halavatif623bafe92018-07-17 12:12:58117 // 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))
[email protected]892f1d62012-11-08 18:24:34120 return false;
[email protected]39565dd2011-11-14 12:09:27121
Ramin Halavatif623bafe92018-07-17 12:12:58122 ephemeral_user_pref_store_->SetValue(
Roland Bocke01119d2022-09-29 01:21:41123 key, persistent_value->Clone(),
Ramin Halavatif623bafe92018-07-17 12:12:58124 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
Vladislav Kuzkokov8ee75fbc2019-01-14 14:14:04125 ephemeral_user_pref_store_->GetMutableValue(key, result);
[email protected]892f1d62012-11-08 18:24:34126 return true;
[email protected]39565dd2011-11-14 12:09:27127}
128
Jan Keitel331cd1692024-06-28 14:30:53129void OverlayUserPrefStore::SetValue(std::string_view key,
Roland Bocke01119d2022-09-29 01:21:41130 base::Value value,
avi9ef8bb02015-12-24 05:29:36131 uint32_t flags) {
Ramin Halavatif623bafe92018-07-17 12:12:58132 if (ShallBeStoredInPersistent(key)) {
133 persistent_user_pref_store_->SetValue(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27134 return;
135 }
136
Alison Galeb8be9522024-04-16 00:00:31137 // TODO(crbug.com/40584094): If we always store in in-memory storage
Ramin Halavatif623bafe92018-07-17 12:12:58138 // and conditionally also stored in persistent one, we wouldn't have to do a
139 // complex merge in GetValues().
Ramin Halavatif623bafe92018-07-17 12:12:58140 ephemeral_user_pref_store_->SetValue(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27141}
142
Jan Keitel331cd1692024-06-28 14:30:53143void OverlayUserPrefStore::SetValueSilently(std::string_view key,
Roland Bocke01119d2022-09-29 01:21:41144 base::Value value,
avi9ef8bb02015-12-24 05:29:36145 uint32_t flags) {
Ramin Halavatif623bafe92018-07-17 12:12:58146 if (ShallBeStoredInPersistent(key)) {
147 persistent_user_pref_store_->SetValueSilently(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27148 return;
149 }
150
Ramin Halavatif623bafe92018-07-17 12:12:58151 ephemeral_user_pref_store_->SetValueSilently(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27152}
153
Jan Keitel331cd1692024-06-28 14:30:53154void OverlayUserPrefStore::RemoveValue(std::string_view key, uint32_t flags) {
Ramin Halavatif623bafe92018-07-17 12:12:58155 if (ShallBeStoredInPersistent(key)) {
156 persistent_user_pref_store_->RemoveValue(key, flags);
[email protected]39565dd2011-11-14 12:09:27157 return;
158 }
159
Ramin Halavatif623bafe92018-07-17 12:12:58160 ephemeral_user_pref_store_->RemoveValue(key, flags);
[email protected]39565dd2011-11-14 12:09:27161}
162
Anatoliy Potapchuk5d9d8de2020-04-21 02:09:26163void OverlayUserPrefStore::RemoveValuesByPrefixSilently(
Jan Keitel331cd1692024-06-28 14:30:53164 std::string_view prefix) {
Anatoliy Potapchuk5d9d8de2020-04-21 02:09:26165 NOTIMPLEMENTED();
166}
167
[email protected]39565dd2011-11-14 12:09:27168bool OverlayUserPrefStore::ReadOnly() const {
169 return false;
170}
171
[email protected]59c10712012-03-13 02:10:34172PersistentPrefStore::PrefReadError OverlayUserPrefStore::GetReadError() const {
173 return PersistentPrefStore::PREF_READ_ERROR_NONE;
174}
175
[email protected]39565dd2011-11-14 12:09:27176PersistentPrefStore::PrefReadError OverlayUserPrefStore::ReadPrefs() {
177 // We do not read intentionally.
Ramin Halavatif623bafe92018-07-17 12:12:58178 OnInitializationCompleted(/* ephemeral */ false, true);
[email protected]39565dd2011-11-14 12:09:27179 return PersistentPrefStore::PREF_READ_ERROR_NONE;
180}
181
182void OverlayUserPrefStore::ReadPrefsAsync(
183 ReadErrorDelegate* error_delegate_raw) {
dcheng5f043bc2016-04-22 19:09:06184 std::unique_ptr<ReadErrorDelegate> error_delegate(error_delegate_raw);
[email protected]39565dd2011-11-14 12:09:27185 // We do not read intentionally.
Ramin Halavatif623bafe92018-07-17 12:12:58186 OnInitializationCompleted(/* ephemeral */ false, true);
[email protected]39565dd2011-11-14 12:09:27187}
188
Gabriel Charette788eaf62018-08-07 20:11:46189void 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));
[email protected]39565dd2011-11-14 12:09:27194 // We do not write our content intentionally.
195}
196
benwells26730592015-05-28 13:08:08197void OverlayUserPrefStore::SchedulePendingLossyWrites() {
Ramin Halavatif623bafe92018-07-17 12:12:58198 persistent_user_pref_store_->SchedulePendingLossyWrites();
benwells26730592015-05-28 13:08:08199}
200
Jan Keitel331cd1692024-06-28 14:30:53201void OverlayUserPrefStore::ReportValueChanged(std::string_view key,
avi9ef8bb02015-12-24 05:29:36202 uint32_t flags) {
ericwilligers42b92c12016-10-24 20:21:13203 for (PrefStore::Observer& observer : observers_)
204 observer.OnPrefValueChanged(key);
[email protected]39565dd2011-11-14 12:09:27205}
206
Jan Keitel6288ad6b2024-07-26 09:00:14207void OverlayUserPrefStore::RegisterPersistentPref(std::string_view key) {
Johan Tibell6566c8ac2017-05-11 03:22:17208 DCHECK(!key.empty()) << "Key is empty";
Ramin Halavatif623bafe92018-07-17 12:12:58209 DCHECK(persistent_names_set_.find(key) == persistent_names_set_.end())
210 << "Key already registered: " << key;
Jan Keitel6288ad6b2024-07-26 09:00:14211 persistent_names_set_.insert(std::string(key));
[email protected]39565dd2011-11-14 12:09:27212}
213
proberge45e347282017-08-16 21:24:05214void OverlayUserPrefStore::OnStoreDeletionFromDisk() {
Ramin Halavatif623bafe92018-07-17 12:12:58215 persistent_user_pref_store_->OnStoreDeletionFromDisk();
proberge45e347282017-08-16 21:24:05216}
217
[email protected]2dea5c02012-04-25 07:01:07218OverlayUserPrefStore::~OverlayUserPrefStore() {
Ramin Halavatif623bafe92018-07-17 12:12:58219 ephemeral_user_pref_store_->RemoveObserver(
220 ephemeral_pref_store_observer_.get());
221 persistent_user_pref_store_->RemoveObserver(
222 persistent_pref_store_observer_.get());
Johan Tibell0595f762017-05-25 23:54:50223}
224
Ramin Halavatif623bafe92018-07-17 12:12:58225void OverlayUserPrefStore::OnPrefValueChanged(bool ephemeral,
Jan Keitel07b772b2024-06-28 14:34:30226 std::string_view key) {
Ramin Halavatif623bafe92018-07-17 12:12:58227 if (ephemeral) {
Johan Tibell0595f762017-05-25 23:54:50228 ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
229 } else {
Ramin Halavatif623bafe92018-07-17 12:12:58230 if (!ephemeral_user_pref_store_->GetValue(key, nullptr))
Johan Tibell0595f762017-05-25 23:54:50231 ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
232 }
233}
234
Ramin Halavatif623bafe92018-07-17 12:12:58235void OverlayUserPrefStore::OnInitializationCompleted(bool ephemeral,
Johan Tibell0595f762017-05-25 23:54:50236 bool succeeded) {
237 if (!IsInitializationComplete())
238 return;
239 for (PrefStore::Observer& observer : observers_)
240 observer.OnInitializationCompleted(succeeded);
[email protected]39565dd2011-11-14 12:09:27241}
242
Ramin Halavatif623bafe92018-07-17 12:12:58243bool OverlayUserPrefStore::ShallBeStoredInPersistent(
Helmut Januschka3ae90002024-05-02 18:42:28244 std::string_view key) const {
Ramin Halavatif623bafe92018-07-17 12:12:58245 return persistent_names_set_.find(key) != persistent_names_set_.end();
[email protected]39565dd2011-11-14 12:09:27246}
Ankush Singha77ee8392024-05-15 08:20:41247
248bool OverlayUserPrefStore::HasReadErrorDelegate() const {
249 return persistent_user_pref_store_->HasReadErrorDelegate();
250}