OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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" |
(...skipping 23 matching lines...) Expand all Loading... | |
34 FROM_HERE, | 34 FROM_HERE, |
35 NewRunnableMethod(this, | 35 NewRunnableMethod(this, |
36 &FileThreadDeserializer::ReadFileAndReport, | 36 &FileThreadDeserializer::ReadFileAndReport, |
37 path)); | 37 path)); |
38 } | 38 } |
39 | 39 |
40 // Deserializes JSON on the FILE thread. | 40 // Deserializes JSON on the FILE thread. |
41 void ReadFileAndReport(const FilePath& path) { | 41 void ReadFileAndReport(const FilePath& path) { |
42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 42 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
43 | 43 |
44 int error_code; | 44 value_.reset(DoReading(path, &error_, &no_dir_)); |
45 std::string error_msg; | |
46 JSONFileValueSerializer serializer(path); | |
47 value_.reset(serializer.Deserialize(&error_code, &error_msg)); | |
48 | |
49 HandleErrors(value_.get(), path, error_code, error_msg, &error_); | |
50 | |
51 no_dir_ = !file_util::PathExists(path.DirName()); | |
52 | 45 |
53 BrowserThread::PostTask( | 46 BrowserThread::PostTask( |
54 BrowserThread::UI, | 47 BrowserThread::UI, |
55 FROM_HERE, | 48 FROM_HERE, |
56 NewRunnableMethod(this, &FileThreadDeserializer::ReportOnUIThread)); | 49 NewRunnableMethod(this, &FileThreadDeserializer::ReportOnUIThread)); |
57 } | 50 } |
58 | 51 |
59 // Reports deserialization result on the UI thread. | 52 // Reports deserialization result on the UI thread. |
60 void ReportOnUIThread() { | 53 void ReportOnUIThread() { |
61 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 54 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
62 delegate_->OnFileRead(value_.release(), error_, no_dir_); | 55 delegate_->OnFileRead(value_.release(), error_, no_dir_); |
63 } | 56 } |
64 | 57 |
58 static Value* DoReading(const FilePath& path, | |
59 PersistentPrefStore::PrefReadError* error, | |
60 bool* no_dir) { | |
61 int error_code; | |
62 std::string error_msg; | |
63 JSONFileValueSerializer serializer(path); | |
64 Value* value = serializer.Deserialize(&error_code, &error_msg); | |
65 HandleErrors(value, path, error_code, error_msg, error); | |
66 (*no_dir) = !file_util::PathExists(path.DirName()); | |
67 return value; | |
68 } | |
69 | |
65 static void HandleErrors(const Value* value, | 70 static void HandleErrors(const Value* value, |
66 const FilePath& path, | 71 const FilePath& path, |
67 int error_code, | 72 int error_code, |
68 const std::string& error_msg, | 73 const std::string& error_msg, |
69 PersistentPrefStore::PrefReadError* error); | 74 PersistentPrefStore::PrefReadError* error); |
70 | 75 |
71 private: | 76 private: |
72 friend class base::RefCountedThreadSafe<FileThreadDeserializer>; | 77 friend class base::RefCountedThreadSafe<FileThreadDeserializer>; |
73 | 78 |
74 bool no_dir_; | 79 bool no_dir_; |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
123 } | 128 } |
124 } | 129 } |
125 | 130 |
126 } // namespace | 131 } // namespace |
127 | 132 |
128 JsonPrefStore::JsonPrefStore(const FilePath& filename, | 133 JsonPrefStore::JsonPrefStore(const FilePath& filename, |
129 base::MessageLoopProxy* file_message_loop_proxy) | 134 base::MessageLoopProxy* file_message_loop_proxy) |
130 : path_(filename), | 135 : path_(filename), |
131 prefs_(new DictionaryValue()), | 136 prefs_(new DictionaryValue()), |
132 read_only_(false), | 137 read_only_(false), |
133 writer_(filename, file_message_loop_proxy) { | 138 writer_(filename, file_message_loop_proxy), |
139 error_(PREF_READ_ERROR_NONE), | |
140 is_fatal_(false) { | |
134 } | 141 } |
135 | 142 |
136 JsonPrefStore::~JsonPrefStore() { | 143 JsonPrefStore::~JsonPrefStore() { |
137 CommitPendingWrite(); | 144 CommitPendingWrite(); |
138 } | 145 } |
139 | 146 |
140 PrefStore::ReadResult JsonPrefStore::GetValue(const std::string& key, | 147 PrefStore::ReadResult JsonPrefStore::GetValue(const std::string& key, |
141 const Value** result) const { | 148 const Value** result) const { |
142 Value* tmp = NULL; | 149 Value* tmp = NULL; |
143 if (prefs_->Get(key, &tmp)) { | 150 if (prefs_->Get(key, &tmp)) { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
186 } | 193 } |
187 } | 194 } |
188 | 195 |
189 bool JsonPrefStore::ReadOnly() const { | 196 bool JsonPrefStore::ReadOnly() const { |
190 return read_only_; | 197 return read_only_; |
191 } | 198 } |
192 | 199 |
193 void JsonPrefStore::OnFileRead(Value* value_owned, | 200 void JsonPrefStore::OnFileRead(Value* value_owned, |
194 PersistentPrefStore::PrefReadError error, | 201 PersistentPrefStore::PrefReadError error, |
195 bool no_dir) { | 202 bool no_dir) { |
203 error_ = error; | |
204 is_fatal_ = no_dir; | |
205 | |
196 scoped_ptr<Value> value(value_owned); | 206 scoped_ptr<Value> value(value_owned); |
197 switch (error) { | 207 switch (error) { |
198 case PREF_READ_ERROR_ACCESS_DENIED: | 208 case PREF_READ_ERROR_ACCESS_DENIED: |
199 case PREF_READ_ERROR_FILE_OTHER: | 209 case PREF_READ_ERROR_FILE_OTHER: |
200 case PREF_READ_ERROR_FILE_LOCKED: | 210 case PREF_READ_ERROR_FILE_LOCKED: |
201 case PREF_READ_ERROR_JSON_TYPE: | 211 case PREF_READ_ERROR_JSON_TYPE: |
212 case PREF_READ_ERROR_FILE_NOT_SPECIFIED: | |
202 read_only_ = true; | 213 read_only_ = true; |
203 break; | 214 break; |
204 case PREF_READ_ERROR_NONE: | 215 case PREF_READ_ERROR_NONE: |
205 DCHECK(value.get()); | 216 DCHECK(value.get()); |
206 prefs_.reset(static_cast<DictionaryValue*>(value.release())); | 217 prefs_.reset(static_cast<DictionaryValue*>(value.release())); |
207 break; | 218 break; |
208 case PREF_READ_ERROR_NO_FILE: | 219 case PREF_READ_ERROR_NO_FILE: |
209 // If the file just doesn't exist, maybe this is first run. In any case | 220 // If the file just doesn't exist, maybe this is first run. In any case |
210 // there's no harm in writing out default prefs in this case. | 221 // there's no harm in writing out default prefs in this case. |
211 break; | 222 break; |
212 case PREF_READ_ERROR_JSON_PARSE: | 223 case PREF_READ_ERROR_JSON_PARSE: |
213 case PREF_READ_ERROR_JSON_REPEAT: | 224 case PREF_READ_ERROR_JSON_REPEAT: |
214 break; | 225 break; |
215 default: | 226 default: |
216 NOTREACHED() << "Unknown error: " << error; | 227 NOTREACHED() << "Unknown error: " << error; |
217 } | 228 } |
218 | 229 |
219 if (delegate_) | 230 FOR_EACH_OBSERVER(PrefStore::Observer, |
220 delegate_->OnPrefsRead(error, no_dir); | 231 observers_, |
232 OnInitializationCompleted()); | |
221 } | 233 } |
222 | 234 |
223 void JsonPrefStore::ReadPrefs(Delegate* delegate) { | 235 void JsonPrefStore::ReadPrefsAsync() { |
Mattias Nissler (ping if slow)
2011/04/26 09:04:26
I was wondering before if we could just merge Read
altimofeev
2011/04/27 10:32:08
I remember, and actually thought about it. And the
Mattias Nissler (ping if slow)
2011/04/27 12:16:30
If we do it, we should make sure we don't put addi
| |
224 DCHECK(delegate); | |
225 delegate_ = delegate; | |
226 | |
227 if (path_.empty()) { | 236 if (path_.empty()) { |
228 read_only_ = true; | 237 OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); |
229 delegate_->OnPrefsRead(PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); | |
230 return; | 238 return; |
231 } | 239 } |
232 | 240 |
233 // This guarantees that class will not be deleted while JSON is readed. | 241 // This guarantees that class will not be deleted while JSON is readed. |
234 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 242 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
235 | 243 |
236 // Start async reading of the preferences file. It will delete itself | 244 // Start async reading of the preferences file. It will delete itself |
237 // in the end. | 245 // in the end. |
238 scoped_refptr<FileThreadDeserializer> deserializer( | 246 scoped_refptr<FileThreadDeserializer> deserializer( |
239 new FileThreadDeserializer(this)); | 247 new FileThreadDeserializer(this)); |
240 deserializer->Start(path_); | 248 deserializer->Start(path_); |
241 } | 249 } |
242 | 250 |
243 PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() { | 251 PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() { |
244 delegate_ = NULL; | |
245 | |
246 if (path_.empty()) { | 252 if (path_.empty()) { |
247 read_only_ = true; | 253 OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false); |
248 return PREF_READ_ERROR_FILE_NOT_SPECIFIED; | 254 return error_; |
249 } | 255 } |
250 | 256 |
251 int error_code = 0; | 257 Value* value = FileThreadDeserializer::DoReading(path_, |
252 std::string error_msg; | 258 &error_, |
259 &is_fatal_); | |
260 OnFileRead(value, error_, is_fatal_); | |
261 return error_; | |
262 } | |
253 | 263 |
254 JSONFileValueSerializer serializer(path_); | 264 void JsonPrefStore::GetErrors(PrefReadError* error, bool* is_fatal) { |
255 scoped_ptr<Value> value(serializer.Deserialize(&error_code, &error_msg)); | 265 (*error) = error_; |
Bernhard Bauer
2011/04/25 15:54:10
Nit: the parentheses are not actually necessary, b
altimofeev
2011/04/27 10:32:08
This is the matter of taste, I think. But grep say
| |
256 | 266 (*is_fatal) = is_fatal_; |
257 PersistentPrefStore::PrefReadError error; | |
258 FileThreadDeserializer::HandleErrors(value.get(), | |
259 path_, | |
260 error_code, | |
261 error_msg, | |
262 &error); | |
263 | |
264 OnFileRead(value.release(), error, false); | |
265 | |
266 return error; | |
267 } | 267 } |
268 | 268 |
269 bool JsonPrefStore::WritePrefs() { | 269 bool JsonPrefStore::WritePrefs() { |
270 std::string data; | 270 std::string data; |
271 if (!SerializeData(&data)) | 271 if (!SerializeData(&data)) |
272 return false; | 272 return false; |
273 | 273 |
274 // Lie about our ability to save. | 274 // Lie about our ability to save. |
275 if (read_only_) | 275 if (read_only_) |
276 return true; | 276 return true; |
(...skipping 19 matching lines...) Expand all Loading... | |
296 } | 296 } |
297 | 297 |
298 bool JsonPrefStore::SerializeData(std::string* output) { | 298 bool JsonPrefStore::SerializeData(std::string* output) { |
299 // TODO(tc): Do we want to prune webkit preferences that match the default | 299 // TODO(tc): Do we want to prune webkit preferences that match the default |
300 // value? | 300 // value? |
301 JSONStringValueSerializer serializer(output); | 301 JSONStringValueSerializer serializer(output); |
302 serializer.set_pretty_print(true); | 302 serializer.set_pretty_print(true); |
303 scoped_ptr<DictionaryValue> copy(prefs_->DeepCopyWithoutEmptyChildren()); | 303 scoped_ptr<DictionaryValue> copy(prefs_->DeepCopyWithoutEmptyChildren()); |
304 return serializer.Serialize(*(copy.get())); | 304 return serializer.Serialize(*(copy.get())); |
305 } | 305 } |
OLD | NEW |