| 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 "chrome/common/json_pref_store.h" | 5 #include "chrome/common/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" |
| 11 #include "base/file_util.h" | 11 #include "base/file_util.h" |
| 12 #include "base/json/json_file_value_serializer.h" | 12 #include "base/json/json_file_value_serializer.h" |
| 13 #include "base/json/json_string_value_serializer.h" | 13 #include "base/json/json_string_value_serializer.h" |
| 14 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 15 #include "base/message_loop_proxy.h" | 15 #include "base/message_loop_proxy.h" |
| 16 #include "base/sequenced_task_runner.h" | |
| 17 #include "base/values.h" | 16 #include "base/values.h" |
| 18 | 17 |
| 19 namespace { | 18 namespace { |
| 20 | 19 |
| 21 // Some extensions we'll tack on to copies of the Preferences files. | 20 // Some extensions we'll tack on to copies of the Preferences files. |
| 22 const FilePath::CharType* kBadExtension = FILE_PATH_LITERAL("bad"); | 21 const FilePath::CharType* kBadExtension = FILE_PATH_LITERAL("bad"); |
| 23 | 22 |
| 24 // Differentiates file loading between origin thread and passed | 23 // Differentiates file loading between origin thread and passed |
| 25 // (aka file) thread. | 24 // (aka file) thread. |
| 26 class FileThreadDeserializer | 25 class FileThreadDeserializer |
| 27 : public base::RefCountedThreadSafe<FileThreadDeserializer> { | 26 : public base::RefCountedThreadSafe<FileThreadDeserializer> { |
| 28 public: | 27 public: |
| 29 FileThreadDeserializer(JsonPrefStore* delegate, | 28 FileThreadDeserializer(JsonPrefStore* delegate, |
| 30 base::SequencedTaskRunner* blocking_task_runner) | 29 base::MessageLoopProxy* file_loop_proxy) |
| 31 : no_dir_(false), | 30 : no_dir_(false), |
| 32 error_(PersistentPrefStore::PREF_READ_ERROR_NONE), | 31 error_(PersistentPrefStore::PREF_READ_ERROR_NONE), |
| 33 delegate_(delegate), | 32 delegate_(delegate), |
| 34 blocking_task_runner_(blocking_task_runner), | 33 file_loop_proxy_(file_loop_proxy), |
| 35 origin_loop_proxy_(base::MessageLoopProxy::current()) { | 34 origin_loop_proxy_(base::MessageLoopProxy::current()) { |
| 36 } | 35 } |
| 37 | 36 |
| 38 void Start(const FilePath& path) { | 37 void Start(const FilePath& path) { |
| 39 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); | 38 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); |
| 40 blocking_task_runner_->PostTask( | 39 file_loop_proxy_->PostTask( |
| 41 FROM_HERE, | 40 FROM_HERE, |
| 42 base::Bind(&FileThreadDeserializer::ReadFileAndReport, | 41 base::Bind(&FileThreadDeserializer::ReadFileAndReport, |
| 43 this, path)); | 42 this, path)); |
| 44 } | 43 } |
| 45 | 44 |
| 46 // Deserializes JSON on the file thread. | 45 // Deserializes JSON on the file thread. |
| 47 void ReadFileAndReport(const FilePath& path) { | 46 void ReadFileAndReport(const FilePath& path) { |
| 47 DCHECK(file_loop_proxy_->BelongsToCurrentThread()); |
| 48 |
| 48 value_.reset(DoReading(path, &error_, &no_dir_)); | 49 value_.reset(DoReading(path, &error_, &no_dir_)); |
| 49 | 50 |
| 50 origin_loop_proxy_->PostTask( | 51 origin_loop_proxy_->PostTask( |
| 51 FROM_HERE, | 52 FROM_HERE, |
| 52 base::Bind(&FileThreadDeserializer::ReportOnOriginThread, this)); | 53 base::Bind(&FileThreadDeserializer::ReportOnOriginThread, this)); |
| 53 } | 54 } |
| 54 | 55 |
| 55 // Reports deserialization result on the origin thread. | 56 // Reports deserialization result on the origin thread. |
| 56 void ReportOnOriginThread() { | 57 void ReportOnOriginThread() { |
| 57 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); | 58 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 77 PersistentPrefStore::PrefReadError* error); | 78 PersistentPrefStore::PrefReadError* error); |
| 78 | 79 |
| 79 private: | 80 private: |
| 80 friend class base::RefCountedThreadSafe<FileThreadDeserializer>; | 81 friend class base::RefCountedThreadSafe<FileThreadDeserializer>; |
| 81 ~FileThreadDeserializer() {} | 82 ~FileThreadDeserializer() {} |
| 82 | 83 |
| 83 bool no_dir_; | 84 bool no_dir_; |
| 84 PersistentPrefStore::PrefReadError error_; | 85 PersistentPrefStore::PrefReadError error_; |
| 85 scoped_ptr<Value> value_; | 86 scoped_ptr<Value> value_; |
| 86 scoped_refptr<JsonPrefStore> delegate_; | 87 scoped_refptr<JsonPrefStore> delegate_; |
| 87 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; | 88 scoped_refptr<base::MessageLoopProxy> file_loop_proxy_; |
| 88 scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_; | 89 scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_; |
| 89 }; | 90 }; |
| 90 | 91 |
| 91 // static | 92 // static |
| 92 void FileThreadDeserializer::HandleErrors( | 93 void FileThreadDeserializer::HandleErrors( |
| 93 const Value* value, | 94 const Value* value, |
| 94 const FilePath& path, | 95 const FilePath& path, |
| 95 int error_code, | 96 int error_code, |
| 96 const std::string& error_msg, | 97 const std::string& error_msg, |
| 97 PersistentPrefStore::PrefReadError* error) { | 98 PersistentPrefStore::PrefReadError* error) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 break; | 131 break; |
| 131 } | 132 } |
| 132 } else if (!value->IsType(Value::TYPE_DICTIONARY)) { | 133 } else if (!value->IsType(Value::TYPE_DICTIONARY)) { |
| 133 *error = PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE; | 134 *error = PersistentPrefStore::PREF_READ_ERROR_JSON_TYPE; |
| 134 } | 135 } |
| 135 } | 136 } |
| 136 | 137 |
| 137 } // namespace | 138 } // namespace |
| 138 | 139 |
| 139 JsonPrefStore::JsonPrefStore(const FilePath& filename, | 140 JsonPrefStore::JsonPrefStore(const FilePath& filename, |
| 140 base::SequencedTaskRunner* blocking_task_runner) | 141 base::MessageLoopProxy* file_message_loop_proxy) |
| 141 : path_(filename), | 142 : path_(filename), |
| 142 blocking_task_runner_(blocking_task_runner), | 143 file_message_loop_proxy_(file_message_loop_proxy), |
| 143 prefs_(new DictionaryValue()), | 144 prefs_(new DictionaryValue()), |
| 144 read_only_(false), | 145 read_only_(false), |
| 145 writer_(filename, blocking_task_runner), | 146 writer_(filename, file_message_loop_proxy), |
| 146 error_delegate_(NULL), | 147 error_delegate_(NULL), |
| 147 initialized_(false), | 148 initialized_(false), |
| 148 read_error_(PREF_READ_ERROR_OTHER) { | 149 read_error_(PREF_READ_ERROR_OTHER) { |
| 149 } | 150 } |
| 150 | 151 |
| 151 PrefStore::ReadResult JsonPrefStore::GetValue(const std::string& key, | 152 PrefStore::ReadResult JsonPrefStore::GetValue(const std::string& key, |
| 152 const Value** result) const { | 153 const Value** result) const { |
| 153 Value* tmp = NULL; | 154 Value* tmp = NULL; |
| 154 if (prefs_->Get(key, &tmp)) { | 155 if (prefs_->Get(key, &tmp)) { |
| 155 if (result) | 156 if (result) |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 237 initialized_ = false; | 238 initialized_ = false; |
| 238 error_delegate_.reset(error_delegate); | 239 error_delegate_.reset(error_delegate); |
| 239 if (path_.empty()) { | 240 if (path_.empty()) { |
| 240 OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); | 241 OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); |
| 241 return; | 242 return; |
| 242 } | 243 } |
| 243 | 244 |
| 244 // Start async reading of the preferences file. It will delete itself | 245 // Start async reading of the preferences file. It will delete itself |
| 245 // in the end. | 246 // in the end. |
| 246 scoped_refptr<FileThreadDeserializer> deserializer( | 247 scoped_refptr<FileThreadDeserializer> deserializer( |
| 247 new FileThreadDeserializer(this, blocking_task_runner_)); | 248 new FileThreadDeserializer(this, file_message_loop_proxy_.get())); |
| 248 deserializer->Start(path_); | 249 deserializer->Start(path_); |
| 249 } | 250 } |
| 250 | 251 |
| 251 void JsonPrefStore::CommitPendingWrite() { | 252 void JsonPrefStore::CommitPendingWrite() { |
| 252 if (writer_.HasPendingWrite() && !read_only_) | 253 if (writer_.HasPendingWrite() && !read_only_) |
| 253 writer_.DoScheduledWrite(); | 254 writer_.DoScheduledWrite(); |
| 254 } | 255 } |
| 255 | 256 |
| 256 void JsonPrefStore::ReportValueChanged(const std::string& key) { | 257 void JsonPrefStore::ReportValueChanged(const std::string& key) { |
| 257 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); | 258 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 copy->Set(key, new base::ListValue); | 334 copy->Set(key, new base::ListValue); |
| 334 } else if (value->IsType(base::Value::TYPE_DICTIONARY)) { | 335 } else if (value->IsType(base::Value::TYPE_DICTIONARY)) { |
| 335 const base::DictionaryValue* dict = NULL; | 336 const base::DictionaryValue* dict = NULL; |
| 336 if (value->GetAsDictionary(&dict) && dict->empty()) | 337 if (value->GetAsDictionary(&dict) && dict->empty()) |
| 337 copy->Set(key, new base::DictionaryValue); | 338 copy->Set(key, new base::DictionaryValue); |
| 338 } | 339 } |
| 339 } | 340 } |
| 340 | 341 |
| 341 return serializer.Serialize(*(copy.get())); | 342 return serializer.Serialize(*(copy.get())); |
| 342 } | 343 } |
| OLD | NEW |