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 |