Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(798)

Side by Side Diff: trunk/src/base/prefs/json_pref_store.cc

Issue 273243002: Revert 269415 "Introduce a new framework for back-and-forth trac..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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"
(...skipping 21 matching lines...) Expand all
32 base::SequencedTaskRunner* sequenced_task_runner) 32 base::SequencedTaskRunner* sequenced_task_runner)
33 : no_dir_(false), 33 : no_dir_(false),
34 error_(PersistentPrefStore::PREF_READ_ERROR_NONE), 34 error_(PersistentPrefStore::PREF_READ_ERROR_NONE),
35 delegate_(delegate), 35 delegate_(delegate),
36 sequenced_task_runner_(sequenced_task_runner), 36 sequenced_task_runner_(sequenced_task_runner),
37 origin_loop_proxy_(base::MessageLoopProxy::current()) { 37 origin_loop_proxy_(base::MessageLoopProxy::current()) {
38 } 38 }
39 39
40 void Start(const base::FilePath& path) { 40 void Start(const base::FilePath& path) {
41 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 41 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
42 // TODO(gab): This should use PostTaskAndReplyWithResult instead of using
43 // the |error_| member to pass data across tasks.
44 sequenced_task_runner_->PostTask( 42 sequenced_task_runner_->PostTask(
45 FROM_HERE, 43 FROM_HERE,
46 base::Bind(&FileThreadDeserializer::ReadFileAndReport, 44 base::Bind(&FileThreadDeserializer::ReadFileAndReport,
47 this, path)); 45 this, path));
48 } 46 }
49 47
50 // Deserializes JSON on the sequenced task runner. 48 // Deserializes JSON on the sequenced task runner.
51 void ReadFileAndReport(const base::FilePath& path) { 49 void ReadFileAndReport(const base::FilePath& path) {
52 DCHECK(sequenced_task_runner_->RunsTasksOnCurrentThread()); 50 DCHECK(sequenced_task_runner_->RunsTasksOnCurrentThread());
53 51
54 value_.reset(DoReading(path, &error_, &no_dir_)); 52 value_.reset(DoReading(path, &error_, &no_dir_));
55 53
56 origin_loop_proxy_->PostTask( 54 origin_loop_proxy_->PostTask(
57 FROM_HERE, 55 FROM_HERE,
58 base::Bind(&FileThreadDeserializer::ReportOnOriginThread, this)); 56 base::Bind(&FileThreadDeserializer::ReportOnOriginThread, this));
59 } 57 }
60 58
61 // Reports deserialization result on the origin thread. 59 // Reports deserialization result on the origin thread.
62 void ReportOnOriginThread() { 60 void ReportOnOriginThread() {
63 DCHECK(origin_loop_proxy_->BelongsToCurrentThread()); 61 DCHECK(origin_loop_proxy_->BelongsToCurrentThread());
64 delegate_->OnFileRead(value_.Pass(), error_, no_dir_); 62 delegate_->OnFileRead(value_.release(), error_, no_dir_);
65 } 63 }
66 64
67 static base::Value* DoReading(const base::FilePath& path, 65 static base::Value* DoReading(const base::FilePath& path,
68 PersistentPrefStore::PrefReadError* error, 66 PersistentPrefStore::PrefReadError* error,
69 bool* no_dir) { 67 bool* no_dir) {
70 int error_code; 68 int error_code;
71 std::string error_msg; 69 std::string error_msg;
72 JSONFileValueSerializer serializer(path); 70 JSONFileValueSerializer serializer(path);
73 base::Value* value = serializer.Deserialize(&error_code, &error_msg); 71 base::Value* value = serializer.Deserialize(&error_code, &error_msg);
74 HandleErrors(value, path, error_code, error_msg, error); 72 HandleErrors(value, path, error_code, error_msg, error);
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 JsonPrefStore::JsonPrefStore(const base::FilePath& filename, 154 JsonPrefStore::JsonPrefStore(const base::FilePath& filename,
157 base::SequencedTaskRunner* sequenced_task_runner, 155 base::SequencedTaskRunner* sequenced_task_runner,
158 scoped_ptr<PrefFilter> pref_filter) 156 scoped_ptr<PrefFilter> pref_filter)
159 : path_(filename), 157 : path_(filename),
160 sequenced_task_runner_(sequenced_task_runner), 158 sequenced_task_runner_(sequenced_task_runner),
161 prefs_(new base::DictionaryValue()), 159 prefs_(new base::DictionaryValue()),
162 read_only_(false), 160 read_only_(false),
163 writer_(filename, sequenced_task_runner), 161 writer_(filename, sequenced_task_runner),
164 pref_filter_(pref_filter.Pass()), 162 pref_filter_(pref_filter.Pass()),
165 initialized_(false), 163 initialized_(false),
166 filtering_in_progress_(false), 164 read_error_(PREF_READ_ERROR_OTHER) {}
167 read_error_(PREF_READ_ERROR_NONE) {
168 }
169 165
170 bool JsonPrefStore::GetValue(const std::string& key, 166 bool JsonPrefStore::GetValue(const std::string& key,
171 const base::Value** result) const { 167 const base::Value** result) const {
172 base::Value* tmp = NULL; 168 base::Value* tmp = NULL;
173 if (!prefs_->Get(key, &tmp)) 169 if (!prefs_->Get(key, &tmp))
174 return false; 170 return false;
175 171
176 if (result) 172 if (result)
177 *result = tmp; 173 *result = tmp;
178 return true; 174 return true;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
221 if (!read_only_) 217 if (!read_only_)
222 writer_.ScheduleWrite(this); 218 writer_.ScheduleWrite(this);
223 } 219 }
224 } 220 }
225 221
226 void JsonPrefStore::RemoveValue(const std::string& key) { 222 void JsonPrefStore::RemoveValue(const std::string& key) {
227 if (prefs_->RemovePath(key, NULL)) 223 if (prefs_->RemovePath(key, NULL))
228 ReportValueChanged(key); 224 ReportValueChanged(key);
229 } 225 }
230 226
231 void JsonPrefStore::RemoveValueSilently(const std::string& key) {
232 prefs_->RemovePath(key, NULL);
233 if (!read_only_)
234 writer_.ScheduleWrite(this);
235 }
236
237 bool JsonPrefStore::ReadOnly() const { 227 bool JsonPrefStore::ReadOnly() const {
238 return read_only_; 228 return read_only_;
239 } 229 }
240 230
241 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const { 231 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const {
242 return read_error_; 232 return read_error_;
243 } 233 }
244 234
245 PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() { 235 PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() {
246 if (path_.empty()) { 236 if (path_.empty()) {
247 OnFileRead( 237 OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false);
248 scoped_ptr<base::Value>(), PREF_READ_ERROR_FILE_NOT_SPECIFIED, false);
249 return PREF_READ_ERROR_FILE_NOT_SPECIFIED; 238 return PREF_READ_ERROR_FILE_NOT_SPECIFIED;
250 } 239 }
251 240
252 PrefReadError error; 241 PrefReadError error;
253 bool no_dir; 242 bool no_dir;
254 scoped_ptr<base::Value> value( 243 base::Value* value =
255 FileThreadDeserializer::DoReading(path_, &error, &no_dir)); 244 FileThreadDeserializer::DoReading(path_, &error, &no_dir);
256 OnFileRead(value.Pass(), error, no_dir); 245 OnFileRead(value, error, no_dir);
257 return filtering_in_progress_ ? PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE : 246 return error;
258 error;
259 } 247 }
260 248
261 void JsonPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) { 249 void JsonPrefStore::ReadPrefsAsync(ReadErrorDelegate *error_delegate) {
262 initialized_ = false; 250 initialized_ = false;
263 error_delegate_.reset(error_delegate); 251 error_delegate_.reset(error_delegate);
264 if (path_.empty()) { 252 if (path_.empty()) {
265 OnFileRead( 253 OnFileRead(NULL, PREF_READ_ERROR_FILE_NOT_SPECIFIED, false);
266 scoped_ptr<base::Value>(), PREF_READ_ERROR_FILE_NOT_SPECIFIED, false);
267 return; 254 return;
268 } 255 }
269 256
270 // Start async reading of the preferences file. It will delete itself 257 // Start async reading of the preferences file. It will delete itself
271 // in the end. 258 // in the end.
272 scoped_refptr<FileThreadDeserializer> deserializer( 259 scoped_refptr<FileThreadDeserializer> deserializer(
273 new FileThreadDeserializer(this, sequenced_task_runner_.get())); 260 new FileThreadDeserializer(this, sequenced_task_runner_.get()));
274 deserializer->Start(path_); 261 deserializer->Start(path_);
275 } 262 }
276 263
277 void JsonPrefStore::CommitPendingWrite() { 264 void JsonPrefStore::CommitPendingWrite() {
278 if (writer_.HasPendingWrite() && !read_only_) 265 if (writer_.HasPendingWrite() && !read_only_)
279 writer_.DoScheduledWrite(); 266 writer_.DoScheduledWrite();
280 } 267 }
281 268
282 void JsonPrefStore::ReportValueChanged(const std::string& key) { 269 void JsonPrefStore::ReportValueChanged(const std::string& key) {
283 if (pref_filter_) 270 if (pref_filter_)
284 pref_filter_->FilterUpdate(key); 271 pref_filter_->FilterUpdate(key);
285 272
286 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); 273 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key));
287 274
288 if (!read_only_) 275 if (!read_only_)
289 writer_.ScheduleWrite(this); 276 writer_.ScheduleWrite(this);
290 } 277 }
291 278
292 void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback( 279 void JsonPrefStore::OnFileRead(base::Value* value_owned,
293 const base::Closure& on_next_successful_write) {
294 writer_.RegisterOnNextSuccessfulWriteCallback(on_next_successful_write);
295 }
296
297 void JsonPrefStore::OnFileRead(scoped_ptr<base::Value> value,
298 PersistentPrefStore::PrefReadError error, 280 PersistentPrefStore::PrefReadError error,
299 bool no_dir) { 281 bool no_dir) {
300 scoped_ptr<base::DictionaryValue> unfiltered_prefs(new base::DictionaryValue); 282 scoped_ptr<base::Value> value(value_owned);
301
302 read_error_ = error; 283 read_error_ = error;
303 284
304 bool initialization_successful = !no_dir; 285 if (no_dir) {
305 286 FOR_EACH_OBSERVER(PrefStore::Observer,
306 if (initialization_successful) { 287 observers_,
307 switch (read_error_) { 288 OnInitializationCompleted(false));
308 case PREF_READ_ERROR_ACCESS_DENIED: 289 return;
309 case PREF_READ_ERROR_FILE_OTHER:
310 case PREF_READ_ERROR_FILE_LOCKED:
311 case PREF_READ_ERROR_JSON_TYPE:
312 case PREF_READ_ERROR_FILE_NOT_SPECIFIED:
313 read_only_ = true;
314 break;
315 case PREF_READ_ERROR_NONE:
316 DCHECK(value.get());
317 unfiltered_prefs.reset(
318 static_cast<base::DictionaryValue*>(value.release()));
319 break;
320 case PREF_READ_ERROR_NO_FILE:
321 // If the file just doesn't exist, maybe this is first run. In any case
322 // there's no harm in writing out default prefs in this case.
323 break;
324 case PREF_READ_ERROR_JSON_PARSE:
325 case PREF_READ_ERROR_JSON_REPEAT:
326 break;
327 case PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE:
328 // This is a special error code to be returned by ReadPrefs when it
329 // can't complete synchronously, it should never be returned by the read
330 // operation itself.
331 NOTREACHED();
332 break;
333 case PREF_READ_ERROR_MAX_ENUM:
334 NOTREACHED();
335 break;
336 }
337 } 290 }
338 291
339 if (pref_filter_) { 292 initialized_ = true;
340 filtering_in_progress_ = true; 293
341 const PrefFilter::PostFilterOnLoadCallback post_filter_on_load_callback( 294 switch (error) {
342 base::Bind( 295 case PREF_READ_ERROR_ACCESS_DENIED:
343 &JsonPrefStore::FinalizeFileRead, this, initialization_successful)); 296 case PREF_READ_ERROR_FILE_OTHER:
344 pref_filter_->FilterOnLoad(post_filter_on_load_callback, 297 case PREF_READ_ERROR_FILE_LOCKED:
345 unfiltered_prefs.Pass()); 298 case PREF_READ_ERROR_JSON_TYPE:
346 } else { 299 case PREF_READ_ERROR_FILE_NOT_SPECIFIED:
347 FinalizeFileRead(initialization_successful, unfiltered_prefs.Pass(), false); 300 read_only_ = true;
301 break;
302 case PREF_READ_ERROR_NONE:
303 DCHECK(value.get());
304 prefs_.reset(static_cast<base::DictionaryValue*>(value.release()));
305 break;
306 case PREF_READ_ERROR_NO_FILE:
307 // If the file just doesn't exist, maybe this is first run. In any case
308 // there's no harm in writing out default prefs in this case.
309 break;
310 case PREF_READ_ERROR_JSON_PARSE:
311 case PREF_READ_ERROR_JSON_REPEAT:
312 break;
313 default:
314 NOTREACHED() << "Unknown error: " << error;
348 } 315 }
316
317 if (pref_filter_ && pref_filter_->FilterOnLoad(prefs_.get()))
318 writer_.ScheduleWrite(this);
319
320 if (error_delegate_.get() && error != PREF_READ_ERROR_NONE)
321 error_delegate_->OnError(error);
322
323 FOR_EACH_OBSERVER(PrefStore::Observer,
324 observers_,
325 OnInitializationCompleted(true));
349 } 326 }
350 327
351 JsonPrefStore::~JsonPrefStore() { 328 JsonPrefStore::~JsonPrefStore() {
352 CommitPendingWrite(); 329 CommitPendingWrite();
353 } 330 }
354 331
355 bool JsonPrefStore::SerializeData(std::string* output) { 332 bool JsonPrefStore::SerializeData(std::string* output) {
356 if (pref_filter_) 333 if (pref_filter_)
357 pref_filter_->FilterSerializeData(prefs_.get()); 334 pref_filter_->FilterSerializeData(prefs_.get());
358 335
359 JSONStringValueSerializer serializer(output); 336 JSONStringValueSerializer serializer(output);
360 serializer.set_pretty_print(true); 337 serializer.set_pretty_print(true);
361 return serializer.Serialize(*prefs_); 338 return serializer.Serialize(*prefs_);
362 } 339 }
363
364 void JsonPrefStore::FinalizeFileRead(bool initialization_successful,
365 scoped_ptr<base::DictionaryValue> prefs,
366 bool schedule_write) {
367 filtering_in_progress_ = false;
368
369 if (!initialization_successful) {
370 FOR_EACH_OBSERVER(PrefStore::Observer,
371 observers_,
372 OnInitializationCompleted(false));
373 return;
374 }
375
376 prefs_ = prefs.Pass();
377
378 initialized_ = true;
379
380 if (schedule_write && !read_only_)
381 writer_.ScheduleWrite(this);
382
383 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE)
384 error_delegate_->OnError(read_error_);
385
386 FOR_EACH_OBSERVER(PrefStore::Observer,
387 observers_,
388 OnInitializationCompleted(true));
389
390 return;
391 }
OLDNEW
« no previous file with comments | « trunk/src/base/prefs/json_pref_store.h ('k') | trunk/src/base/prefs/json_pref_store_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698