| 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" |
| 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/message_loop_proxy.h" | |
| 16 #include "base/prefs/pref_filter.h" | 15 #include "base/prefs/pref_filter.h" |
| 17 #include "base/sequenced_task_runner.h" | 16 #include "base/sequenced_task_runner.h" |
| 17 #include "base/thread_task_runner_handle.h" |
| 18 #include "base/threading/sequenced_worker_pool.h" | 18 #include "base/threading/sequenced_worker_pool.h" |
| 19 #include "base/values.h" | 19 #include "base/values.h" |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
| 22 | 22 |
| 23 // Some extensions we'll tack on to copies of the Preferences files. | 23 // Some extensions we'll tack on to copies of the Preferences files. |
| 24 const base::FilePath::CharType* kBadExtension = FILE_PATH_LITERAL("bad"); | 24 const base::FilePath::CharType* kBadExtension = FILE_PATH_LITERAL("bad"); |
| 25 | 25 |
| 26 // Differentiates file loading between origin thread and passed | 26 // Differentiates file loading between origin thread and passed |
| 27 // (aka file) thread. | 27 // (aka file) thread. |
| 28 class FileThreadDeserializer | 28 class FileThreadDeserializer |
| 29 : public base::RefCountedThreadSafe<FileThreadDeserializer> { | 29 : public base::RefCountedThreadSafe<FileThreadDeserializer> { |
| 30 public: | 30 public: |
| 31 FileThreadDeserializer(JsonPrefStore* delegate, | 31 FileThreadDeserializer( |
| 32 base::SequencedTaskRunner* sequenced_task_runner) | 32 JsonPrefStore* delegate, |
| 33 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner) |
| 33 : no_dir_(false), | 34 : no_dir_(false), |
| 34 error_(PersistentPrefStore::PREF_READ_ERROR_NONE), | 35 error_(PersistentPrefStore::PREF_READ_ERROR_NONE), |
| 35 delegate_(delegate), | 36 delegate_(delegate), |
| 36 sequenced_task_runner_(sequenced_task_runner), | 37 sequenced_task_runner_(sequenced_task_runner), |
| 37 origin_loop_proxy_(base::MessageLoopProxy::current()) { | 38 origin_task_runner_(base::ThreadTaskRunnerHandle::Get()) {} |
| 38 } | |
| 39 | 39 |
| 40 void Start(const base::FilePath& path, | 40 void Start(const base::FilePath& path, |
| 41 const base::FilePath& alternate_path) { | 41 const base::FilePath& alternate_path) { |
| 42 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); | 42 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); |
| 43 // TODO(gab): This should use PostTaskAndReplyWithResult instead of using | 43 // TODO(gab): This should use PostTaskAndReplyWithResult instead of using |
| 44 // the |error_| member to pass data across tasks. | 44 // the |error_| member to pass data across tasks. |
| 45 sequenced_task_runner_->PostTask( | 45 sequenced_task_runner_->PostTask( |
| 46 FROM_HERE, | 46 FROM_HERE, |
| 47 base::Bind(&FileThreadDeserializer::ReadFileAndReport, | 47 base::Bind(&FileThreadDeserializer::ReadFileAndReport, |
| 48 this, path, alternate_path)); | 48 this, path, alternate_path)); |
| 49 } | 49 } |
| 50 | 50 |
| 51 // Deserializes JSON on the sequenced task runner. | 51 // Deserializes JSON on the sequenced task runner. |
| 52 void ReadFileAndReport(const base::FilePath& path, | 52 void ReadFileAndReport(const base::FilePath& path, |
| 53 const base::FilePath& alternate_path) { | 53 const base::FilePath& alternate_path) { |
| 54 DCHECK(sequenced_task_runner_->RunsTasksOnCurrentThread()); | 54 DCHECK(sequenced_task_runner_->RunsTasksOnCurrentThread()); |
| 55 | 55 |
| 56 value_.reset(DoReading(path, alternate_path, &error_, &no_dir_)); | 56 value_.reset(DoReading(path, alternate_path, &error_, &no_dir_)); |
| 57 | 57 |
| 58 origin_loop_proxy_->PostTask( | 58 origin_task_runner_->PostTask( |
| 59 FROM_HERE, | 59 FROM_HERE, |
| 60 base::Bind(&FileThreadDeserializer::ReportOnOriginThread, this)); | 60 base::Bind(&FileThreadDeserializer::ReportOnOriginThread, this)); |
| 61 } | 61 } |
| 62 | 62 |
| 63 // Reports deserialization result on the origin thread. | 63 // Reports deserialization result on the origin thread. |
| 64 void ReportOnOriginThread() { | 64 void ReportOnOriginThread() { |
| 65 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); | 65 DCHECK(origin_task_runner_->RunsTasksOnCurrentThread()); |
| 66 delegate_->OnFileRead(value_.Pass(), error_, no_dir_); | 66 delegate_->OnFileRead(value_.Pass(), error_, no_dir_); |
| 67 } | 67 } |
| 68 | 68 |
| 69 static base::Value* DoReading(const base::FilePath& path, | 69 static base::Value* DoReading(const base::FilePath& path, |
| 70 const base::FilePath& alternate_path, | 70 const base::FilePath& alternate_path, |
| 71 PersistentPrefStore::PrefReadError* error, | 71 PersistentPrefStore::PrefReadError* error, |
| 72 bool* no_dir) { | 72 bool* no_dir) { |
| 73 if (!base::PathExists(path) && !alternate_path.empty() && | 73 if (!base::PathExists(path) && !alternate_path.empty() && |
| 74 base::PathExists(alternate_path)) { | 74 base::PathExists(alternate_path)) { |
| 75 base::Move(alternate_path, path); | 75 base::Move(alternate_path, path); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 92 | 92 |
| 93 private: | 93 private: |
| 94 friend class base::RefCountedThreadSafe<FileThreadDeserializer>; | 94 friend class base::RefCountedThreadSafe<FileThreadDeserializer>; |
| 95 ~FileThreadDeserializer() {} | 95 ~FileThreadDeserializer() {} |
| 96 | 96 |
| 97 bool no_dir_; | 97 bool no_dir_; |
| 98 PersistentPrefStore::PrefReadError error_; | 98 PersistentPrefStore::PrefReadError error_; |
| 99 scoped_ptr<base::Value> value_; | 99 scoped_ptr<base::Value> value_; |
| 100 const scoped_refptr<JsonPrefStore> delegate_; | 100 const scoped_refptr<JsonPrefStore> delegate_; |
| 101 const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_; | 101 const scoped_refptr<base::SequencedTaskRunner> sequenced_task_runner_; |
| 102 const scoped_refptr<base::MessageLoopProxy> origin_loop_proxy_; | 102 const scoped_refptr<base::SequencedTaskRunner> origin_task_runner_; |
| 103 }; | 103 }; |
| 104 | 104 |
| 105 // static | 105 // static |
| 106 void FileThreadDeserializer::HandleErrors( | 106 void FileThreadDeserializer::HandleErrors( |
| 107 const base::Value* value, | 107 const base::Value* value, |
| 108 const base::FilePath& path, | 108 const base::FilePath& path, |
| 109 int error_code, | 109 int error_code, |
| 110 const std::string& error_msg, | 110 const std::string& error_msg, |
| 111 PersistentPrefStore::PrefReadError* error) { | 111 PersistentPrefStore::PrefReadError* error) { |
| 112 *error = PersistentPrefStore::PREF_READ_ERROR_NONE; | 112 *error = PersistentPrefStore::PREF_READ_ERROR_NONE; |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 scoped_refptr<base::SequencedTaskRunner> JsonPrefStore::GetTaskRunnerForFile( | 154 scoped_refptr<base::SequencedTaskRunner> JsonPrefStore::GetTaskRunnerForFile( |
| 155 const base::FilePath& filename, | 155 const base::FilePath& filename, |
| 156 base::SequencedWorkerPool* worker_pool) { | 156 base::SequencedWorkerPool* worker_pool) { |
| 157 std::string token("json_pref_store-"); | 157 std::string token("json_pref_store-"); |
| 158 token.append(filename.AsUTF8Unsafe()); | 158 token.append(filename.AsUTF8Unsafe()); |
| 159 return worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( | 159 return worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( |
| 160 worker_pool->GetNamedSequenceToken(token), | 160 worker_pool->GetNamedSequenceToken(token), |
| 161 base::SequencedWorkerPool::BLOCK_SHUTDOWN); | 161 base::SequencedWorkerPool::BLOCK_SHUTDOWN); |
| 162 } | 162 } |
| 163 | 163 |
| 164 JsonPrefStore::JsonPrefStore(const base::FilePath& filename, | 164 JsonPrefStore::JsonPrefStore( |
| 165 base::SequencedTaskRunner* sequenced_task_runner, | 165 const base::FilePath& filename, |
| 166 scoped_ptr<PrefFilter> pref_filter) | 166 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner, |
| 167 scoped_ptr<PrefFilter> pref_filter) |
| 167 : path_(filename), | 168 : path_(filename), |
| 168 sequenced_task_runner_(sequenced_task_runner), | 169 sequenced_task_runner_(sequenced_task_runner), |
| 169 prefs_(new base::DictionaryValue()), | 170 prefs_(new base::DictionaryValue()), |
| 170 read_only_(false), | 171 read_only_(false), |
| 171 writer_(filename, sequenced_task_runner), | 172 writer_(filename, sequenced_task_runner), |
| 172 pref_filter_(pref_filter.Pass()), | 173 pref_filter_(pref_filter.Pass()), |
| 173 initialized_(false), | 174 initialized_(false), |
| 174 filtering_in_progress_(false), | 175 filtering_in_progress_(false), |
| 175 read_error_(PREF_READ_ERROR_NONE) { | 176 read_error_(PREF_READ_ERROR_NONE) { |
| 176 } | 177 } |
| 177 | 178 |
| 178 JsonPrefStore::JsonPrefStore(const base::FilePath& filename, | 179 JsonPrefStore::JsonPrefStore( |
| 179 const base::FilePath& alternate_filename, | 180 const base::FilePath& filename, |
| 180 base::SequencedTaskRunner* sequenced_task_runner, | 181 const base::FilePath& alternate_filename, |
| 181 scoped_ptr<PrefFilter> pref_filter) | 182 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner, |
| 183 scoped_ptr<PrefFilter> pref_filter) |
| 182 : path_(filename), | 184 : path_(filename), |
| 183 alternate_path_(alternate_filename), | 185 alternate_path_(alternate_filename), |
| 184 sequenced_task_runner_(sequenced_task_runner), | 186 sequenced_task_runner_(sequenced_task_runner), |
| 185 prefs_(new base::DictionaryValue()), | 187 prefs_(new base::DictionaryValue()), |
| 186 read_only_(false), | 188 read_only_(false), |
| 187 writer_(filename, sequenced_task_runner), | 189 writer_(filename, sequenced_task_runner), |
| 188 pref_filter_(pref_filter.Pass()), | 190 pref_filter_(pref_filter.Pass()), |
| 189 initialized_(false), | 191 initialized_(false), |
| 190 filtering_in_progress_(false), | 192 filtering_in_progress_(false), |
| 191 read_error_(PREF_READ_ERROR_NONE) { | 193 read_error_(PREF_READ_ERROR_NONE) { |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 412 | 414 |
| 413 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE) | 415 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE) |
| 414 error_delegate_->OnError(read_error_); | 416 error_delegate_->OnError(read_error_); |
| 415 | 417 |
| 416 FOR_EACH_OBSERVER(PrefStore::Observer, | 418 FOR_EACH_OBSERVER(PrefStore::Observer, |
| 417 observers_, | 419 observers_, |
| 418 OnInitializationCompleted(true)); | 420 OnInitializationCompleted(true)); |
| 419 | 421 |
| 420 return; | 422 return; |
| 421 } | 423 } |
| OLD | NEW |