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

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: run cleanup directly if destination store wasn't altered (i.e. migration completed in previous run,… 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 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 JsonPrefStore::JsonPrefStore(const base::FilePath& filename, 154 JsonPrefStore::JsonPrefStore(const base::FilePath& filename,
155 base::SequencedTaskRunner* sequenced_task_runner, 155 base::SequencedTaskRunner* sequenced_task_runner,
156 scoped_ptr<PrefFilter> pref_filter) 156 scoped_ptr<PrefFilter> pref_filter)
157 : path_(filename), 157 : path_(filename),
158 sequenced_task_runner_(sequenced_task_runner), 158 sequenced_task_runner_(sequenced_task_runner),
159 prefs_(new base::DictionaryValue()), 159 prefs_(new base::DictionaryValue()),
160 read_only_(false), 160 read_only_(false),
161 writer_(filename, sequenced_task_runner), 161 writer_(filename, sequenced_task_runner),
162 pref_filter_(pref_filter.Pass()), 162 pref_filter_(pref_filter.Pass()),
163 initialized_(false), 163 initialized_(false),
164 read_error_(PREF_READ_ERROR_OTHER) {} 164 read_error_(PREF_READ_ERROR_OTHER),
165 weak_factory_(this) {}
165 166
166 bool JsonPrefStore::GetValue(const std::string& key, 167 bool JsonPrefStore::GetValue(const std::string& key,
167 const base::Value** result) const { 168 const base::Value** result) const {
168 base::Value* tmp = NULL; 169 base::Value* tmp = NULL;
169 if (!prefs_->Get(key, &tmp)) 170 if (!prefs_->Get(key, &tmp))
170 return false; 171 return false;
171 172
172 if (result) 173 if (result)
173 *result = tmp; 174 *result = tmp;
174 return true; 175 return true;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 if (!read_only_) 218 if (!read_only_)
218 writer_.ScheduleWrite(this); 219 writer_.ScheduleWrite(this);
219 } 220 }
220 } 221 }
221 222
222 void JsonPrefStore::RemoveValue(const std::string& key) { 223 void JsonPrefStore::RemoveValue(const std::string& key) {
223 if (prefs_->RemovePath(key, NULL)) 224 if (prefs_->RemovePath(key, NULL))
224 ReportValueChanged(key); 225 ReportValueChanged(key);
225 } 226 }
226 227
228 void JsonPrefStore::RemoveValueSilently(const std::string& key) {
229 prefs_->RemovePath(key, NULL);
230 if (!read_only_)
231 writer_.ScheduleWrite(this);
232 }
233
227 bool JsonPrefStore::ReadOnly() const { 234 bool JsonPrefStore::ReadOnly() const {
228 return read_only_; 235 return read_only_;
229 } 236 }
230 237
231 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const { 238 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const {
232 return read_error_; 239 return read_error_;
233 } 240 }
234 241
235 PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() { 242 PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() {
236 if (path_.empty()) { 243 if (path_.empty()) {
237 OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); 244 OnFileRead(
245 scoped_ptr<base::Value>(), PREF_READ_ERROR_FILE_NOT_SPECIFIED, false);
238 return PREF_READ_ERROR_FILE_NOT_SPECIFIED; 246 return PREF_READ_ERROR_FILE_NOT_SPECIFIED;
239 } 247 }
240 248
241 PrefReadError error; 249 PrefReadError error;
242 bool no_dir; 250 bool no_dir;
243 base::Value* value = 251 scoped_ptr<base::Value> value(
244 FileThreadDeserializer::DoReading(path_, &error, &no_dir); 252 FileThreadDeserializer::DoReading(path_, &error, &no_dir));
245 OnFileRead(value, error, no_dir); 253 OnFileRead(value.Pass(), error, no_dir);
246 return error; 254 return error;
247 } 255 }
248 256
249 void JsonPrefStore::ReadPrefsAsync(ReadErrorDelegate *error_delegate) { 257 void JsonPrefStore::ReadPrefsAsync(ReadErrorDelegate *error_delegate) {
250 initialized_ = false; 258 initialized_ = false;
251 error_delegate_.reset(error_delegate); 259 error_delegate_.reset(error_delegate);
252 if (path_.empty()) { 260 if (path_.empty()) {
253 OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); 261 OnFileRead(
262 scoped_ptr<base::Value>(), PREF_READ_ERROR_FILE_NOT_SPECIFIED, false);
254 return; 263 return;
255 } 264 }
256 265
257 // Start async reading of the preferences file. It will delete itself 266 // Start async reading of the preferences file. It will delete itself
258 // in the end. 267 // in the end.
259 scoped_refptr<FileThreadDeserializer> deserializer( 268 scoped_refptr<FileThreadDeserializer> deserializer(
260 new FileThreadDeserializer(this, sequenced_task_runner_.get())); 269 new FileThreadDeserializer(this, sequenced_task_runner_.get()));
261 deserializer->Start(path_); 270 deserializer->Start(path_);
262 } 271 }
263 272
264 void JsonPrefStore::CommitPendingWrite() { 273 void JsonPrefStore::CommitPendingWrite() {
265 if (writer_.HasPendingWrite() && !read_only_) 274 if (writer_.HasPendingWrite() && !read_only_)
266 writer_.DoScheduledWrite(); 275 writer_.DoScheduledWrite();
267 } 276 }
268 277
269 void JsonPrefStore::ReportValueChanged(const std::string& key) { 278 void JsonPrefStore::ReportValueChanged(const std::string& key) {
270 if (pref_filter_) 279 if (pref_filter_)
271 pref_filter_->FilterUpdate(key); 280 pref_filter_->FilterUpdate(key);
272 281
273 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); 282 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
274 283
275 if (!read_only_) 284 if (!read_only_)
276 writer_.ScheduleWrite(this); 285 writer_.ScheduleWrite(this);
277 } 286 }
278 287
279 void JsonPrefStore::OnFileRead(base::Value* value_owned, 288 void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback(
289 const base::Closure& on_next_successful_write) {
290 writer_.RegisterOnNextSuccessfulWriteCallback(on_next_successful_write);
291 }
292
293 void JsonPrefStore::InterceptNextFileRead(
294 const OnFileReadInterceptor& on_file_read_interceptor) {
295 DCHECK(on_file_read_interceptor_.is_null());
296 on_file_read_interceptor_ = on_file_read_interceptor;
297 }
298
299 void JsonPrefStore::OnFileRead(scoped_ptr<base::Value> value,
280 PersistentPrefStore::PrefReadError error, 300 PersistentPrefStore::PrefReadError error,
281 bool no_dir) { 301 bool no_dir) {
282 scoped_ptr<base::Value> value(value_owned); 302 scoped_ptr<base::DictionaryValue> unprocessed_prefs(
303 new base::DictionaryValue);
304
283 read_error_ = error; 305 read_error_ = error;
284 306
285 if (no_dir) { 307 bool initialization_successful = !no_dir;
286 FOR_EACH_OBSERVER(PrefStore::Observer, 308
287 observers_, 309 if (initialization_successful) {
288 OnInitializationCompleted(false)); 310 switch (error) {
289 return; 311 case PREF_READ_ERROR_ACCESS_DENIED:
312 case PREF_READ_ERROR_FILE_OTHER:
313 case PREF_READ_ERROR_FILE_LOCKED:
314 case PREF_READ_ERROR_JSON_TYPE:
315 case PREF_READ_ERROR_FILE_NOT_SPECIFIED:
316 read_only_ = true;
317 break;
318 case PREF_READ_ERROR_NONE:
319 DCHECK(value.get());
320 unprocessed_prefs.reset(
321 static_cast<base::DictionaryValue*>(value.release()));
322 break;
323 case PREF_READ_ERROR_NO_FILE:
324 // If the file just doesn't exist, maybe this is first run. In any case
325 // there's no harm in writing out default prefs in this case.
326 break;
327 case PREF_READ_ERROR_JSON_PARSE:
328 case PREF_READ_ERROR_JSON_REPEAT:
329 break;
330 case PREF_READ_ERROR_MAX_ENUM:
331 NOTREACHED();
332 break;
333 }
290 } 334 }
291 335
292 initialized_ = true; 336 if (on_file_read_interceptor_.is_null()) {
293 337 FinalizeFileRead(initialization_successful, unprocessed_prefs.Pass(),
294 switch (error) { 338 false);
295 case PREF_READ_ERROR_ACCESS_DENIED: 339 } else {
296 case PREF_READ_ERROR_FILE_OTHER: 340 const FinalizePrefsReadCallback finalize_file_read(
297 case PREF_READ_ERROR_FILE_LOCKED: 341 base::Bind(&JsonPrefStore::FinalizeFileRead, this,
298 case PREF_READ_ERROR_JSON_TYPE: 342 initialization_successful));
299 case PREF_READ_ERROR_FILE_NOT_SPECIFIED: 343 on_file_read_interceptor_.Run(unprocessed_prefs.Pass(),
300 read_only_ = true; 344 finalize_file_read);
301 break; 345 on_file_read_interceptor_.Reset();
302 case PREF_READ_ERROR_NONE:
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 } 346 }
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 } 347 }
327 348
328 JsonPrefStore::~JsonPrefStore() { 349 JsonPrefStore::~JsonPrefStore() {
329 CommitPendingWrite(); 350 CommitPendingWrite();
330 } 351 }
331 352
332 bool JsonPrefStore::SerializeData(std::string* output) { 353 bool JsonPrefStore::SerializeData(std::string* output) {
333 if (pref_filter_) 354 if (pref_filter_)
334 pref_filter_->FilterSerializeData(prefs_.get()); 355 pref_filter_->FilterSerializeData(prefs_.get());
335 356
336 JSONStringValueSerializer serializer(output); 357 JSONStringValueSerializer serializer(output);
337 serializer.set_pretty_print(true); 358 serializer.set_pretty_print(true);
338 return serializer.Serialize(*prefs_); 359 return serializer.Serialize(*prefs_);
339 } 360 }
361
362 base::WeakPtr<JsonPrefStore> JsonPrefStore::FinalizeFileRead(
363 bool initialization_successful,
364 scoped_ptr<base::DictionaryValue> prefs,
365 bool schedule_write) {
366 if (!initialization_successful) {
367 FOR_EACH_OBSERVER(PrefStore::Observer,
368 observers_,
369 OnInitializationCompleted(false));
370 return weak_factory_.GetWeakPtr();;
Bernhard Bauer 2014/04/30 09:31:05 Nit: one semicolon too much.
gab 2014/04/30 14:32:53 Done.
371 }
372
373 prefs_ = prefs.Pass();
374
375 initialized_ = true;
376
377 bool had_filter_modification =
378 pref_filter_ && pref_filter_->FilterOnLoad(prefs_.get());
379
380 if ((schedule_write || had_filter_modification) && !read_only_)
381 writer_.ScheduleWrite(this);
382
383 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE)
384 error_delegate_->OnError(read_error_);
385
386 FOR_EACH_OBSERVER(PrefStore::Observer,
387 observers_,
388 OnInitializationCompleted(true));
389
390 return weak_factory_.GetWeakPtr();
391 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698