OLD | NEW |
(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 |
OLD | NEW |