| 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" |
| (...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 151 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner, | 151 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner, |
| 152 scoped_ptr<PrefFilter> pref_filter) | 152 scoped_ptr<PrefFilter> pref_filter) |
| 153 : path_(filename), | 153 : path_(filename), |
| 154 sequenced_task_runner_(sequenced_task_runner), | 154 sequenced_task_runner_(sequenced_task_runner), |
| 155 prefs_(new base::DictionaryValue()), | 155 prefs_(new base::DictionaryValue()), |
| 156 read_only_(false), | 156 read_only_(false), |
| 157 writer_(filename, sequenced_task_runner), | 157 writer_(filename, sequenced_task_runner), |
| 158 pref_filter_(pref_filter.Pass()), | 158 pref_filter_(pref_filter.Pass()), |
| 159 initialized_(false), | 159 initialized_(false), |
| 160 filtering_in_progress_(false), | 160 filtering_in_progress_(false), |
| 161 pending_lossy_write_(false), |
| 161 read_error_(PREF_READ_ERROR_NONE), | 162 read_error_(PREF_READ_ERROR_NONE), |
| 162 write_count_histogram_(writer_.commit_interval(), path_) { | 163 write_count_histogram_(writer_.commit_interval(), path_) { |
| 163 DCHECK(!path_.empty()); | 164 DCHECK(!path_.empty()); |
| 164 } | 165 } |
| 165 | 166 |
| 166 JsonPrefStore::JsonPrefStore( | 167 JsonPrefStore::JsonPrefStore( |
| 167 const base::FilePath& filename, | 168 const base::FilePath& filename, |
| 168 const base::FilePath& alternate_filename, | 169 const base::FilePath& alternate_filename, |
| 169 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner, | 170 const scoped_refptr<base::SequencedTaskRunner>& sequenced_task_runner, |
| 170 scoped_ptr<PrefFilter> pref_filter) | 171 scoped_ptr<PrefFilter> pref_filter) |
| 171 : path_(filename), | 172 : path_(filename), |
| 172 alternate_path_(alternate_filename), | 173 alternate_path_(alternate_filename), |
| 173 sequenced_task_runner_(sequenced_task_runner), | 174 sequenced_task_runner_(sequenced_task_runner), |
| 174 prefs_(new base::DictionaryValue()), | 175 prefs_(new base::DictionaryValue()), |
| 175 read_only_(false), | 176 read_only_(false), |
| 176 writer_(filename, sequenced_task_runner), | 177 writer_(filename, sequenced_task_runner), |
| 177 pref_filter_(pref_filter.Pass()), | 178 pref_filter_(pref_filter.Pass()), |
| 178 initialized_(false), | 179 initialized_(false), |
| 179 filtering_in_progress_(false), | 180 filtering_in_progress_(false), |
| 181 pending_lossy_write_(false), |
| 180 read_error_(PREF_READ_ERROR_NONE), | 182 read_error_(PREF_READ_ERROR_NONE), |
| 181 write_count_histogram_(writer_.commit_interval(), path_) { | 183 write_count_histogram_(writer_.commit_interval(), path_) { |
| 182 DCHECK(!path_.empty()); | 184 DCHECK(!path_.empty()); |
| 183 } | 185 } |
| 184 | 186 |
| 185 bool JsonPrefStore::GetValue(const std::string& key, | 187 bool JsonPrefStore::GetValue(const std::string& key, |
| 186 const base::Value** result) const { | 188 const base::Value** result) const { |
| 187 DCHECK(CalledOnValidThread()); | 189 DCHECK(CalledOnValidThread()); |
| 188 | 190 |
| 189 base::Value* tmp = NULL; | 191 base::Value* tmp = NULL; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 base::Value* value, | 247 base::Value* value, |
| 246 uint32 flags) { | 248 uint32 flags) { |
| 247 DCHECK(CalledOnValidThread()); | 249 DCHECK(CalledOnValidThread()); |
| 248 | 250 |
| 249 DCHECK(value); | 251 DCHECK(value); |
| 250 scoped_ptr<base::Value> new_value(value); | 252 scoped_ptr<base::Value> new_value(value); |
| 251 base::Value* old_value = NULL; | 253 base::Value* old_value = NULL; |
| 252 prefs_->Get(key, &old_value); | 254 prefs_->Get(key, &old_value); |
| 253 if (!old_value || !value->Equals(old_value)) { | 255 if (!old_value || !value->Equals(old_value)) { |
| 254 prefs_->Set(key, new_value.release()); | 256 prefs_->Set(key, new_value.release()); |
| 255 if (!read_only_) | 257 ScheduleWrite(flags); |
| 256 writer_.ScheduleWrite(this); | |
| 257 } | 258 } |
| 258 } | 259 } |
| 259 | 260 |
| 260 void JsonPrefStore::RemoveValue(const std::string& key, uint32 flags) { | 261 void JsonPrefStore::RemoveValue(const std::string& key, uint32 flags) { |
| 261 DCHECK(CalledOnValidThread()); | 262 DCHECK(CalledOnValidThread()); |
| 262 | 263 |
| 263 if (prefs_->RemovePath(key, NULL)) | 264 if (prefs_->RemovePath(key, NULL)) |
| 264 ReportValueChanged(key, flags); | 265 ReportValueChanged(key, flags); |
| 265 } | 266 } |
| 266 | 267 |
| 267 void JsonPrefStore::RemoveValueSilently(const std::string& key, uint32 flags) { | 268 void JsonPrefStore::RemoveValueSilently(const std::string& key, uint32 flags) { |
| 268 DCHECK(CalledOnValidThread()); | 269 DCHECK(CalledOnValidThread()); |
| 269 | 270 |
| 270 prefs_->RemovePath(key, NULL); | 271 prefs_->RemovePath(key, NULL); |
| 271 if (!read_only_) | 272 ScheduleWrite(flags); |
| 272 writer_.ScheduleWrite(this); | |
| 273 } | 273 } |
| 274 | 274 |
| 275 bool JsonPrefStore::ReadOnly() const { | 275 bool JsonPrefStore::ReadOnly() const { |
| 276 DCHECK(CalledOnValidThread()); | 276 DCHECK(CalledOnValidThread()); |
| 277 | 277 |
| 278 return read_only_; | 278 return read_only_; |
| 279 } | 279 } |
| 280 | 280 |
| 281 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const { | 281 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const { |
| 282 DCHECK(CalledOnValidThread()); | 282 DCHECK(CalledOnValidThread()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 302 base::PostTaskAndReplyWithResult( | 302 base::PostTaskAndReplyWithResult( |
| 303 sequenced_task_runner_.get(), | 303 sequenced_task_runner_.get(), |
| 304 FROM_HERE, | 304 FROM_HERE, |
| 305 base::Bind(&ReadPrefsFromDisk, path_, alternate_path_), | 305 base::Bind(&ReadPrefsFromDisk, path_, alternate_path_), |
| 306 base::Bind(&JsonPrefStore::OnFileRead, AsWeakPtr())); | 306 base::Bind(&JsonPrefStore::OnFileRead, AsWeakPtr())); |
| 307 } | 307 } |
| 308 | 308 |
| 309 void JsonPrefStore::CommitPendingWrite() { | 309 void JsonPrefStore::CommitPendingWrite() { |
| 310 DCHECK(CalledOnValidThread()); | 310 DCHECK(CalledOnValidThread()); |
| 311 | 311 |
| 312 // Schedule a write for any lossy writes that are outstanding to ensure that |
| 313 // they get flushed when this function is called. |
| 314 if (pending_lossy_write_) |
| 315 writer_.ScheduleWrite(this); |
| 316 |
| 312 if (writer_.HasPendingWrite() && !read_only_) | 317 if (writer_.HasPendingWrite() && !read_only_) |
| 313 writer_.DoScheduledWrite(); | 318 writer_.DoScheduledWrite(); |
| 314 } | 319 } |
| 315 | 320 |
| 316 void JsonPrefStore::ReportValueChanged(const std::string& key, uint32 flags) { | 321 void JsonPrefStore::ReportValueChanged(const std::string& key, uint32 flags) { |
| 317 DCHECK(CalledOnValidThread()); | 322 DCHECK(CalledOnValidThread()); |
| 318 | 323 |
| 319 if (pref_filter_) | 324 if (pref_filter_) |
| 320 pref_filter_->FilterUpdate(key); | 325 pref_filter_->FilterUpdate(key); |
| 321 | 326 |
| 322 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); | 327 FOR_EACH_OBSERVER(PrefStore::Observer, observers_, OnPrefValueChanged(key)); |
| 323 | 328 |
| 324 if (!read_only_) | 329 ScheduleWrite(flags); |
| 325 writer_.ScheduleWrite(this); | |
| 326 } | 330 } |
| 327 | 331 |
| 328 void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback( | 332 void JsonPrefStore::RegisterOnNextSuccessfulWriteCallback( |
| 329 const base::Closure& on_next_successful_write) { | 333 const base::Closure& on_next_successful_write) { |
| 330 DCHECK(CalledOnValidThread()); | 334 DCHECK(CalledOnValidThread()); |
| 331 | 335 |
| 332 writer_.RegisterOnNextSuccessfulWriteCallback(on_next_successful_write); | 336 writer_.RegisterOnNextSuccessfulWriteCallback(on_next_successful_write); |
| 333 } | 337 } |
| 334 | 338 |
| 335 void JsonPrefStore::OnFileRead(scoped_ptr<ReadResult> read_result) { | 339 void JsonPrefStore::OnFileRead(scoped_ptr<ReadResult> read_result) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 394 } | 398 } |
| 395 } | 399 } |
| 396 | 400 |
| 397 JsonPrefStore::~JsonPrefStore() { | 401 JsonPrefStore::~JsonPrefStore() { |
| 398 CommitPendingWrite(); | 402 CommitPendingWrite(); |
| 399 } | 403 } |
| 400 | 404 |
| 401 bool JsonPrefStore::SerializeData(std::string* output) { | 405 bool JsonPrefStore::SerializeData(std::string* output) { |
| 402 DCHECK(CalledOnValidThread()); | 406 DCHECK(CalledOnValidThread()); |
| 403 | 407 |
| 408 pending_lossy_write_ = false; |
| 409 |
| 404 write_count_histogram_.RecordWriteOccured(); | 410 write_count_histogram_.RecordWriteOccured(); |
| 405 | 411 |
| 406 if (pref_filter_) | 412 if (pref_filter_) |
| 407 pref_filter_->FilterSerializeData(prefs_.get()); | 413 pref_filter_->FilterSerializeData(prefs_.get()); |
| 408 | 414 |
| 409 JSONStringValueSerializer serializer(output); | 415 JSONStringValueSerializer serializer(output); |
| 410 // Not pretty-printing prefs shrinks pref file size by ~30%. To obtain | 416 // Not pretty-printing prefs shrinks pref file size by ~30%. To obtain |
| 411 // readable prefs for debugging purposes, you can dump your prefs into any | 417 // readable prefs for debugging purposes, you can dump your prefs into any |
| 412 // command-line or online JSON pretty printing tool. | 418 // command-line or online JSON pretty printing tool. |
| 413 serializer.set_pretty_print(false); | 419 serializer.set_pretty_print(false); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 425 FOR_EACH_OBSERVER(PrefStore::Observer, | 431 FOR_EACH_OBSERVER(PrefStore::Observer, |
| 426 observers_, | 432 observers_, |
| 427 OnInitializationCompleted(false)); | 433 OnInitializationCompleted(false)); |
| 428 return; | 434 return; |
| 429 } | 435 } |
| 430 | 436 |
| 431 prefs_ = prefs.Pass(); | 437 prefs_ = prefs.Pass(); |
| 432 | 438 |
| 433 initialized_ = true; | 439 initialized_ = true; |
| 434 | 440 |
| 435 if (schedule_write && !read_only_) | 441 if (schedule_write) |
| 436 writer_.ScheduleWrite(this); | 442 ScheduleWrite(DEFAULT_PREF_WRITE_FLAGS); |
| 437 | 443 |
| 438 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE) | 444 if (error_delegate_ && read_error_ != PREF_READ_ERROR_NONE) |
| 439 error_delegate_->OnError(read_error_); | 445 error_delegate_->OnError(read_error_); |
| 440 | 446 |
| 441 FOR_EACH_OBSERVER(PrefStore::Observer, | 447 FOR_EACH_OBSERVER(PrefStore::Observer, |
| 442 observers_, | 448 observers_, |
| 443 OnInitializationCompleted(true)); | 449 OnInitializationCompleted(true)); |
| 444 | 450 |
| 445 return; | 451 return; |
| 446 } | 452 } |
| 447 | 453 |
| 454 void JsonPrefStore::ScheduleWrite(uint32 flags) { |
| 455 if (read_only_) |
| 456 return; |
| 457 |
| 458 if (flags & LOSSY_PREF_WRITE_FLAG) |
| 459 pending_lossy_write_ = true; |
| 460 else |
| 461 writer_.ScheduleWrite(this); |
| 462 } |
| 463 |
| 448 // NOTE: This value should NOT be changed without renaming the histogram | 464 // NOTE: This value should NOT be changed without renaming the histogram |
| 449 // otherwise it will create incompatible buckets. | 465 // otherwise it will create incompatible buckets. |
| 450 const int32_t | 466 const int32_t |
| 451 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins = 5; | 467 JsonPrefStore::WriteCountHistogram::kHistogramWriteReportIntervalMins = 5; |
| 452 | 468 |
| 453 JsonPrefStore::WriteCountHistogram::WriteCountHistogram( | 469 JsonPrefStore::WriteCountHistogram::WriteCountHistogram( |
| 454 const base::TimeDelta& commit_interval, | 470 const base::TimeDelta& commit_interval, |
| 455 const base::FilePath& path) | 471 const base::FilePath& path) |
| 456 : WriteCountHistogram(commit_interval, | 472 : WriteCountHistogram(commit_interval, |
| 457 path, | 473 path, |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 525 DCHECK_EQ(31, num_buckets); | 541 DCHECK_EQ(31, num_buckets); |
| 526 | 542 |
| 527 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS | 543 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS |
| 528 // macro adapted to allow for a dynamically suffixed histogram name. | 544 // macro adapted to allow for a dynamically suffixed histogram name. |
| 529 // Note: The factory creates and owns the histogram. | 545 // Note: The factory creates and owns the histogram. |
| 530 base::HistogramBase* histogram = base::Histogram::FactoryGet( | 546 base::HistogramBase* histogram = base::Histogram::FactoryGet( |
| 531 histogram_name, min_value, max_value, num_buckets, | 547 histogram_name, min_value, max_value, num_buckets, |
| 532 base::HistogramBase::kUmaTargetedHistogramFlag); | 548 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 533 return histogram; | 549 return histogram; |
| 534 } | 550 } |
| OLD | NEW |