Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(335)

Side by Side Diff: services/preferences/public/cpp/scoped_pref_update.cc

Issue 2812863002: Pref service: Add a ScopedDictionaryPrefUpdate to track value changes. (Closed)
Patch Set: rebase Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
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 "services/preferences/public/cpp/scoped_pref_update.h"
6
7 #include <algorithm>
8 #include <utility>
9
10 #include "base/memory/ptr_util.h"
11 #include "base/strings/string_split.h"
12 #include "components/prefs/pref_service.h"
13
14 namespace prefs {
15
16 ScopedDictionaryPrefUpdate::ScopedDictionaryPrefUpdate(PrefService* service,
17 base::StringPiece path)
18 : service_(service), path_(path.as_string()) {
19 base::DictionaryValue* value = static_cast<base::DictionaryValue*>(
20 service_->GetMutableUserPref(path_, base::Value::Type::DICTIONARY));
21 value_ = Insert(base::WrapUnique(
22 new DictionaryValueUpdate(this, value, std::vector<std::string>())));
23 }
24
25 ScopedDictionaryPrefUpdate::~ScopedDictionaryPrefUpdate() {
26 if (value_)
27 Notify();
28 }
29
30 DictionaryValueUpdate* ScopedDictionaryPrefUpdate::Get() {
31 return value_;
32 }
33
34 DictionaryValueUpdate* ScopedDictionaryPrefUpdate::operator->() {
35 return Get();
36 }
37
38 void ScopedDictionaryPrefUpdate::Notify() {
39 DCHECK(value_);
40 if (!updated_paths_.empty())
41 service_->ReportUserPrefChanged(path_, std::move(updated_paths_));
42 value_ = nullptr;
43 updates_.clear();
44 }
45
46 void ScopedDictionaryPrefUpdate::RecordPath(
47 const std::vector<std::string>& path) {
48 updated_paths_.insert(std::move(path));
49 }
50
51 DictionaryValueUpdate* ScopedDictionaryPrefUpdate::Insert(
52 std::unique_ptr<DictionaryValueUpdate> dictionary_value_update) {
53 updates_.push_back(std::move(dictionary_value_update));
54 return updates_.back().get();
55 }
56
57 DictionaryValueUpdate::DictionaryValueUpdate(ScopedDictionaryPrefUpdate* update,
58 base::DictionaryValue* value,
59 std::vector<std::string> path)
60 : update_(update), value_(value), path_(std::move(path)) {}
61
62 DictionaryValueUpdate::~DictionaryValueUpdate() = default;
63
64 bool DictionaryValueUpdate::HasKey(base::StringPiece key) const {
65 return value_->HasKey(key);
66 }
67
68 size_t DictionaryValueUpdate::size() const {
69 return value_->size();
70 }
71
72 bool DictionaryValueUpdate::empty() const {
73 return value_->empty();
74 }
75
76 void DictionaryValueUpdate::Clear() {
77 if (empty())
78 return;
79
80 RecordSplitPath(std::vector<base::StringPiece>());
81 value_->Clear();
82 }
83
84 void DictionaryValueUpdate::Set(base::StringPiece path,
85 std::unique_ptr<base::Value> in_value) {
86 const base::Value* old_value = nullptr;
87 if (value_->Get(path, &old_value) && *old_value == *in_value)
88 return;
89
90 RecordPath(path);
91 value_->Set(path, std::move(in_value));
92 }
93
94 void DictionaryValueUpdate::SetBoolean(base::StringPiece path, bool in_value) {
95 Set(path, base::MakeUnique<base::Value>(in_value));
96 }
97
98 void DictionaryValueUpdate::SetInteger(base::StringPiece path, int in_value) {
99 Set(path, base::MakeUnique<base::Value>(in_value));
100 }
101
102 void DictionaryValueUpdate::SetDouble(base::StringPiece path, double in_value) {
103 Set(path, base::MakeUnique<base::Value>(in_value));
104 }
105
106 void DictionaryValueUpdate::SetString(base::StringPiece path,
107 base::StringPiece in_value) {
108 Set(path, base::MakeUnique<base::Value>(in_value));
109 }
110
111 void DictionaryValueUpdate::SetString(base::StringPiece path,
112 const base::string16& in_value) {
113 Set(path, base::MakeUnique<base::Value>(in_value));
114 }
115
116 DictionaryValueUpdate* DictionaryValueUpdate::SetDictionary(
117 base::StringPiece path,
118 std::unique_ptr<base::DictionaryValue> in_value) {
119 RecordPath(path);
120 base::DictionaryValue* dictionary_value = in_value.get();
121 value_->Set(path, std::move(in_value));
122
123 return update_->Insert(base::WrapUnique(new DictionaryValueUpdate(
124 update_, dictionary_value, ConcatPath(path_, path))));
125 }
126
127 void DictionaryValueUpdate::SetWithoutPathExpansion(
128 base::StringPiece key,
129 std::unique_ptr<base::Value> in_value) {
130 const base::Value* old_value = nullptr;
131 if (value_->GetWithoutPathExpansion(key, &old_value) &&
132 *old_value == *in_value) {
133 return;
134 }
135 RecordKey(key);
136 value_->SetWithoutPathExpansion(key, std::move(in_value));
137 }
138
139 void DictionaryValueUpdate::SetBooleanWithoutPathExpansion(
140 base::StringPiece path,
141 bool in_value) {
142 SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
143 }
144
145 void DictionaryValueUpdate::SetIntegerWithoutPathExpansion(
146 base::StringPiece path,
147 int in_value) {
148 SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
149 }
150
151 void DictionaryValueUpdate::SetDoubleWithoutPathExpansion(
152 base::StringPiece path,
153 double in_value) {
154 SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
155 }
156
157 void DictionaryValueUpdate::SetStringWithoutPathExpansion(
158 base::StringPiece path,
159 base::StringPiece in_value) {
160 SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
161 }
162
163 void DictionaryValueUpdate::SetStringWithoutPathExpansion(
164 base::StringPiece path,
165 const base::string16& in_value) {
166 SetWithoutPathExpansion(path, base::MakeUnique<base::Value>(in_value));
167 }
168
169 DictionaryValueUpdate* DictionaryValueUpdate::SetDictionaryWithoutPathExpansion(
170 base::StringPiece path,
171 std::unique_ptr<base::DictionaryValue> in_value) {
172 RecordKey(path);
173 base::DictionaryValue* dictionary_value = in_value.get();
174 value_->SetWithoutPathExpansion(path, std::move(in_value));
175
176 std::vector<std::string> full_path = path_;
177 full_path.push_back(path.as_string());
178 return update_->Insert(base::WrapUnique(new DictionaryValueUpdate(
179 update_, dictionary_value, std::move(full_path))));
180 }
181
182 bool DictionaryValueUpdate::GetBoolean(base::StringPiece path,
183 bool* out_value) const {
184 return value_->GetBoolean(path, out_value);
185 }
186
187 bool DictionaryValueUpdate::GetInteger(base::StringPiece path,
188 int* out_value) const {
189 return value_->GetInteger(path, out_value);
190 }
191
192 bool DictionaryValueUpdate::GetDouble(base::StringPiece path,
193 double* out_value) const {
194 return value_->GetDouble(path, out_value);
195 }
196
197 bool DictionaryValueUpdate::GetString(base::StringPiece path,
198 std::string* out_value) const {
199 return value_->GetString(path, out_value);
200 }
201
202 bool DictionaryValueUpdate::GetString(base::StringPiece path,
203 base::string16* out_value) const {
204 return value_->GetString(path, out_value);
205 }
206
207 bool DictionaryValueUpdate::GetBinary(base::StringPiece path,
208 const base::Value** out_value) const {
209 return AsConstDictionary()->GetBinary(path, out_value);
210 }
211
212 bool DictionaryValueUpdate::GetDictionary(
213 base::StringPiece path,
214 const base::DictionaryValue** out_value) const {
215 return AsConstDictionary()->GetDictionary(path, out_value);
216 }
217
218 bool DictionaryValueUpdate::GetDictionary(base::StringPiece path,
219 DictionaryValueUpdate** out_value) {
220 base::DictionaryValue* dictionary_value = nullptr;
221 if (!value_->GetDictionary(path, &dictionary_value))
222 return false;
223
224 *out_value = update_->Insert(base::WrapUnique(new DictionaryValueUpdate(
225 update_, dictionary_value, ConcatPath(path_, path))));
226 return true;
227 }
228
229 bool DictionaryValueUpdate::GetList(base::StringPiece path,
230 const base::ListValue** out_value) const {
231 return AsConstDictionary()->GetList(path, out_value);
232 }
233
234 bool DictionaryValueUpdate::GetList(base::StringPiece path,
235 base::ListValue** out_value) {
236 RecordPath(path);
237 return value_->GetList(path, out_value);
238 }
239
240 bool DictionaryValueUpdate::GetBooleanWithoutPathExpansion(
241 base::StringPiece key,
242 bool* out_value) const {
243 return value_->GetBooleanWithoutPathExpansion(key, out_value);
244 }
245
246 bool DictionaryValueUpdate::GetIntegerWithoutPathExpansion(
247 base::StringPiece key,
248 int* out_value) const {
249 return value_->GetIntegerWithoutPathExpansion(key, out_value);
250 }
251
252 bool DictionaryValueUpdate::GetDoubleWithoutPathExpansion(
253 base::StringPiece key,
254 double* out_value) const {
255 return value_->GetDoubleWithoutPathExpansion(key, out_value);
256 }
257
258 bool DictionaryValueUpdate::GetStringWithoutPathExpansion(
259 base::StringPiece key,
260 std::string* out_value) const {
261 return value_->GetStringWithoutPathExpansion(key, out_value);
262 }
263
264 bool DictionaryValueUpdate::GetStringWithoutPathExpansion(
265 base::StringPiece key,
266 base::string16* out_value) const {
267 return value_->GetStringWithoutPathExpansion(key, out_value);
268 }
269
270 bool DictionaryValueUpdate::GetDictionaryWithoutPathExpansion(
271 base::StringPiece key,
272 const base::DictionaryValue** out_value) const {
273 return value_->GetDictionaryWithoutPathExpansion(key, out_value);
274 }
275
276 bool DictionaryValueUpdate::GetDictionaryWithoutPathExpansion(
277 base::StringPiece key,
278 DictionaryValueUpdate** out_value) {
279 base::DictionaryValue* dictionary_value = nullptr;
280 if (!value_->GetDictionary(key, &dictionary_value))
281 return false;
282
283 std::vector<std::string> full_path = path_;
284 full_path.push_back(key.as_string());
285 *out_value = update_->Insert(base::WrapUnique(new DictionaryValueUpdate(
286 update_, dictionary_value, std::move(full_path))));
287 return true;
288 }
289
290 bool DictionaryValueUpdate::GetListWithoutPathExpansion(
291 base::StringPiece key,
292 const base::ListValue** out_value) const {
293 return value_->GetListWithoutPathExpansion(key, out_value);
294 }
295
296 bool DictionaryValueUpdate::GetListWithoutPathExpansion(
297 base::StringPiece key,
298 base::ListValue** out_value) {
299 RecordKey(key);
300 return value_->GetListWithoutPathExpansion(key, out_value);
301 }
302
303 bool DictionaryValueUpdate::Remove(base::StringPiece path,
304 std::unique_ptr<base::Value>* out_value) {
305 if (!value_->Remove(path, out_value))
306 return false;
307
308 RecordPath(path);
309 return true;
310 }
311
312 bool DictionaryValueUpdate::RemoveWithoutPathExpansion(
313 base::StringPiece key,
314 std::unique_ptr<base::Value>* out_value) {
315 if (!value_->RemoveWithoutPathExpansion(key, out_value))
316 return false;
317
318 RecordKey(key);
319 return true;
320 }
321
322 bool DictionaryValueUpdate::RemovePath(
323 base::StringPiece path,
324 std::unique_ptr<base::Value>* out_value) {
325 if (!value_->RemovePath(path, out_value))
326 return false;
327
328 std::vector<base::StringPiece> split_path = SplitPath(path);
329 base::DictionaryValue* dict = value_;
330 for (size_t i = 0; i < split_path.size() - 1; ++i) {
331 if (!dict->GetDictionary(split_path[i], &dict)) {
332 split_path.resize(i + 1);
333 RecordSplitPath(split_path);
334 return true;
335 }
336 }
337 RecordPath(path);
338 return true;
339 }
340
341 base::DictionaryValue* DictionaryValueUpdate::AsDictionary() {
342 RecordSplitPath(std::vector<base::StringPiece>());
343 return value_;
344 }
345
346 const base::DictionaryValue* DictionaryValueUpdate::AsConstDictionary() const {
347 return value_;
348 }
349
350 void DictionaryValueUpdate::RecordKey(base::StringPiece key) {
351 RecordSplitPath({key});
352 }
353
354 void DictionaryValueUpdate::RecordPath(base::StringPiece path) {
355 RecordSplitPath(SplitPath(path));
356 }
357
358 void DictionaryValueUpdate::RecordSplitPath(
359 const std::vector<base::StringPiece>& path) {
360 update_->RecordPath(ConcatPath(path_, path));
361 }
362
363 std::vector<base::StringPiece> DictionaryValueUpdate::SplitPath(
364 base::StringPiece path) {
365 return base::SplitStringPiece(path, ".", base::TRIM_WHITESPACE,
366 base::SPLIT_WANT_NONEMPTY);
367 }
368
369 std::vector<std::string> DictionaryValueUpdate::ConcatPath(
370 const std::vector<std::string>& base_path,
371 base::StringPiece path) {
372 return ConcatPath(base_path, SplitPath(path));
373 }
374
375 std::vector<std::string> DictionaryValueUpdate::ConcatPath(
376 const std::vector<std::string>& base_path,
377 const std::vector<base::StringPiece>& path) {
378 std::vector<std::string> full_path = base_path;
379 full_path.reserve(full_path.size() + path.size());
380 std::transform(path.begin(), path.end(), std::back_inserter(full_path),
381 [](base::StringPiece s) { return s.as_string(); });
382 return full_path;
383 }
384
385 } // namespace prefs
OLDNEW
« no previous file with comments | « services/preferences/public/cpp/scoped_pref_update.h ('k') | services/preferences/public/cpp/tests/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698