summaryrefslogtreecommitdiffstats
path: root/chrome/common/pref_service.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/common/pref_service.cc')
-rw-r--r--chrome/common/pref_service.cc119
1 files changed, 27 insertions, 92 deletions
diff --git a/chrome/common/pref_service.cc b/chrome/common/pref_service.cc
index 12ed13e..74d8805 100644
--- a/chrome/common/pref_service.cc
+++ b/chrome/common/pref_service.cc
@@ -4,12 +4,9 @@
#include "chrome/common/pref_service.h"
-#include "base/compiler_specific.h"
-#include "base/file_util.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/string_util.h"
-#include "base/task.h"
#include "base/thread.h"
#include "chrome/common/json_value_serializer.h"
#include "chrome/common/l10n_util.h"
@@ -19,43 +16,6 @@
namespace {
-// The number of milliseconds we'll wait to do a write of chrome prefs to disk.
-// This lets us batch together write operations.
-static const int kCommitIntervalMs = 10000;
-
-// Replaces the given file's content with the given data. This allows the
-// preferences to be written to disk on a background thread.
-class SaveLaterTask : public Task {
- public:
- SaveLaterTask(const FilePath& file_name,
- const std::string& data)
- : file_name_(file_name),
- data_(data) {
- }
-
- void Run() {
- // Write the data to a temp file then rename to avoid data loss if we crash
- // while writing the file.
- FilePath tmp_file_name(file_name_.value() + FILE_PATH_LITERAL(".tmp"));
- int bytes_written = file_util::WriteFile(tmp_file_name, data_.c_str(),
- static_cast<int>(data_.length()));
- if (bytes_written != -1) {
- if (!file_util::Move(tmp_file_name, file_name_)) {
- // Rename failed. Try again on the off chance someone has locked either
- // file and hope we're successful the second time through.
- bool move_result = file_util::Move(tmp_file_name, file_name_);
- DCHECK(move_result);
- }
- }
- }
-
- private:
- FilePath file_name_;
- std::string data_;
-
- DISALLOW_COPY_AND_ASSIGN(SaveLaterTask);
-};
-
// A helper function for RegisterLocalized*Pref that creates a Value* based on
// the string value in the locale dll. Because we control the values in a
// locale dll, this should always return a Value of the appropriate type.
@@ -99,18 +59,12 @@ Value* CreateLocaleDefaultValue(Value::ValueType type, int message_id) {
} // namespace
-PrefService::PrefService()
+PrefService::PrefService(const FilePath& pref_filename,
+ const base::Thread* backend_thread)
: persistent_(new DictionaryValue),
transient_(new DictionaryValue),
- save_preferences_factory_(NULL) {
-}
-
-PrefService::PrefService(const FilePath& pref_filename)
- : persistent_(new DictionaryValue),
- transient_(new DictionaryValue),
- pref_filename_(pref_filename),
- ALLOW_THIS_IN_INITIALIZER_LIST(save_preferences_factory_(this)) {
- LoadPersistentPrefs(pref_filename_);
+ writer_(pref_filename, backend_thread) {
+ ReloadPersistentPrefs();
}
PrefService::~PrefService() {
@@ -132,11 +86,10 @@ PrefService::~PrefService() {
pref_observers_.clear();
}
-bool PrefService::LoadPersistentPrefs(const FilePath& file_path) {
- DCHECK(!file_path.empty());
+bool PrefService::ReloadPersistentPrefs() {
DCHECK(CalledOnValidThread());
- JSONFileValueSerializer serializer(file_path);
+ JSONFileValueSerializer serializer(writer_.path());
scoped_ptr<Value> root(serializer.Deserialize(NULL));
if (!root.get())
return false;
@@ -146,60 +99,34 @@ bool PrefService::LoadPersistentPrefs(const FilePath& file_path) {
return false;
persistent_.reset(static_cast<DictionaryValue*>(root.release()));
- return true;
-}
-
-void PrefService::ReloadPersistentPrefs() {
- DCHECK(CalledOnValidThread());
-
- JSONFileValueSerializer serializer(pref_filename_);
- scoped_ptr<Value> root(serializer.Deserialize(NULL));
- if (!root.get())
- return;
-
- // Preferences should always have a dictionary root.
- if (!root->IsType(Value::TYPE_DICTIONARY))
- return;
-
- persistent_.reset(static_cast<DictionaryValue*>(root.release()));
for (PreferenceSet::iterator it = prefs_.begin();
it != prefs_.end(); ++it) {
(*it)->root_pref_ = persistent_.get();
}
+
+ return true;
}
-bool PrefService::SavePersistentPrefs(base::Thread* thread) const {
- DCHECK(!pref_filename_.empty());
+bool PrefService::SavePersistentPrefs() {
DCHECK(CalledOnValidThread());
- // TODO(tc): Do we want to prune webkit preferences that match the default
- // value?
std::string data;
- JSONStringValueSerializer serializer(&data);
- serializer.set_pretty_print(true);
- if (!serializer.Serialize(*(persistent_.get())))
+ if (!SerializePrefData(&data))
return false;
- SaveLaterTask* task = new SaveLaterTask(pref_filename_, data);
- if (thread != NULL) {
- // We can use the background thread, it will take ownership of the task.
- thread->message_loop()->PostTask(FROM_HERE, task);
- } else {
- // In unit test mode, we have no background thread, just execute.
- task->Run();
- delete task;
- }
+ writer_.WriteNow(data);
return true;
}
-void PrefService::ScheduleSavePersistentPrefs(base::Thread* thread) {
- if (!save_preferences_factory_.empty())
- return;
+bool PrefService::ScheduleSavePersistentPrefs() {
+ DCHECK(CalledOnValidThread());
- MessageLoop::current()->PostDelayedTask(FROM_HERE,
- save_preferences_factory_.NewRunnableMethod(
- &PrefService::SavePersistentPrefs, thread),
- kCommitIntervalMs);
+ std::string data;
+ if (!SerializePrefData(&data))
+ return false;
+
+ writer_.ScheduleWrite(data);
+ return true;
}
void PrefService::RegisterBooleanPref(const wchar_t* path,
@@ -717,6 +644,14 @@ void PrefService::FireObservers(const wchar_t* path) {
}
}
+bool PrefService::SerializePrefData(std::string* output) const {
+ // TODO(tc): Do we want to prune webkit preferences that match the default
+ // value?
+ JSONStringValueSerializer serializer(output);
+ serializer.set_pretty_print(true);
+ return serializer.Serialize(*(persistent_.get()));
+}
+
///////////////////////////////////////////////////////////////////////////////
// PrefService::Preference