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

Side by Side Diff: base/prefs/json_pref_store.cc

Issue 257003007: Introduce a new framework for back-and-forth tracked/protected preferences migration. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/prefs/json_pref_store.h" 5 #include "base/prefs/json_pref_store.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/callback.h" 10 #include "base/callback.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 value_.reset(DoReading(path, &error_, &no_dir_)); 52 value_.reset(DoReading(path, &error_, &no_dir_));
53 53
54 origin_loop_proxy_->PostTask( 54 origin_loop_proxy_->PostTask(
55 FROM_HERE, 55 FROM_HERE,
56 base::Bind(&FileThreadDeserializer::ReportOnOriginThread, this)); 56 base::Bind(&FileThreadDeserializer::ReportOnOriginThread, this));
57 } 57 }
58 58
59 // Reports deserialization result on the origin thread. 59 // Reports deserialization result on the origin thread.
60 void ReportOnOriginThread() { 60 void ReportOnOriginThread() {
61 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 61 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
62 delegate_->OnFileRead(value_.release(), error_, no_dir_); 62 delegate_->OnFileRead(value_.Pass(), error_, no_dir_);
63 } 63 }
64 64
65 static base::Value* DoReading(const base::FilePath& path, 65 static base::Value* DoReading(const base::FilePath& path,
66 PersistentPrefStore::PrefReadError* error, 66 PersistentPrefStore::PrefReadError* error,
67 bool* no_dir) { 67 bool* no_dir) {
68 int error_code; 68 int error_code;
69 std::string error_msg; 69 std::string error_msg;
70 JSONFileValueSerializer serializer(path); 70 JSONFileValueSerializer serializer(path);
71 base::Value* value = serializer.Deserialize(&error_code, &error_msg); 71 base::Value* value = serializer.Deserialize(&error_code, &error_msg);
72 HandleErrors(value, path, error_code, error_msg, error); 72 HandleErrors(value, path, error_code, error_msg, error);
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
227 bool JsonPrefStore::ReadOnly() const { 227 bool JsonPrefStore::ReadOnly() const {
228 return read_only_; 228 return read_only_;
229 } 229 }
230 230
231 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const { 231 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const {
232 return read_error_; 232 return read_error_;
233 } 233 }
234 234
235 PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() { 235 PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() {
236 if (path_.empty()) { 236 if (path_.empty()) {
237 OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); 237 OnFileRead(
238 scoped_ptr<base::Value>(), PREF_READ_ERROR_FILE_NOT_SPECIFIED, false);
238 return PREF_READ_ERROR_FILE_NOT_SPECIFIED; 239 return PREF_READ_ERROR_FILE_NOT_SPECIFIED;
239 } 240 }
240 241
241 PrefReadError error; 242 PrefReadError error;
242 bool no_dir; 243 bool no_dir;
243 base::Value* value = 244 scoped_ptr<base::Value> value(
244 FileThreadDeserializer::DoReading(path_, &error, &no_dir); 245 FileThreadDeserializer::DoReading(path_, &error, &no_dir));
245 OnFileRead(value, error, no_dir); 246 OnFileRead(value.Pass(), error, no_dir);
246 return error; 247 return error;
247 } 248 }
248 249
249 void JsonPrefStore::ReadPrefsAsync(ReadErrorDelegate *error_delegate) { 250 void JsonPrefStore::ReadPrefsAsync(ReadErrorDelegate *error_delegate) {
250 initialized_ = false; 251 initialized_ = false;
251 error_delegate_.reset(error_delegate); 252 error_delegate_.reset(error_delegate);
252 if (path_.empty()) { 253 if (path_.empty()) {
253 OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); 254 OnFileRead(
255 scoped_ptr<base::Value>(), PREF_READ_ERROR_FILE_NOT_SPECIFIED, false);
254 return; 256 return;
255 } 257 }
256 258
257 // Start async reading of the preferences file. It will delete itself 259 // Start async reading of the preferences file. It will delete itself
258 // in the end. 260 // in the end.
259 scoped_refptr<FileThreadDeserializer> deserializer( 261 scoped_refptr<FileThreadDeserializer> deserializer(
260 new FileThreadDeserializer(this, sequenced_task_runner_.get())); 262 new FileThreadDeserializer(this, sequenced_task_runner_.get()));
261 deserializer->Start(path_); 263 deserializer->Start(path_);
262 } 264 }
263 265
264 void JsonPrefStore::CommitPendingWrite() { 266 void JsonPrefStore::CommitPendingWrite() {
265 if (writer_.HasPendingWrite() && !read_only_) 267 if (writer_.HasPendingWrite() && !read_only_)
266 writer_.DoScheduledWrite(); 268 writer_.DoScheduledWrite();
267 } 269 }
268 270
269 void JsonPrefStore::ReportValueChanged(const std::string& key) { 271 void JsonPrefStore::ReportValueChanged(const std::string& key) {
270 if (pref_filter_) 272 if (pref_filter_)
271 pref_filter_->FilterUpdate(key); 273 pref_filter_->FilterUpdate(key);
272 274
273 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); 275 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
274 276
275 if (!read_only_) 277 if (!read_only_)
276 writer_.ScheduleWrite(this); 278 writer_.ScheduleWrite(this);
277 } 279 }
278 280
279 void JsonPrefStore::OnFileRead(base::Value* value_owned, 281 void JsonPrefStore::InterceptNextFileRead(
282 const OnFileReadInterceptor& on_file_read_interceptor) {
283 on_file_read_interceptor_.reset(
284 new OnFileReadInterceptor(on_file_read_interceptor));
285 }
286
287 void JsonPrefStore::OnFileRead(scoped_ptr<base::Value> value,
280 PersistentPrefStore::PrefReadError error, 288 PersistentPrefStore::PrefReadError error,
281 bool no_dir) { 289 bool no_dir) {
282 scoped_ptr<base::Value> value(value_owned); 290 scoped_ptr<base::DictionaryValue> unprocessed_prefs(
291 new base::DictionaryValue);
292
283 read_error_ = error; 293 read_error_ = error;
284 294
285 if (no_dir) { 295 bool initialization_successful = !no_dir;
286 FOR_EACH_OBSERVER(PrefStore::Observer, 296
287 observers_, 297 if (initialization_successful) {
288 OnInitializationCompleted(false)); 298 switch (error) {
289 return; 299 case PREF_READ_ERROR_ACCESS_DENIED:
300 case PREF_READ_ERROR_FILE_OTHER:
301 case PREF_READ_ERROR_FILE_LOCKED:
302 case PREF_READ_ERROR_JSON_TYPE:
303 case PREF_READ_ERROR_FILE_NOT_SPECIFIED:
304 read_only_ = true;
305 break;
306 case PREF_READ_ERROR_NONE:
307 DCHECK(value.get());
308 unprocessed_prefs.reset(
309 static_cast<base::DictionaryValue*>(value.release()));
310 break;
311 case PREF_READ_ERROR_NO_FILE:
312 // If the file just doesn't exist, maybe this is first run. In any case
313 // there's no harm in writing out default prefs in this case.
314 break;
315 case PREF_READ_ERROR_JSON_PARSE:
316 case PREF_READ_ERROR_JSON_REPEAT:
317 break;
318 default:
Bernhard Bauer 2014/04/29 15:13:04 Could we get rid of the default statement?
gab 2014/04/29 15:46:44 Yes, if we provide a case for PREF_READ_ERROR_MAX_
319 NOTREACHED() << "Unknown error: " << error;
320 }
290 } 321 }
291 322
292 initialized_ = true; 323 if (on_file_read_interceptor_) {
293 324 const FinalizePrefsReadCallback finalize_file_read(
294 switch (error) { 325 base::Bind(&JsonPrefStore::FinalizeFileRead, this,
295 case PREF_READ_ERROR_ACCESS_DENIED: 326 initialization_successful));
296 case PREF_READ_ERROR_FILE_OTHER: 327 on_file_read_interceptor_->Run(unprocessed_prefs.Pass(),
297 case PREF_READ_ERROR_FILE_LOCKED: 328 read_only_,
298 case PREF_READ_ERROR_JSON_TYPE: 329 finalize_file_read);
299 case PREF_READ_ERROR_FILE_NOT_SPECIFIED: 330 on_file_read_interceptor_.reset();
300 read_only_ = true; 331 } else {
301 break; 332 FinalizeFileRead(initialization_successful, unprocessed_prefs.Pass(),
302 case PREF_READ_ERROR_NONE: 333 false);
303 DCHECK(value.get());
304 prefs_.reset(static_cast<base::DictionaryValue*>(value.release()));
305 break;
306 case PREF_READ_ERROR_NO_FILE:
307 // If the file just doesn't exist, maybe this is first run. In any case
308 // there's no harm in writing out default prefs in this case.
309 break;
310 case PREF_READ_ERROR_JSON_PARSE:
311 case PREF_READ_ERROR_JSON_REPEAT:
312 break;
313 default:
314 NOTREACHED() << "Unknown error: " << error;
315 } 334 }
316
317 if (pref_filter_ && pref_filter_->FilterOnLoad(prefs_.get()))
318 writer_.ScheduleWrite(this);
319
320 if (error_delegate_.get() && error != PREF_READ_ERROR_NONE)
321 error_delegate_->OnError(error);
322
323 FOR_EACH_OBSERVER(PrefStore::Observer,
324 observers_,
325 OnInitializationCompleted(true));
326 } 335 }
327 336
328 JsonPrefStore::~JsonPrefStore() { 337 JsonPrefStore::~JsonPrefStore() {
329 CommitPendingWrite(); 338 CommitPendingWrite();
330 } 339 }
331 340
332 bool JsonPrefStore::SerializeData(std::string* output) { 341 bool JsonPrefStore::SerializeData(std::string* output) {
333 if (pref_filter_) 342 if (pref_filter_)
334 pref_filter_->FilterSerializeData(prefs_.get()); 343 pref_filter_->FilterSerializeData(prefs_.get());
335 344
336 JSONStringValueSerializer serializer(output); 345 JSONStringValueSerializer serializer(output);
337 serializer.set_pretty_print(true); 346 serializer.set_pretty_print(true);
338 return serializer.Serialize(*prefs_); 347 return serializer.Serialize(*prefs_);
339 } 348 }
349
350 void JsonPrefStore::FinalizeFileRead(bool initialization_successful,
351 scoped_ptr<base::DictionaryValue> prefs,
352 bool schedule_write) {
353 if (!initialization_successful) {
354 FOR_EACH_OBSERVER(PrefStore::Observer,
355 observers_,
356 OnInitializationCompleted(false));
357 return;
358 }
359
360 prefs_ = prefs.Pass();
361
362 initialized_ = true;
363
364 const bool had_filter_modification =
Bernhard Bauer 2014/04/29 15:13:04 Nit: we don't usually mark local variables as cons
gab 2014/04/29 15:46:44 Sure, I like putting const as much as possible whe
365 pref_filter_ && pref_filter_->FilterOnLoad(prefs_.get());
366
367 if ((schedule_write || had_filter_modification) && !read_only_)
368 writer_.ScheduleWrite(this);
369
370 if (error_delegate_.get() && read_error_ != PREF_READ_ERROR_NONE)
Bernhard Bauer 2014/04/29 15:13:04 You could probably leave out the .get().
gab 2014/04/29 15:46:44 Done.
371 error_delegate_->OnError(read_error_);
372
373 FOR_EACH_OBSERVER(PrefStore::Observer,
374 observers_,
375 OnInitializationCompleted(true));
376 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698