| 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 "components/prefs/json_pref_store.h" | 5 #include "components/prefs/json_pref_store.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <utility> | 10 #include <utility> |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 155 filtering_in_progress_(false), | 155 filtering_in_progress_(false), |
| 156 pending_lossy_write_(false), | 156 pending_lossy_write_(false), |
| 157 read_error_(PREF_READ_ERROR_NONE), | 157 read_error_(PREF_READ_ERROR_NONE), |
| 158 has_pending_write_reply_(false), | 158 has_pending_write_reply_(false), |
| 159 write_count_histogram_(writer_.commit_interval(), path_) { | 159 write_count_histogram_(writer_.commit_interval(), path_) { |
| 160 DCHECK(!path_.empty()); | 160 DCHECK(!path_.empty()); |
| 161 } | 161 } |
| 162 | 162 |
| 163 bool JsonPrefStore::GetValue(const std::string& key, | 163 bool JsonPrefStore::GetValue(const std::string& key, |
| 164 const base::Value** result) const { | 164 const base::Value** result) const { |
| 165 DCHECK(CalledOnValidThread()); | 165 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 166 | 166 |
| 167 base::Value* tmp = nullptr; | 167 base::Value* tmp = nullptr; |
| 168 if (!prefs_->Get(key, &tmp)) | 168 if (!prefs_->Get(key, &tmp)) |
| 169 return false; | 169 return false; |
| 170 | 170 |
| 171 if (result) | 171 if (result) |
| 172 *result = tmp; | 172 *result = tmp; |
| 173 return true; | 173 return true; |
| 174 } | 174 } |
| 175 | 175 |
| 176 std::unique_ptr<base::DictionaryValue> JsonPrefStore::GetValues() const { | 176 std::unique_ptr<base::DictionaryValue> JsonPrefStore::GetValues() const { |
| 177 return prefs_->CreateDeepCopy(); | 177 return prefs_->CreateDeepCopy(); |
| 178 } | 178 } |
| 179 | 179 |
| 180 void JsonPrefStore::AddObserver(PrefStore::Observer* observer) { | 180 void JsonPrefStore::AddObserver(PrefStore::Observer* observer) { |
| 181 DCHECK(CalledOnValidThread()); | 181 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 182 | 182 |
| 183 observers_.AddObserver(observer); | 183 observers_.AddObserver(observer); |
| 184 } | 184 } |
| 185 | 185 |
| 186 void JsonPrefStore::RemoveObserver(PrefStore::Observer* observer) { | 186 void JsonPrefStore::RemoveObserver(PrefStore::Observer* observer) { |
| 187 DCHECK(CalledOnValidThread()); | 187 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 188 | 188 |
| 189 observers_.RemoveObserver(observer); | 189 observers_.RemoveObserver(observer); |
| 190 } | 190 } |
| 191 | 191 |
| 192 bool JsonPrefStore::HasObservers() const { | 192 bool JsonPrefStore::HasObservers() const { |
| 193 DCHECK(CalledOnValidThread()); | 193 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 194 | 194 |
| 195 return observers_.might_have_observers(); | 195 return observers_.might_have_observers(); |
| 196 } | 196 } |
| 197 | 197 |
| 198 bool JsonPrefStore::IsInitializationComplete() const { | 198 bool JsonPrefStore::IsInitializationComplete() const { |
| 199 DCHECK(CalledOnValidThread()); | 199 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 200 | 200 |
| 201 return initialized_; | 201 return initialized_; |
| 202 } | 202 } |
| 203 | 203 |
| 204 bool JsonPrefStore::GetMutableValue(const std::string& key, | 204 bool JsonPrefStore::GetMutableValue(const std::string& key, |
| 205 base::Value** result) { | 205 base::Value** result) { |
| 206 DCHECK(CalledOnValidThread()); | 206 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 207 | 207 |
| 208 return prefs_->Get(key, result); | 208 return prefs_->Get(key, result); |
| 209 } | 209 } |
| 210 | 210 |
| 211 void JsonPrefStore::SetValue(const std::string& key, | 211 void JsonPrefStore::SetValue(const std::string& key, |
| 212 std::unique_ptr<base::Value> value, | 212 std::unique_ptr<base::Value> value, |
| 213 uint32_t flags) { | 213 uint32_t flags) { |
| 214 DCHECK(CalledOnValidThread()); | 214 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 215 | 215 |
| 216 DCHECK(value); | 216 DCHECK(value); |
| 217 base::Value* old_value = nullptr; | 217 base::Value* old_value = nullptr; |
| 218 prefs_->Get(key, &old_value); | 218 prefs_->Get(key, &old_value); |
| 219 if (!old_value || !value->Equals(old_value)) { | 219 if (!old_value || !value->Equals(old_value)) { |
| 220 prefs_->Set(key, std::move(value)); | 220 prefs_->Set(key, std::move(value)); |
| 221 ReportValueChanged(key, flags); | 221 ReportValueChanged(key, flags); |
| 222 } | 222 } |
| 223 } | 223 } |
| 224 | 224 |
| 225 void JsonPrefStore::SetValueSilently(const std::string& key, | 225 void JsonPrefStore::SetValueSilently(const std::string& key, |
| 226 std::unique_ptr<base::Value> value, | 226 std::unique_ptr<base::Value> value, |
| 227 uint32_t flags) { | 227 uint32_t flags) { |
| 228 DCHECK(CalledOnValidThread()); | 228 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 229 | 229 |
| 230 DCHECK(value); | 230 DCHECK(value); |
| 231 base::Value* old_value = nullptr; | 231 base::Value* old_value = nullptr; |
| 232 prefs_->Get(key, &old_value); | 232 prefs_->Get(key, &old_value); |
| 233 if (!old_value || !value->Equals(old_value)) { | 233 if (!old_value || !value->Equals(old_value)) { |
| 234 prefs_->Set(key, std::move(value)); | 234 prefs_->Set(key, std::move(value)); |
| 235 ScheduleWrite(flags); | 235 ScheduleWrite(flags); |
| 236 } | 236 } |
| 237 } | 237 } |
| 238 | 238 |
| 239 void JsonPrefStore::RemoveValue(const std::string& key, uint32_t flags) { | 239 void JsonPrefStore::RemoveValue(const std::string& key, uint32_t flags) { |
| 240 DCHECK(CalledOnValidThread()); | 240 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 241 | 241 |
| 242 if (prefs_->RemovePath(key, nullptr)) | 242 if (prefs_->RemovePath(key, nullptr)) |
| 243 ReportValueChanged(key, flags); | 243 ReportValueChanged(key, flags); |
| 244 } | 244 } |
| 245 | 245 |
| 246 void JsonPrefStore::RemoveValueSilently(const std::string& key, | 246 void JsonPrefStore::RemoveValueSilently(const std::string& key, |
| 247 uint32_t flags) { | 247 uint32_t flags) { |
| 248 DCHECK(CalledOnValidThread()); | 248 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 249 | 249 |
| 250 prefs_->RemovePath(key, nullptr); | 250 prefs_->RemovePath(key, nullptr); |
| 251 ScheduleWrite(flags); | 251 ScheduleWrite(flags); |
| 252 } | 252 } |
| 253 | 253 |
| 254 bool JsonPrefStore::ReadOnly() const { | 254 bool JsonPrefStore::ReadOnly() const { |
| 255 DCHECK(CalledOnValidThread()); | 255 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 256 | 256 |
| 257 return read_only_; | 257 return read_only_; |
| 258 } | 258 } |
| 259 | 259 |
| 260 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const { | 260 PersistentPrefStore::PrefReadError JsonPrefStore::GetReadError() const { |
| 261 DCHECK(CalledOnValidThread()); | 261 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 262 | 262 |
| 263 return read_error_; | 263 return read_error_; |
| 264 } | 264 } |
| 265 | 265 |
| 266 PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() { | 266 PersistentPrefStore::PrefReadError JsonPrefStore::ReadPrefs() { |
| 267 DCHECK(CalledOnValidThread()); | 267 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 268 | 268 |
| 269 OnFileRead(ReadPrefsFromDisk(path_)); | 269 OnFileRead(ReadPrefsFromDisk(path_)); |
| 270 return filtering_in_progress_ ? PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE | 270 return filtering_in_progress_ ? PREF_READ_ERROR_ASYNCHRONOUS_TASK_INCOMPLETE |
| 271 : read_error_; | 271 : read_error_; |
| 272 } | 272 } |
| 273 | 273 |
| 274 void JsonPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) { | 274 void JsonPrefStore::ReadPrefsAsync(ReadErrorDelegate* error_delegate) { |
| 275 DCHECK(CalledOnValidThread()); | 275 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 276 | 276 |
| 277 initialized_ = false; | 277 initialized_ = false; |
| 278 error_delegate_.reset(error_delegate); | 278 error_delegate_.reset(error_delegate); |
| 279 | 279 |
| 280 // Weakly binds the read task so that it doesn't kick in during shutdown. | 280 // Weakly binds the read task so that it doesn't kick in during shutdown. |
| 281 base::PostTaskAndReplyWithResult( | 281 base::PostTaskAndReplyWithResult( |
| 282 sequenced_task_runner_.get(), FROM_HERE, | 282 sequenced_task_runner_.get(), FROM_HERE, |
| 283 base::Bind(&ReadPrefsFromDisk, path_), | 283 base::Bind(&ReadPrefsFromDisk, path_), |
| 284 base::Bind(&JsonPrefStore::OnFileRead, AsWeakPtr())); | 284 base::Bind(&JsonPrefStore::OnFileRead, AsWeakPtr())); |
| 285 } | 285 } |
| 286 | 286 |
| 287 void JsonPrefStore::CommitPendingWrite() { | 287 void JsonPrefStore::CommitPendingWrite() { |
| 288 DCHECK(CalledOnValidThread()); | 288 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 289 | 289 |
| 290 // Schedule a write for any lossy writes that are outstanding to ensure that | 290 // Schedule a write for any lossy writes that are outstanding to ensure that |
| 291 // they get flushed when this function is called. | 291 // they get flushed when this function is called. |
| 292 SchedulePendingLossyWrites(); | 292 SchedulePendingLossyWrites(); |
| 293 | 293 |
| 294 if (writer_.HasPendingWrite() && !read_only_) | 294 if (writer_.HasPendingWrite() && !read_only_) |
| 295 writer_.DoScheduledWrite(); | 295 writer_.DoScheduledWrite(); |
| 296 } | 296 } |
| 297 | 297 |
| 298 void JsonPrefStore::SchedulePendingLossyWrites() { | 298 void JsonPrefStore::SchedulePendingLossyWrites() { |
| 299 if (pending_lossy_write_) | 299 if (pending_lossy_write_) |
| 300 writer_.ScheduleWrite(this); | 300 writer_.ScheduleWrite(this); |
| 301 } | 301 } |
| 302 | 302 |
| 303 void JsonPrefStore::ReportValueChanged(const std::string& key, uint32_t flags) { | 303 void JsonPrefStore::ReportValueChanged(const std::string& key, uint32_t flags) { |
| 304 DCHECK(CalledOnValidThread()); | 304 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 305 | 305 |
| 306 if (pref_filter_) | 306 if (pref_filter_) |
| 307 pref_filter_->FilterUpdate(key); | 307 pref_filter_->FilterUpdate(key); |
| 308 | 308 |
| 309 for (PrefStore::Observer& observer : observers_) | 309 for (PrefStore::Observer& observer : observers_) |
| 310 observer.OnPrefValueChanged(key); | 310 observer.OnPrefValueChanged(key); |
| 311 | 311 |
| 312 ScheduleWrite(flags); | 312 ScheduleWrite(flags); |
| 313 } | 313 } |
| 314 | 314 |
| 315 void JsonPrefStore::RunOrScheduleNextSuccessfulWriteCallback( | 315 void JsonPrefStore::RunOrScheduleNextSuccessfulWriteCallback( |
| 316 bool write_success) { | 316 bool write_success) { |
| 317 DCHECK(CalledOnValidThread()); | 317 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 318 | 318 |
| 319 has_pending_write_reply_ = false; | 319 has_pending_write_reply_ = false; |
| 320 if (!on_next_successful_write_reply_.is_null()) { | 320 if (!on_next_successful_write_reply_.is_null()) { |
| 321 base::Closure on_successful_write = | 321 base::Closure on_successful_write = |
| 322 std::move(on_next_successful_write_reply_); | 322 std::move(on_next_successful_write_reply_); |
| 323 if (write_success) { | 323 if (write_success) { |
| 324 on_successful_write.Run(); | 324 on_successful_write.Run(); |
| 325 } else { | 325 } else { |
| 326 RegisterOnNextSuccessfulWriteReply(on_successful_write); | 326 RegisterOnNextSuccessfulWriteReply(on_successful_write); |
| 327 } | 327 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 338 on_next_write_callback.Run(write_success); | 338 on_next_write_callback.Run(write_success); |
| 339 | 339 |
| 340 // We can't run |on_next_write_reply| on the current thread. Bounce back to | 340 // We can't run |on_next_write_reply| on the current thread. Bounce back to |
| 341 // the |reply_task_runner| which is the correct sequenced thread. | 341 // the |reply_task_runner| which is the correct sequenced thread. |
| 342 reply_task_runner->PostTask(FROM_HERE, | 342 reply_task_runner->PostTask(FROM_HERE, |
| 343 base::Bind(on_next_write_reply, write_success)); | 343 base::Bind(on_next_write_reply, write_success)); |
| 344 } | 344 } |
| 345 | 345 |
| 346 void JsonPrefStore::RegisterOnNextSuccessfulWriteReply( | 346 void JsonPrefStore::RegisterOnNextSuccessfulWriteReply( |
| 347 const base::Closure& on_next_successful_write_reply) { | 347 const base::Closure& on_next_successful_write_reply) { |
| 348 DCHECK(CalledOnValidThread()); | 348 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 349 DCHECK(on_next_successful_write_reply_.is_null()); | 349 DCHECK(on_next_successful_write_reply_.is_null()); |
| 350 | 350 |
| 351 on_next_successful_write_reply_ = on_next_successful_write_reply; | 351 on_next_successful_write_reply_ = on_next_successful_write_reply; |
| 352 | 352 |
| 353 // If there are pending callbacks, avoid erasing them; the reply will be used | 353 // If there are pending callbacks, avoid erasing them; the reply will be used |
| 354 // as we set |on_next_successful_write_reply_|. Otherwise, setup a reply with | 354 // as we set |on_next_successful_write_reply_|. Otherwise, setup a reply with |
| 355 // an empty callback. | 355 // an empty callback. |
| 356 if (!has_pending_write_reply_) { | 356 if (!has_pending_write_reply_) { |
| 357 has_pending_write_reply_ = true; | 357 has_pending_write_reply_ = true; |
| 358 writer_.RegisterOnNextWriteCallbacks( | 358 writer_.RegisterOnNextWriteCallbacks( |
| 359 base::Closure(), | 359 base::Closure(), |
| 360 base::Bind( | 360 base::Bind( |
| 361 &PostWriteCallback, base::Callback<void(bool success)>(), | 361 &PostWriteCallback, base::Callback<void(bool success)>(), |
| 362 base::Bind(&JsonPrefStore::RunOrScheduleNextSuccessfulWriteCallback, | 362 base::Bind(&JsonPrefStore::RunOrScheduleNextSuccessfulWriteCallback, |
| 363 AsWeakPtr()), | 363 AsWeakPtr()), |
| 364 base::SequencedTaskRunnerHandle::Get())); | 364 base::SequencedTaskRunnerHandle::Get())); |
| 365 } | 365 } |
| 366 } | 366 } |
| 367 | 367 |
| 368 void JsonPrefStore::RegisterOnNextWriteSynchronousCallbacks( | 368 void JsonPrefStore::RegisterOnNextWriteSynchronousCallbacks( |
| 369 OnWriteCallbackPair callbacks) { | 369 OnWriteCallbackPair callbacks) { |
| 370 DCHECK(CalledOnValidThread()); | 370 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 371 | 371 |
| 372 has_pending_write_reply_ = true; | 372 has_pending_write_reply_ = true; |
| 373 | 373 |
| 374 writer_.RegisterOnNextWriteCallbacks( | 374 writer_.RegisterOnNextWriteCallbacks( |
| 375 callbacks.first, | 375 callbacks.first, |
| 376 base::Bind( | 376 base::Bind( |
| 377 &PostWriteCallback, callbacks.second, | 377 &PostWriteCallback, callbacks.second, |
| 378 base::Bind(&JsonPrefStore::RunOrScheduleNextSuccessfulWriteCallback, | 378 base::Bind(&JsonPrefStore::RunOrScheduleNextSuccessfulWriteCallback, |
| 379 AsWeakPtr()), | 379 AsWeakPtr()), |
| 380 base::SequencedTaskRunnerHandle::Get())); | 380 base::SequencedTaskRunnerHandle::Get())); |
| 381 } | 381 } |
| 382 | 382 |
| 383 void JsonPrefStore::ClearMutableValues() { | 383 void JsonPrefStore::ClearMutableValues() { |
| 384 NOTIMPLEMENTED(); | 384 NOTIMPLEMENTED(); |
| 385 } | 385 } |
| 386 | 386 |
| 387 void JsonPrefStore::OnFileRead(std::unique_ptr<ReadResult> read_result) { | 387 void JsonPrefStore::OnFileRead(std::unique_ptr<ReadResult> read_result) { |
| 388 DCHECK(CalledOnValidThread()); | 388 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 389 | 389 |
| 390 DCHECK(read_result); | 390 DCHECK(read_result); |
| 391 | 391 |
| 392 std::unique_ptr<base::DictionaryValue> unfiltered_prefs( | 392 std::unique_ptr<base::DictionaryValue> unfiltered_prefs( |
| 393 new base::DictionaryValue); | 393 new base::DictionaryValue); |
| 394 | 394 |
| 395 read_error_ = read_result->error; | 395 read_error_ = read_result->error; |
| 396 | 396 |
| 397 bool initialization_successful = !read_result->no_dir; | 397 bool initialization_successful = !read_result->no_dir; |
| 398 | 398 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 initialization_successful)); | 434 initialization_successful)); |
| 435 pref_filter_->FilterOnLoad(post_filter_on_load_callback, | 435 pref_filter_->FilterOnLoad(post_filter_on_load_callback, |
| 436 std::move(unfiltered_prefs)); | 436 std::move(unfiltered_prefs)); |
| 437 } else { | 437 } else { |
| 438 FinalizeFileRead(initialization_successful, std::move(unfiltered_prefs), | 438 FinalizeFileRead(initialization_successful, std::move(unfiltered_prefs), |
| 439 false); | 439 false); |
| 440 } | 440 } |
| 441 } | 441 } |
| 442 | 442 |
| 443 JsonPrefStore::~JsonPrefStore() { | 443 JsonPrefStore::~JsonPrefStore() { |
| 444 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 444 CommitPendingWrite(); | 445 CommitPendingWrite(); |
| 445 } | 446 } |
| 446 | 447 |
| 447 bool JsonPrefStore::SerializeData(std::string* output) { | 448 bool JsonPrefStore::SerializeData(std::string* output) { |
| 448 DCHECK(CalledOnValidThread()); | 449 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 449 | 450 |
| 450 pending_lossy_write_ = false; | 451 pending_lossy_write_ = false; |
| 451 | 452 |
| 452 write_count_histogram_.RecordWriteOccured(); | 453 write_count_histogram_.RecordWriteOccured(); |
| 453 | 454 |
| 454 if (pref_filter_) { | 455 if (pref_filter_) { |
| 455 OnWriteCallbackPair callbacks = | 456 OnWriteCallbackPair callbacks = |
| 456 pref_filter_->FilterSerializeData(prefs_.get()); | 457 pref_filter_->FilterSerializeData(prefs_.get()); |
| 457 if (!callbacks.first.is_null() || !callbacks.second.is_null()) | 458 if (!callbacks.first.is_null() || !callbacks.second.is_null()) |
| 458 RegisterOnNextWriteSynchronousCallbacks(callbacks); | 459 RegisterOnNextWriteSynchronousCallbacks(callbacks); |
| 459 } | 460 } |
| 460 | 461 |
| 461 JSONStringValueSerializer serializer(output); | 462 JSONStringValueSerializer serializer(output); |
| 462 // Not pretty-printing prefs shrinks pref file size by ~30%. To obtain | 463 // Not pretty-printing prefs shrinks pref file size by ~30%. To obtain |
| 463 // readable prefs for debugging purposes, you can dump your prefs into any | 464 // readable prefs for debugging purposes, you can dump your prefs into any |
| 464 // command-line or online JSON pretty printing tool. | 465 // command-line or online JSON pretty printing tool. |
| 465 serializer.set_pretty_print(false); | 466 serializer.set_pretty_print(false); |
| 466 bool success = serializer.Serialize(*prefs_); | 467 bool success = serializer.Serialize(*prefs_); |
| 467 DCHECK(success); | 468 DCHECK(success); |
| 468 return success; | 469 return success; |
| 469 } | 470 } |
| 470 | 471 |
| 471 void JsonPrefStore::FinalizeFileRead( | 472 void JsonPrefStore::FinalizeFileRead( |
| 472 bool initialization_successful, | 473 bool initialization_successful, |
| 473 std::unique_ptr<base::DictionaryValue> prefs, | 474 std::unique_ptr<base::DictionaryValue> prefs, |
| 474 bool schedule_write) { | 475 bool schedule_write) { |
| 475 DCHECK(CalledOnValidThread()); | 476 DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_); |
| 476 | 477 |
| 477 filtering_in_progress_ = false; | 478 filtering_in_progress_ = false; |
| 478 | 479 |
| 479 if (!initialization_successful) { | 480 if (!initialization_successful) { |
| 480 for (PrefStore::Observer& observer : observers_) | 481 for (PrefStore::Observer& observer : observers_) |
| 481 observer.OnInitializationCompleted(false); | 482 observer.OnInitializationCompleted(false); |
| 482 return; | 483 return; |
| 483 } | 484 } |
| 484 | 485 |
| 485 prefs_ = std::move(prefs); | 486 prefs_ = std::move(prefs); |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 587 DCHECK_EQ(31, num_buckets); | 588 DCHECK_EQ(31, num_buckets); |
| 588 | 589 |
| 589 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS | 590 // The histogram below is an expansion of the UMA_HISTOGRAM_CUSTOM_COUNTS |
| 590 // macro adapted to allow for a dynamically suffixed histogram name. | 591 // macro adapted to allow for a dynamically suffixed histogram name. |
| 591 // Note: The factory creates and owns the histogram. | 592 // Note: The factory creates and owns the histogram. |
| 592 base::HistogramBase* histogram = base::Histogram::FactoryGet( | 593 base::HistogramBase* histogram = base::Histogram::FactoryGet( |
| 593 histogram_name, min_value, max_value, num_buckets, | 594 histogram_name, min_value, max_value, num_buckets, |
| 594 base::HistogramBase::kUmaTargetedHistogramFlag); | 595 base::HistogramBase::kUmaTargetedHistogramFlag); |
| 595 return histogram; | 596 return histogram; |
| 596 } | 597 } |
| OLD | NEW |