Chromium Code Reviews| Index: chrome/common/json_pref_store.cc |
| diff --git a/chrome/common/json_pref_store.cc b/chrome/common/json_pref_store.cc |
| index 038f6331b6a88289d459af13f0e21d07494f3c92..2fbc6d06b4208e3a08659176f71ee760e794f882 100644 |
| --- a/chrome/common/json_pref_store.cc |
| +++ b/chrome/common/json_pref_store.cc |
| @@ -10,8 +10,8 @@ |
| #include "base/callback.h" |
| #include "base/file_util.h" |
| #include "base/memory/ref_counted.h" |
| +#include "base/message_loop_proxy.h" |
| #include "base/values.h" |
| -#include "content/browser/browser_thread.h" |
| #include "content/common/json_value_serializer.h" |
| namespace { |
| @@ -19,49 +19,56 @@ namespace { |
| // Some extensions we'll tack on to copies of the Preferences files. |
| const FilePath::CharType* kBadExtension = FILE_PATH_LITERAL("bad"); |
| -// Differentiates file loading between UI and FILE threads. |
| +// Differentiates file loading between current (aka ui) thread and passed |
| +// (aka file) thread. |
| class FileThreadDeserializer |
| : public base::RefCountedThreadSafe<FileThreadDeserializer> { |
| public: |
| - explicit FileThreadDeserializer(JsonPrefStore* delegate) |
| - : delegate_(delegate) { |
| + explicit FileThreadDeserializer(JsonPrefStore* delegate, |
| + base::MessageLoopProxy* file_loop_proxy) |
| + : delegate_(delegate), |
| + file_loop_proxy_(file_loop_proxy), |
| + ui_loop_proxy_(base::MessageLoopProxy::CreateForCurrentThread()) { |
| } |
| void Start(const FilePath& path) { |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - BrowserThread::PostTask( |
| - BrowserThread::FILE, |
| + DCHECK(ui_loop_proxy_->BelongsToCurrentThread()); |
| + file_loop_proxy_->PostTask( |
| FROM_HERE, |
| NewRunnableMethod(this, |
| &FileThreadDeserializer::ReadFileAndReport, |
| path)); |
| } |
| - // Deserializes JSON on the FILE thread. |
| + // Deserializes JSON on the file thread. |
| void ReadFileAndReport(const FilePath& path) { |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| + DCHECK(file_loop_proxy_->BelongsToCurrentThread()); |
| - int error_code; |
| - std::string error_msg; |
| - JSONFileValueSerializer serializer(path); |
| - value_.reset(serializer.Deserialize(&error_code, &error_msg)); |
| - |
| - HandleErrors(value_.get(), path, error_code, error_msg, &error_); |
| - |
| - no_dir_ = !file_util::PathExists(path.DirName()); |
| + value_.reset(DoReading(path, &error_, &no_dir_)); |
| - BrowserThread::PostTask( |
| - BrowserThread::UI, |
| + ui_loop_proxy_->PostTask( |
| FROM_HERE, |
| NewRunnableMethod(this, &FileThreadDeserializer::ReportOnUIThread)); |
| } |
| - // Reports deserialization result on the UI thread. |
| + // Reports deserialization result on the ui thread. |
| void ReportOnUIThread() { |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| + DCHECK(ui_loop_proxy_->BelongsToCurrentThread()); |
| delegate_->OnFileRead(value_.release(), error_, no_dir_); |
| } |
| + static Value* DoReading(const FilePath& path, |
| + PersistentPrefStore::PrefReadError* error, |
| + bool* no_dir) { |
| + int error_code; |
| + std::string error_msg; |
| + JSONFileValueSerializer serializer(path); |
| + Value* value = serializer.Deserialize(&error_code, &error_msg); |
| + HandleErrors(value, path, error_code, error_msg, error); |
| + *no_dir = !file_util::PathExists(path.DirName()); |
| + return value; |
| + } |
| + |
| static void HandleErrors(const Value* value, |
| const FilePath& path, |
| int error_code, |
| @@ -75,6 +82,8 @@ class FileThreadDeserializer |
| PersistentPrefStore::PrefReadError error_; |
| scoped_ptr<Value> value_; |
| scoped_refptr<JsonPrefStore> delegate_; |
| + scoped_refptr<base::MessageLoopProxy> file_loop_proxy_; |
| + scoped_refptr<base::MessageLoopProxy> ui_loop_proxy_; |
|
Mattias Nissler (ping if slow)
2011/04/27 12:16:30
ui_loop_proxy is a misnomer IMHO, the service proc
altimofeev
2011/05/04 13:46:14
Done.
|
| }; |
| // static |
| @@ -128,9 +137,12 @@ void FileThreadDeserializer::HandleErrors( |
| JsonPrefStore::JsonPrefStore(const FilePath& filename, |
| base::MessageLoopProxy* file_message_loop_proxy) |
| : path_(filename), |
| + file_message_loop_proxy_(file_message_loop_proxy), |
| prefs_(new DictionaryValue()), |
| read_only_(false), |
| - writer_(filename, file_message_loop_proxy) { |
| + writer_(filename, file_message_loop_proxy), |
| + error_(PREF_READ_ERROR_NONE), |
| + is_fatal_(false) { |
| } |
| JsonPrefStore::~JsonPrefStore() { |
| @@ -193,12 +205,16 @@ bool JsonPrefStore::ReadOnly() const { |
| void JsonPrefStore::OnFileRead(Value* value_owned, |
| PersistentPrefStore::PrefReadError error, |
| bool no_dir) { |
| + error_ = error; |
| + is_fatal_ = no_dir; |
| + |
| scoped_ptr<Value> value(value_owned); |
| switch (error) { |
| case PREF_READ_ERROR_ACCESS_DENIED: |
| case PREF_READ_ERROR_FILE_OTHER: |
| case PREF_READ_ERROR_FILE_LOCKED: |
| case PREF_READ_ERROR_JSON_TYPE: |
| + case PREF_READ_ERROR_FILE_NOT_SPECIFIED: |
| read_only_ = true; |
| break; |
| case PREF_READ_ERROR_NONE: |
| @@ -216,54 +232,40 @@ void JsonPrefStore::OnFileRead(Value* value_owned, |
| NOTREACHED() << "Unknown error: " << error; |
| } |
| - if (delegate_) |
| - delegate_->OnPrefsRead(error, no_dir); |
| + FOR_EACH_OBSERVER(PrefStore::Observer, |
| + observers_, |
| + OnInitializationCompleted()); |
| } |
| -void JsonPrefStore::ReadPrefs(Delegate* delegate) { |
| - DCHECK(delegate); |
| - delegate_ = delegate; |
| - |
| +void JsonPrefStore::ReadPrefsAsync() { |
| if (path_.empty()) { |
| - read_only_ = true; |
| - delegate_->OnPrefsRead(PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); |
| + OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); |
| return; |
| } |
| - // This guarantees that class will not be deleted while JSON is readed. |
| - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| - |
| // Start async reading of the preferences file. It will delete itself |
| // in the end. |
| scoped_refptr<FileThreadDeserializer> deserializer( |
| - new FileThreadDeserializer(this)); |
| + new FileThreadDeserializer(this, file_message_loop_proxy_.get())); |
| deserializer->Start(path_); |
| } |
| PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() { |
| - delegate_ = NULL; |
| - |
| if (path_.empty()) { |
| - read_only_ = true; |
| - return PREF_READ_ERROR_FILE_NOT_SPECIFIED; |
| + OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); |
| + return error_; |
| } |
| - int error_code = 0; |
| - std::string error_msg; |
| - |
| - JSONFileValueSerializer serializer(path_); |
| - scoped_ptr<Value> value(serializer.Deserialize(&error_code, &error_msg)); |
| - |
| - PersistentPrefStore::PrefReadError error; |
| - FileThreadDeserializer::HandleErrors(value.get(), |
| - path_, |
| - error_code, |
| - error_msg, |
| - &error); |
| - |
| - OnFileRead(value.release(), error, false); |
| + Value* value = FileThreadDeserializer::DoReading(path_, |
| + &error_, |
| + &is_fatal_); |
| + OnFileRead(value, error_, is_fatal_); |
| + return error_; |
| +} |
| - return error; |
| +void JsonPrefStore::GetErrors(PrefReadError* error, bool* is_fatal) { |
| + *error = error_; |
| + *is_fatal = is_fatal_; |
| } |
| bool JsonPrefStore::WritePrefs() { |