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

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

Powered by Google App Engine
This is Rietveld 408576698