OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 } | |
OLD | NEW |