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() { |