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 "chrome/browser/prefs/pref_service.h" | 5 #include "chrome/browser/prefs/pref_service.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/file_path.h" | 10 #include "base/file_path.h" |
11 #include "base/logging.h" | 11 #include "base/logging.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
14 #include "base/prefs/default_pref_store.h" | 14 #include "base/prefs/default_pref_store.h" |
15 #include "base/stl_util.h" | 15 #include "base/stl_util.h" |
16 #include "base/string_number_conversions.h" | 16 #include "base/string_number_conversions.h" |
17 #include "base/string_util.h" | 17 #include "base/string_util.h" |
18 #include "base/value_conversions.h" | 18 #include "base/value_conversions.h" |
19 #include "build/build_config.h" | 19 #include "build/build_config.h" |
20 #include "chrome/browser/prefs/pref_notifier_impl.h" | 20 #include "chrome/browser/prefs/pref_notifier_impl.h" |
21 #include "chrome/browser/prefs/pref_registry.h" | |
21 #include "chrome/browser/prefs/pref_value_store.h" | 22 #include "chrome/browser/prefs/pref_value_store.h" |
22 | 23 |
23 using content::BrowserContext; | 24 using content::BrowserContext; |
24 | 25 |
25 namespace { | 26 namespace { |
26 | 27 |
27 class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate { | 28 class ReadErrorHandler : public PersistentPrefStore::ReadErrorDelegate { |
28 public: | 29 public: |
29 ReadErrorHandler(base::Callback<void(PersistentPrefStore::PrefReadError)> cb) | 30 ReadErrorHandler(base::Callback<void(PersistentPrefStore::PrefReadError)> cb) |
30 : callback_(cb) {} | 31 : callback_(cb) {} |
31 | 32 |
32 virtual void OnError(PersistentPrefStore::PrefReadError error) { | 33 virtual void OnError(PersistentPrefStore::PrefReadError error) { |
33 callback_.Run(error); | 34 callback_.Run(error); |
34 } | 35 } |
35 | 36 |
36 private: | 37 private: |
37 base::Callback<void(PersistentPrefStore::PrefReadError)> callback_; | 38 base::Callback<void(PersistentPrefStore::PrefReadError)> callback_; |
38 }; | 39 }; |
39 | 40 |
40 } // namespace | 41 } // namespace |
41 | 42 |
42 PrefService::PrefService( | 43 PrefService::PrefService( |
43 PrefNotifierImpl* pref_notifier, | 44 PrefNotifierImpl* pref_notifier, |
44 PrefValueStore* pref_value_store, | 45 PrefValueStore* pref_value_store, |
45 PersistentPrefStore* user_prefs, | 46 PersistentPrefStore* user_prefs, |
46 DefaultPrefStore* default_store, | 47 scoped_ptr<PrefRegistry> pref_registry, |
47 base::Callback<void(PersistentPrefStore::PrefReadError)> | 48 base::Callback<void(PersistentPrefStore::PrefReadError)> |
48 read_error_callback, | 49 read_error_callback, |
49 bool async) | 50 bool async) |
50 : pref_notifier_(pref_notifier), | 51 : pref_notifier_(pref_notifier), |
51 pref_value_store_(pref_value_store), | 52 pref_value_store_(pref_value_store), |
52 user_pref_store_(user_prefs), | 53 user_pref_store_(user_prefs), |
53 default_store_(default_store), | 54 read_error_callback_(read_error_callback), |
54 read_error_callback_(read_error_callback) { | 55 pref_registry_(pref_registry.Pass()) { |
55 pref_notifier_->SetPrefService(this); | 56 pref_notifier_->SetPrefService(this); |
57 | |
58 pref_registry_->RetrieveDefaults(&default_store_); | |
59 pref_registry_->pref_service_ = this; | |
60 RegisterInitialPreferences(); | |
61 | |
56 InitFromStorage(async); | 62 InitFromStorage(async); |
57 } | 63 } |
58 | 64 |
59 PrefService::~PrefService() { | 65 PrefService::~PrefService() { |
60 DCHECK(CalledOnValidThread()); | 66 DCHECK(CalledOnValidThread()); |
61 | 67 |
62 // Reset pointers so accesses after destruction reliably crash. | 68 // Reset pointers so accesses after destruction reliably crash. |
63 pref_value_store_.reset(); | 69 pref_value_store_.reset(); |
64 user_pref_store_ = NULL; | 70 user_pref_store_ = NULL; |
65 default_store_ = NULL; | 71 default_store_ = NULL; |
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
293 } | 299 } |
294 | 300 |
295 void PrefService::RemovePrefObserver(const char* path, PrefObserver* obs) { | 301 void PrefService::RemovePrefObserver(const char* path, PrefObserver* obs) { |
296 pref_notifier_->RemovePrefObserver(path, obs); | 302 pref_notifier_->RemovePrefObserver(path, obs); |
297 } | 303 } |
298 | 304 |
299 void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) { | 305 void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) { |
300 pref_notifier_->AddInitObserver(obs); | 306 pref_notifier_->AddInitObserver(obs); |
301 } | 307 } |
302 | 308 |
309 PrefRegistry* PrefService::DeprecatedGetPrefRegistry() const { | |
310 return pref_registry_.get(); | |
311 } | |
312 | |
313 void PrefService::RegisterInitialPreferences() { | |
314 // Invariant: default_store_ is valid and contains the preferences | |
315 // registered prior to construction time. | |
316 for (DefaultPrefStore::const_iterator it = default_store_->begin(); | |
317 it != default_store_->end(); | |
318 ++it) { | |
319 RegisterPreference(it->first.c_str(), it->second, true); | |
320 } | |
321 } | |
322 | |
323 // TODO(joi): Once all registration is done before the PrefService is | |
324 // constructed, we can stop exposing a separate RegisterPreference | |
325 // method, and we can simplify the registration logic. Possibly at the | |
326 // same point we can remove UnregisterPreference. For now, because a | |
327 // few remaining places register preferences after PrefService | |
328 // construction, it is better to leave this here and have PrefRegistry | |
329 // delegate to PrefService::RegisterPreference after that | |
330 // point. Otherwise, PrefRegistry would need to control PrefService's | |
331 // default_store_ and user_pref_store_ members, as well as the | |
332 // pref_map_ member for UnregisterPreference. | |
Mattias Nissler (ping if slow)
2013/01/25 14:57:11
The default_store_ it controls already! The user_p
Jói
2013/01/29 16:10:02
Registration is now fully owned by PrefRegistry. P
| |
333 // | |
334 // We are, however, able to implement the interface we desire in the | |
335 // long term on PrefRegistry, and make this relationship an | |
336 // implementation detail. | |
303 void PrefService::RegisterPreference(const char* path, | 337 void PrefService::RegisterPreference(const char* path, |
304 Value* default_value) { | 338 Value* default_value, |
339 bool in_default_store) { | |
305 DCHECK(CalledOnValidThread()); | 340 DCHECK(CalledOnValidThread()); |
306 | 341 |
307 // The main code path takes ownership, but most don't. We'll be safe. | 342 // The main code path takes ownership, but most don't. We'll be safe. |
308 scoped_ptr<Value> scoped_value(default_value); | 343 scoped_ptr<Value> scoped_value(default_value); |
309 | 344 |
310 CHECK(!FindPreference(path)) << "Tried to register duplicate pref " << path; | 345 CHECK(!FindPreference(path)) << "Tried to register duplicate pref " << path; |
311 | 346 |
312 base::Value::Type orig_type = default_value->GetType(); | 347 base::Value::Type orig_type = default_value->GetType(); |
313 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) << | 348 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) << |
314 "invalid preference type: " << orig_type; | 349 "invalid preference type: " << orig_type; |
315 | 350 |
316 // For ListValue and DictionaryValue with non empty default, empty value | 351 // For ListValue and DictionaryValue with non empty default, empty value |
317 // for |path| needs to be persisted in |user_pref_store_|. So that | 352 // for |path| needs to be persisted in |user_pref_store_|. So that |
318 // non empty default is not used when user sets an empty ListValue or | 353 // non empty default is not used when user sets an empty ListValue or |
319 // DictionaryValue. | 354 // DictionaryValue. |
320 bool needs_empty_value = false; | 355 bool needs_empty_value = false; |
321 if (orig_type == base::Value::TYPE_LIST) { | 356 if (orig_type == base::Value::TYPE_LIST) { |
322 const base::ListValue* list = NULL; | 357 const base::ListValue* list = NULL; |
323 if (default_value->GetAsList(&list) && !list->empty()) | 358 if (default_value->GetAsList(&list) && !list->empty()) |
324 needs_empty_value = true; | 359 needs_empty_value = true; |
325 } else if (orig_type == base::Value::TYPE_DICTIONARY) { | 360 } else if (orig_type == base::Value::TYPE_DICTIONARY) { |
326 const base::DictionaryValue* dict = NULL; | 361 const base::DictionaryValue* dict = NULL; |
327 if (default_value->GetAsDictionary(&dict) && !dict->empty()) | 362 if (default_value->GetAsDictionary(&dict) && !dict->empty()) |
328 needs_empty_value = true; | 363 needs_empty_value = true; |
329 } | 364 } |
330 if (needs_empty_value) | 365 if (needs_empty_value) |
331 user_pref_store_->MarkNeedsEmptyValue(path); | 366 user_pref_store_->MarkNeedsEmptyValue(path); |
332 | 367 |
333 // Hand off ownership. | 368 if (!in_default_store) { |
334 default_store_->SetDefaultValue(path, scoped_value.release()); | 369 // Hand off ownership. |
370 default_store_->SetDefaultValue(path, scoped_value.release()); | |
371 } | |
335 } | 372 } |
336 | 373 |
337 void PrefService::UnregisterPreference(const char* path) { | 374 void PrefService::UnregisterPreference(const char* path) { |
338 DCHECK(CalledOnValidThread()); | 375 DCHECK(CalledOnValidThread()); |
339 | 376 |
340 PreferenceMap::iterator it = prefs_map_.find(path); | 377 PreferenceMap::iterator it = prefs_map_.find(path); |
341 CHECK(it != prefs_map_.end()) << "Trying to unregister an unregistered pref: " | 378 CHECK(it != prefs_map_.end()) << "Trying to unregister an unregistered pref: " |
342 << path; | 379 << path; |
343 | 380 |
344 prefs_map_.erase(it); | 381 prefs_map_.erase(it); |
345 default_store_->RemoveDefaultValue(path); | 382 default_store_->RemoveDefaultValue(path); |
346 } | 383 } |
347 | 384 |
385 bool PrefService::AllowPrefRegistrarSimple() const { | |
386 return true; | |
387 } | |
388 | |
348 void PrefService::ClearPref(const char* path) { | 389 void PrefService::ClearPref(const char* path) { |
349 DCHECK(CalledOnValidThread()); | 390 DCHECK(CalledOnValidThread()); |
350 | 391 |
351 const Preference* pref = FindPreference(path); | 392 const Preference* pref = FindPreference(path); |
352 if (!pref) { | 393 if (!pref) { |
353 NOTREACHED() << "Trying to clear an unregistered pref: " << path; | 394 NOTREACHED() << "Trying to clear an unregistered pref: " << path; |
354 return; | 395 return; |
355 } | 396 } |
356 user_pref_store_->RemoveValue(path); | 397 user_pref_store_->RemoveValue(path); |
357 } | 398 } |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 const Value* found_value = NULL; | 608 const Value* found_value = NULL; |
568 if (pref_value_store_->GetValue(path, type, &found_value)) { | 609 if (pref_value_store_->GetValue(path, type, &found_value)) { |
569 DCHECK(found_value->IsType(type)); | 610 DCHECK(found_value->IsType(type)); |
570 return found_value; | 611 return found_value; |
571 } | 612 } |
572 | 613 |
573 // Every registered preference has at least a default value. | 614 // Every registered preference has at least a default value. |
574 NOTREACHED() << "no valid value found for registered pref " << path; | 615 NOTREACHED() << "no valid value found for registered pref " << path; |
575 return NULL; | 616 return NULL; |
576 } | 617 } |
OLD | NEW |