blob: bb6d999134c26646a66a0e6db3ab72cff6a16b06 [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"
Daniel Chengbc5784f032025-06-19 19:35:0515#include "base/notimplemented.h"
David Sanders88b24432022-02-28 01:10:0216#include "base/observer_list.h"
[email protected]39565dd2011-11-14 12:09:2717#include "base/values.h"
Johan Tibell0595f762017-05-25 23:54:5018#include "components/prefs/in_memory_pref_store.h"
[email protected]39565dd2011-11-14 12:09:2719
Johan Tibell0595f762017-05-25 23:54:5020// Allows us to monitor two pref stores and tell updates from them apart. It
21// essentially mimics a Callback for the Observer interface (e.g. it allows
22// binding additional arguments).
23class OverlayUserPrefStore::ObserverAdapter : public PrefStore::Observer {
24 public:
Ramin Halavatif623bafe92018-07-17 12:12:5825 ObserverAdapter(bool ephemeral, OverlayUserPrefStore* parent)
26 : ephemeral_user_pref_store_(ephemeral), parent_(parent) {}
Johan Tibell0595f762017-05-25 23:54:5027
28 // Methods of PrefStore::Observer.
Jan Keitel0523c5e32024-06-28 13:58:5229 void OnPrefValueChanged(std::string_view key) override {
Jan Keitel07b772b2024-06-28 14:34:3030 parent_->OnPrefValueChanged(ephemeral_user_pref_store_, key);
Johan Tibell0595f762017-05-25 23:54:5031 }
32 void OnInitializationCompleted(bool succeeded) override {
Ramin Halavatif623bafe92018-07-17 12:12:5833 parent_->OnInitializationCompleted(ephemeral_user_pref_store_, succeeded);
Johan Tibell0595f762017-05-25 23:54:5034 }
35
36 private:
Ramin Halavatif623bafe92018-07-17 12:12:5837 // Is the update for the ephemeral?
38 const bool ephemeral_user_pref_store_;
Keishi Hattori0e45c022021-11-27 09:25:5239 const raw_ptr<OverlayUserPrefStore> parent_;
Johan Tibell0595f762017-05-25 23:54:5040};
41
Ramin Halavatif623bafe92018-07-17 12:12:5842OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* persistent)
43 : OverlayUserPrefStore(new InMemoryPrefStore(), persistent) {}
Johan Tibell0595f762017-05-25 23:54:5044
Ramin Halavatif623bafe92018-07-17 12:12:5845OverlayUserPrefStore::OverlayUserPrefStore(PersistentPrefStore* ephemeral,
46 PersistentPrefStore* persistent)
47 : ephemeral_pref_store_observer_(
Jinho Bang84b58bd2018-01-01 21:44:4848 std::make_unique<OverlayUserPrefStore::ObserverAdapter>(true, this)),
Ramin Halavatif623bafe92018-07-17 12:12:5849 persistent_pref_store_observer_(
Jinho Bang84b58bd2018-01-01 21:44:4850 std::make_unique<OverlayUserPrefStore::ObserverAdapter>(false, this)),
Ramin Halavatif623bafe92018-07-17 12:12:5851 ephemeral_user_pref_store_(ephemeral),
52 persistent_user_pref_store_(persistent) {
53 DCHECK(ephemeral->IsInitializationComplete());
54 ephemeral_user_pref_store_->AddObserver(ephemeral_pref_store_observer_.get());
55 persistent_user_pref_store_->AddObserver(
56 persistent_pref_store_observer_.get());
[email protected]39565dd2011-11-14 12:09:2757}
58
Jan Keitel6288ad6b2024-07-26 09:00:1459bool OverlayUserPrefStore::IsSetInOverlay(std::string_view key) const {
Ramin Halavatif623bafe92018-07-17 12:12:5860 return ephemeral_user_pref_store_->GetValue(key, nullptr);
[email protected]39565dd2011-11-14 12:09:2761}
62
63void OverlayUserPrefStore::AddObserver(PrefStore::Observer* observer) {
64 observers_.AddObserver(observer);
65}
66
67void OverlayUserPrefStore::RemoveObserver(PrefStore::Observer* observer) {
68 observers_.RemoveObserver(observer);
69}
70
[email protected]14e0ec62013-08-26 22:01:3971bool OverlayUserPrefStore::HasObservers() const {
Mitsuru Oshima28f9b6812021-01-20 19:33:0772 return !observers_.empty();
[email protected]d3b05ea2012-01-24 22:57:0573}
74
[email protected]39565dd2011-11-14 12:09:2775bool OverlayUserPrefStore::IsInitializationComplete() const {
Ramin Halavatif623bafe92018-07-17 12:12:5876 return persistent_user_pref_store_->IsInitializationComplete() &&
77 ephemeral_user_pref_store_->IsInitializationComplete();
[email protected]39565dd2011-11-14 12:09:2778}
79
Helmut Januschka3ae90002024-05-02 18:42:2880bool OverlayUserPrefStore::GetValue(std::string_view key,
[email protected]a43a667b2013-06-14 17:56:0881 const base::Value** result) const {
Ramin Halavatif623bafe92018-07-17 12:12:5882 // If the |key| shall NOT be stored in the ephemeral store, there must not
[email protected]39565dd2011-11-14 12:09:2783 // be an entry.
Ramin Halavatif623bafe92018-07-17 12:12:5884 DCHECK(!ShallBeStoredInPersistent(key) ||
85 !ephemeral_user_pref_store_->GetValue(key, nullptr));
[email protected]39565dd2011-11-14 12:09:2786
Ramin Halavatif623bafe92018-07-17 12:12:5887 if (ephemeral_user_pref_store_->GetValue(key, result))
[email protected]892f1d62012-11-08 18:24:3488 return true;
Ramin Halavatif623bafe92018-07-17 12:12:5889 return persistent_user_pref_store_->GetValue(key, result);
[email protected]39565dd2011-11-14 12:09:2790}
91
Matt Menke38ac93c2022-08-17 03:12:5992base::Value::Dict OverlayUserPrefStore::GetValues() const {
Ramin Halavatif623bafe92018-07-17 12:12:5893 auto values = ephemeral_user_pref_store_->GetValues();
94 auto persistent_values = persistent_user_pref_store_->GetValues();
95
96 // Output |values| are read from |ephemeral_user_pref_store_| (in-memory
97 // store). Then the values of preferences in |persistent_names_set_| are
98 // overwritten by the content of |persistent_user_pref_store_| (the persistent
99 // store).
100 for (const auto& key : persistent_names_set_) {
Arthur Sonzognic571efb2024-01-26 20:26:18101 std::optional<base::Value> out_value =
Matt Menke38ac93c2022-08-17 03:12:59102 persistent_values.ExtractByDottedPath(key);
Song Fangzhen61767882021-07-16 04:59:40103 if (out_value.has_value()) {
Matt Menke38ac93c2022-08-17 03:12:59104 values.SetByDottedPath(key, std::move(*out_value));
tibelle23659b42017-02-23 01:44:13105 }
106 }
107 return values;
108}
109
Jan Keitel331cd1692024-06-28 14:30:53110bool OverlayUserPrefStore::GetMutableValue(std::string_view key,
[email protected]a43a667b2013-06-14 17:56:08111 base::Value** result) {
Ramin Halavatif623bafe92018-07-17 12:12:58112 if (ShallBeStoredInPersistent(key))
113 return persistent_user_pref_store_->GetMutableValue(key, result);
[email protected]39565dd2011-11-14 12:09:27114
Ramin Halavatif623bafe92018-07-17 12:12:58115 if (ephemeral_user_pref_store_->GetMutableValue(key, result))
[email protected]892f1d62012-11-08 18:24:34116 return true;
[email protected]39565dd2011-11-14 12:09:27117
Ramin Halavatif623bafe92018-07-17 12:12:58118 // Try to create copy of persistent if the ephemeral does not contain a value.
119 base::Value* persistent_value = nullptr;
120 if (!persistent_user_pref_store_->GetMutableValue(key, &persistent_value))
[email protected]892f1d62012-11-08 18:24:34121 return false;
[email protected]39565dd2011-11-14 12:09:27122
Ramin Halavatif623bafe92018-07-17 12:12:58123 ephemeral_user_pref_store_->SetValue(
Roland Bocke01119d2022-09-29 01:21:41124 key, persistent_value->Clone(),
Ramin Halavatif623bafe92018-07-17 12:12:58125 WriteablePrefStore::DEFAULT_PREF_WRITE_FLAGS);
Vladislav Kuzkokov8ee75fbc2019-01-14 14:14:04126 ephemeral_user_pref_store_->GetMutableValue(key, result);
[email protected]892f1d62012-11-08 18:24:34127 return true;
[email protected]39565dd2011-11-14 12:09:27128}
129
Jan Keitel331cd1692024-06-28 14:30:53130void OverlayUserPrefStore::SetValue(std::string_view key,
Roland Bocke01119d2022-09-29 01:21:41131 base::Value value,
avi9ef8bb02015-12-24 05:29:36132 uint32_t flags) {
Ramin Halavatif623bafe92018-07-17 12:12:58133 if (ShallBeStoredInPersistent(key)) {
134 persistent_user_pref_store_->SetValue(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27135 return;
136 }
137
Alison Galeb8be9522024-04-16 00:00:31138 // TODO(crbug.com/40584094): If we always store in in-memory storage
Ramin Halavatif623bafe92018-07-17 12:12:58139 // and conditionally also stored in persistent one, we wouldn't have to do a
140 // complex merge in GetValues().
Ramin Halavatif623bafe92018-07-17 12:12:58141 ephemeral_user_pref_store_->SetValue(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27142}
143
Jan Keitel331cd1692024-06-28 14:30:53144void OverlayUserPrefStore::SetValueSilently(std::string_view key,
Roland Bocke01119d2022-09-29 01:21:41145 base::Value value,
avi9ef8bb02015-12-24 05:29:36146 uint32_t flags) {
Ramin Halavatif623bafe92018-07-17 12:12:58147 if (ShallBeStoredInPersistent(key)) {
148 persistent_user_pref_store_->SetValueSilently(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27149 return;
150 }
151
Ramin Halavatif623bafe92018-07-17 12:12:58152 ephemeral_user_pref_store_->SetValueSilently(key, std::move(value), flags);
[email protected]39565dd2011-11-14 12:09:27153}
154
Jan Keitel331cd1692024-06-28 14:30:53155void OverlayUserPrefStore::RemoveValue(std::string_view key, uint32_t flags) {
Ramin Halavatif623bafe92018-07-17 12:12:58156 if (ShallBeStoredInPersistent(key)) {
157 persistent_user_pref_store_->RemoveValue(key, flags);
[email protected]39565dd2011-11-14 12:09:27158 return;
159 }
160
Ramin Halavatif623bafe92018-07-17 12:12:58161 ephemeral_user_pref_store_->RemoveValue(key, flags);
[email protected]39565dd2011-11-14 12:09:27162}
163
Anatoliy Potapchuk5d9d8de2020-04-21 02:09:26164void OverlayUserPrefStore::RemoveValuesByPrefixSilently(
Jan Keitel331cd1692024-06-28 14:30:53165 std::string_view prefix) {
Anatoliy Potapchuk5d9d8de2020-04-21 02:09:26166 NOTIMPLEMENTED();
167}
168
[email protected]39565dd2011-11-14 12:09:27169bool OverlayUserPrefStore::ReadOnly() const {
170 return false;
171}
172
[email protected]59c10712012-03-13 02:10:34173PersistentPrefStore::PrefReadError OverlayUserPrefStore::GetReadError() const {
174 return PersistentPrefStore::PREF_READ_ERROR_NONE;
175}
176
[email protected]39565dd2011-11-14 12:09:27177PersistentPrefStore::PrefReadError OverlayUserPrefStore::ReadPrefs() {
178 // We do not read intentionally.
Ramin Halavatif623bafe92018-07-17 12:12:58179 OnInitializationCompleted(/* ephemeral */ false, true);
[email protected]39565dd2011-11-14 12:09:27180 return PersistentPrefStore::PREF_READ_ERROR_NONE;
181}
182
183void OverlayUserPrefStore::ReadPrefsAsync(
184 ReadErrorDelegate* error_delegate_raw) {
dcheng5f043bc2016-04-22 19:09:06185 std::unique_ptr<ReadErrorDelegate> error_delegate(error_delegate_raw);
[email protected]39565dd2011-11-14 12:09:27186 // We do not read intentionally.
Ramin Halavatif623bafe92018-07-17 12:12:58187 OnInitializationCompleted(/* ephemeral */ false, true);
[email protected]39565dd2011-11-14 12:09:27188}
189
Gabriel Charette788eaf62018-08-07 20:11:46190void OverlayUserPrefStore::CommitPendingWrite(
191 base::OnceClosure reply_callback,
192 base::OnceClosure synchronous_done_callback) {
193 persistent_user_pref_store_->CommitPendingWrite(
194 std::move(reply_callback), std::move(synchronous_done_callback));
[email protected]39565dd2011-11-14 12:09:27195 // We do not write our content intentionally.
196}
197
benwells26730592015-05-28 13:08:08198void OverlayUserPrefStore::SchedulePendingLossyWrites() {
Ramin Halavatif623bafe92018-07-17 12:12:58199 persistent_user_pref_store_->SchedulePendingLossyWrites();
benwells26730592015-05-28 13:08:08200}
201
Jan Keitel331cd1692024-06-28 14:30:53202void OverlayUserPrefStore::ReportValueChanged(std::string_view key,
avi9ef8bb02015-12-24 05:29:36203 uint32_t flags) {
ericwilligers42b92c12016-10-24 20:21:13204 for (PrefStore::Observer& observer : observers_)
205 observer.OnPrefValueChanged(key);
[email protected]39565dd2011-11-14 12:09:27206}
207
Jan Keitel6288ad6b2024-07-26 09:00:14208void OverlayUserPrefStore::RegisterPersistentPref(std::string_view key) {
Johan Tibell6566c8ac2017-05-11 03:22:17209 DCHECK(!key.empty()) << "Key is empty";
Ramin Halavatif623bafe92018-07-17 12:12:58210 DCHECK(persistent_names_set_.find(key) == persistent_names_set_.end())
211 << "Key already registered: " << key;
Jan Keitel6288ad6b2024-07-26 09:00:14212 persistent_names_set_.insert(std::string(key));
[email protected]39565dd2011-11-14 12:09:27213}
214
proberge45e347282017-08-16 21:24:05215void OverlayUserPrefStore::OnStoreDeletionFromDisk() {
Ramin Halavatif623bafe92018-07-17 12:12:58216 persistent_user_pref_store_->OnStoreDeletionFromDisk();
proberge45e347282017-08-16 21:24:05217}
218
[email protected]2dea5c02012-04-25 07:01:07219OverlayUserPrefStore::~OverlayUserPrefStore() {
Ramin Halavatif623bafe92018-07-17 12:12:58220 ephemeral_user_pref_store_->RemoveObserver(
221 ephemeral_pref_store_observer_.get());
222 persistent_user_pref_store_->RemoveObserver(
223 persistent_pref_store_observer_.get());
Johan Tibell0595f762017-05-25 23:54:50224}
225
Ramin Halavatif623bafe92018-07-17 12:12:58226void OverlayUserPrefStore::OnPrefValueChanged(bool ephemeral,
Jan Keitel07b772b2024-06-28 14:34:30227 std::string_view key) {
Ramin Halavatif623bafe92018-07-17 12:12:58228 if (ephemeral) {
Johan Tibell0595f762017-05-25 23:54:50229 ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
230 } else {
Ramin Halavatif623bafe92018-07-17 12:12:58231 if (!ephemeral_user_pref_store_->GetValue(key, nullptr))
Johan Tibell0595f762017-05-25 23:54:50232 ReportValueChanged(key, DEFAULT_PREF_WRITE_FLAGS);
233 }
234}
235
Ramin Halavatif623bafe92018-07-17 12:12:58236void OverlayUserPrefStore::OnInitializationCompleted(bool ephemeral,
Johan Tibell0595f762017-05-25 23:54:50237 bool succeeded) {
238 if (!IsInitializationComplete())
239 return;
240 for (PrefStore::Observer& observer : observers_)
241 observer.OnInitializationCompleted(succeeded);
[email protected]39565dd2011-11-14 12:09:27242}
243
Ramin Halavatif623bafe92018-07-17 12:12:58244bool OverlayUserPrefStore::ShallBeStoredInPersistent(
Helmut Januschka3ae90002024-05-02 18:42:28245 std::string_view key) const {
Ramin Halavatif623bafe92018-07-17 12:12:58246 return persistent_names_set_.find(key) != persistent_names_set_.end();
[email protected]39565dd2011-11-14 12:09:27247}
Ankush Singha77ee8392024-05-15 08:20:41248
249bool OverlayUserPrefStore::HasReadErrorDelegate() const {
250 return persistent_user_pref_store_->HasReadErrorDelegate();
251}