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

Side by Side Diff: chrome/browser/prefs/pref_service.cc

Issue 11741003: Remove PrefServiceSimple, replacing it with PrefService and PrefRegistrySimple. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Update production interfaces based on review comments. Created 7 years, 10 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 "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 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),
53 pref_registry_(pref_registry),
52 user_pref_store_(user_prefs), 54 user_pref_store_(user_prefs),
53 default_store_(default_store), 55 read_error_callback_(read_error_callback),
54 read_error_callback_(read_error_callback) { 56 weak_ptr_factory_(this) {
55 pref_notifier_->SetPrefService(this); 57 pref_notifier_->SetPrefService(this);
58
59 pref_registry_->SetRegistrationCallback(
60 base::Bind(&PrefService::AddRegisteredPreference,
61 weak_ptr_factory_.GetWeakPtr()));
Mattias Nissler (ping if slow) 2013/01/29 18:10:45 Do we need the weak_ptr_factory_ here? We hold a r
Jói 2013/01/30 14:23:33 That would be the alternative. Seems a bit cleaner
62 pref_registry_->SetUnregistrationCallback(
63 base::Bind(&PrefService::RemoveRegisteredPreference,
64 weak_ptr_factory_.GetWeakPtr()));
Mattias Nissler (ping if slow) 2013/01/29 18:10:45 So this will break if we're ever passing a registr
Jói 2013/01/30 14:23:33 Yes, which is why I used the approach you see in p
65 AddInitialPreferences();
66
56 InitFromStorage(async); 67 InitFromStorage(async);
57 } 68 }
58 69
59 PrefService::~PrefService() { 70 PrefService::~PrefService() {
60 DCHECK(CalledOnValidThread()); 71 DCHECK(CalledOnValidThread());
61 72
62 // Reset pointers so accesses after destruction reliably crash. 73 // Reset pointers so accesses after destruction reliably crash.
63 pref_value_store_.reset(); 74 pref_value_store_.reset();
64 user_pref_store_ = NULL; 75 user_pref_store_ = NULL;
65 default_store_ = NULL;
66 pref_notifier_.reset(); 76 pref_notifier_.reset();
67 } 77 }
68 78
69 void PrefService::InitFromStorage(bool async) { 79 void PrefService::InitFromStorage(bool async) {
70 if (!async) { 80 if (!async) {
71 read_error_callback_.Run(user_pref_store_->ReadPrefs()); 81 read_error_callback_.Run(user_pref_store_->ReadPrefs());
72 } else { 82 } else {
73 // Guarantee that initialization happens after this function returned. 83 // Guarantee that initialization happens after this function returned.
74 MessageLoop::current()->PostTask( 84 MessageLoop::current()->PostTask(
75 FROM_HERE, 85 FROM_HERE,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
165 } 175 }
166 176
167 bool PrefService::HasPrefPath(const char* path) const { 177 bool PrefService::HasPrefPath(const char* path) const {
168 const Preference* pref = FindPreference(path); 178 const Preference* pref = FindPreference(path);
169 return pref && !pref->IsDefaultValue(); 179 return pref && !pref->IsDefaultValue();
170 } 180 }
171 181
172 DictionaryValue* PrefService::GetPreferenceValues() const { 182 DictionaryValue* PrefService::GetPreferenceValues() const {
173 DCHECK(CalledOnValidThread()); 183 DCHECK(CalledOnValidThread());
174 DictionaryValue* out = new DictionaryValue; 184 DictionaryValue* out = new DictionaryValue;
175 DefaultPrefStore::const_iterator i = default_store_->begin(); 185 PrefRegistry::const_iterator i = pref_registry_->begin();
176 for (; i != default_store_->end(); ++i) { 186 for (; i != pref_registry_->end(); ++i) {
177 const Value* value = GetPreferenceValue(i->first); 187 const Value* value = GetPreferenceValue(i->first);
178 DCHECK(value); 188 DCHECK(value);
179 out->Set(i->first, value->DeepCopy()); 189 out->Set(i->first, value->DeepCopy());
180 } 190 }
181 return out; 191 return out;
182 } 192 }
183 193
184 const PrefService::Preference* PrefService::FindPreference( 194 const PrefService::Preference* PrefService::FindPreference(
185 const char* pref_name) const { 195 const char* pref_name) const {
186 DCHECK(CalledOnValidThread()); 196 DCHECK(CalledOnValidThread());
187 PreferenceMap::iterator it = prefs_map_.find(pref_name); 197 PreferenceMap::iterator it = prefs_map_.find(pref_name);
188 if (it != prefs_map_.end()) 198 if (it != prefs_map_.end())
189 return &(it->second); 199 return &(it->second);
190 const base::Value::Type type = default_store_->GetType(pref_name); 200 const base::Value* default_value = NULL;
191 if (type == Value::TYPE_NULL) 201 if (!pref_registry_->defaults()->GetValue(pref_name, &default_value))
192 return NULL; 202 return NULL;
193 it = prefs_map_.insert( 203 it = prefs_map_.insert(
194 std::make_pair(pref_name, Preference(this, pref_name, type))).first; 204 std::make_pair(pref_name, Preference(
205 this, pref_name, default_value->GetType()))).first;
195 return &(it->second); 206 return &(it->second);
196 } 207 }
197 208
198 bool PrefService::ReadOnly() const { 209 bool PrefService::ReadOnly() const {
199 return user_pref_store_->ReadOnly(); 210 return user_pref_store_->ReadOnly();
200 } 211 }
201 212
202 PrefService::PrefInitializationStatus PrefService::GetInitializationStatus() 213 PrefService::PrefInitializationStatus PrefService::GetInitializationStatus()
203 const { 214 const {
204 if (!user_pref_store_->IsInitializationComplete()) 215 if (!user_pref_store_->IsInitializationComplete())
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 return NULL; 270 return NULL;
260 } 271 }
261 272
262 return value; 273 return value;
263 } 274 }
264 275
265 const base::Value* PrefService::GetDefaultPrefValue(const char* path) const { 276 const base::Value* PrefService::GetDefaultPrefValue(const char* path) const {
266 DCHECK(CalledOnValidThread()); 277 DCHECK(CalledOnValidThread());
267 // Lookup the preference in the default store. 278 // Lookup the preference in the default store.
268 const base::Value* value = NULL; 279 const base::Value* value = NULL;
269 if (!default_store_->GetValue(path, &value)) { 280 if (!pref_registry_->defaults()->GetValue(path, &value)) {
270 NOTREACHED() << "Default value missing for pref: " << path; 281 NOTREACHED() << "Default value missing for pref: " << path;
271 return NULL; 282 return NULL;
272 } 283 }
273 return value; 284 return value;
274 } 285 }
275 286
276 const ListValue* PrefService::GetList(const char* path) const { 287 const ListValue* PrefService::GetList(const char* path) const {
277 DCHECK(CalledOnValidThread()); 288 DCHECK(CalledOnValidThread());
278 289
279 const Value* value = GetPreferenceValue(path); 290 const Value* value = GetPreferenceValue(path);
(...skipping 13 matching lines...) Expand all
293 } 304 }
294 305
295 void PrefService::RemovePrefObserver(const char* path, PrefObserver* obs) { 306 void PrefService::RemovePrefObserver(const char* path, PrefObserver* obs) {
296 pref_notifier_->RemovePrefObserver(path, obs); 307 pref_notifier_->RemovePrefObserver(path, obs);
297 } 308 }
298 309
299 void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) { 310 void PrefService::AddPrefInitObserver(base::Callback<void(bool)> obs) {
300 pref_notifier_->AddInitObserver(obs); 311 pref_notifier_->AddInitObserver(obs);
301 } 312 }
302 313
303 void PrefService::RegisterPreference(const char* path, 314 PrefRegistry* PrefService::DeprecatedGetPrefRegistry() {
304 Value* default_value) { 315 return pref_registry_.get();
316 }
317
318 void PrefService::AddInitialPreferences() {
319 for (PrefRegistry::const_iterator it = pref_registry_->begin();
320 it != pref_registry_->end();
321 ++it) {
322 AddRegisteredPreference(it->first.c_str(), it->second);
323 }
324 }
325
326 // TODO(joi): Once MarkNeedsEmptyValue is gone, we can probably
327 // completely get rid of this method. There will be one difference in
328 // semantics; currently all registered preferences are stored right
329 // away in the prefs_map_, if we remove this they would be stored only
330 // opportunistically.
331 void PrefService::AddRegisteredPreference(const char* path,
332 Value* default_value) {
305 DCHECK(CalledOnValidThread()); 333 DCHECK(CalledOnValidThread());
306 334
307 // The main code path takes ownership, but most don't. We'll be safe. 335 // Calling FindPreference here has the side-effect of updating the
308 scoped_ptr<Value> scoped_value(default_value); 336 // pref_map_ cache, so all preferences are immediately in the cache.
309 337 bool already_registered = FindPreference(path);
310 CHECK(!FindPreference(path)) << "Tried to register duplicate pref " << path; 338 CHECK(!already_registered) << "Tried to register duplicate pref " << path;
311
312 base::Value::Type orig_type = default_value->GetType();
313 DCHECK(orig_type != Value::TYPE_NULL && orig_type != Value::TYPE_BINARY) <<
314 "invalid preference type: " << orig_type;
315 339
316 // For ListValue and DictionaryValue with non empty default, empty value 340 // For ListValue and DictionaryValue with non empty default, empty value
317 // for |path| needs to be persisted in |user_pref_store_|. So that 341 // 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 342 // non empty default is not used when user sets an empty ListValue or
319 // DictionaryValue. 343 // DictionaryValue.
320 bool needs_empty_value = false; 344 bool needs_empty_value = false;
345 base::Value::Type orig_type = default_value->GetType();
321 if (orig_type == base::Value::TYPE_LIST) { 346 if (orig_type == base::Value::TYPE_LIST) {
322 const base::ListValue* list = NULL; 347 const base::ListValue* list = NULL;
323 if (default_value->GetAsList(&list) && !list->empty()) 348 if (default_value->GetAsList(&list) && !list->empty())
324 needs_empty_value = true; 349 needs_empty_value = true;
325 } else if (orig_type == base::Value::TYPE_DICTIONARY) { 350 } else if (orig_type == base::Value::TYPE_DICTIONARY) {
326 const base::DictionaryValue* dict = NULL; 351 const base::DictionaryValue* dict = NULL;
327 if (default_value->GetAsDictionary(&dict) && !dict->empty()) 352 if (default_value->GetAsDictionary(&dict) && !dict->empty())
328 needs_empty_value = true; 353 needs_empty_value = true;
329 } 354 }
330 if (needs_empty_value) 355 if (needs_empty_value)
331 user_pref_store_->MarkNeedsEmptyValue(path); 356 user_pref_store_->MarkNeedsEmptyValue(path);
332
333 // Hand off ownership.
334 default_store_->SetDefaultValue(path, scoped_value.release());
335 } 357 }
336 358
337 void PrefService::UnregisterPreference(const char* path) { 359 // TODO(joi): We can get rid of this once the ability to unregister
360 // prefs has been removed.
361 void PrefService::RemoveRegisteredPreference(const char* path) {
338 DCHECK(CalledOnValidThread()); 362 DCHECK(CalledOnValidThread());
339 363
340 PreferenceMap::iterator it = prefs_map_.find(path); 364 prefs_map_.erase(path);
341 CHECK(it != prefs_map_.end()) << "Trying to unregister an unregistered pref: "
342 << path;
343
344 prefs_map_.erase(it);
345 default_store_->RemoveDefaultValue(path);
346 } 365 }
347 366
348 void PrefService::ClearPref(const char* path) { 367 void PrefService::ClearPref(const char* path) {
349 DCHECK(CalledOnValidThread()); 368 DCHECK(CalledOnValidThread());
350 369
351 const Preference* pref = FindPreference(path); 370 const Preference* pref = FindPreference(path);
352 if (!pref) { 371 if (!pref) {
353 NOTREACHED() << "Trying to clear an unregistered pref: " << path; 372 NOTREACHED() << "Trying to clear an unregistered pref: " << path;
354 return; 373 return;
355 } 374 }
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 return pref_value_store()->PrefValueUserModifiable(name_.c_str()); 573 return pref_value_store()->PrefValueUserModifiable(name_.c_str());
555 } 574 }
556 575
557 bool PrefService::Preference::IsExtensionModifiable() const { 576 bool PrefService::Preference::IsExtensionModifiable() const {
558 return pref_value_store()->PrefValueExtensionModifiable(name_.c_str()); 577 return pref_value_store()->PrefValueExtensionModifiable(name_.c_str());
559 } 578 }
560 579
561 const base::Value* PrefService::GetPreferenceValue( 580 const base::Value* PrefService::GetPreferenceValue(
562 const std::string& path) const { 581 const std::string& path) const {
563 DCHECK(CalledOnValidThread()); 582 DCHECK(CalledOnValidThread());
564 const base::Value::Type type = default_store_->GetType(path); 583 const Value* default_value = NULL;
565 if (type == Value::TYPE_NULL) 584 if (pref_registry_->defaults()->GetValue(path, &default_value)) {
566 return NULL; 585 const Value* found_value = NULL;
567 const Value* found_value = NULL; 586 base::Value::Type default_type = default_value->GetType();
568 if (pref_value_store_->GetValue(path, type, &found_value)) { 587 if (pref_value_store_->GetValue(path, default_type, &found_value)) {
569 DCHECK(found_value->IsType(type)); 588 DCHECK(found_value->IsType(default_type));
570 return found_value; 589 return found_value;
590 } else {
591 // Every registered preference has at least a default value.
592 NOTREACHED() << "no valid value found for registered pref " << path;
593 }
571 } 594 }
572 595
573 // Every registered preference has at least a default value.
574 NOTREACHED() << "no valid value found for registered pref " << path;
575 return NULL; 596 return NULL;
576 } 597 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698