| OLD | NEW |
| (Empty) |
| 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 | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/browser/prefs/pref_member.h" | |
| 6 | |
| 7 #include "base/bind.h" | |
| 8 #include "base/logging.h" | |
| 9 #include "base/value_conversions.h" | |
| 10 #include "chrome/browser/prefs/pref_service.h" | |
| 11 #include "chrome/common/chrome_notification_types.h" | |
| 12 | |
| 13 using content::BrowserThread; | |
| 14 | |
| 15 namespace subtle { | |
| 16 | |
| 17 PrefMemberBase::PrefMemberBase() | |
| 18 : observer_(NULL), | |
| 19 prefs_(NULL), | |
| 20 setting_value_(false) { | |
| 21 } | |
| 22 | |
| 23 PrefMemberBase::~PrefMemberBase() { | |
| 24 Destroy(); | |
| 25 } | |
| 26 | |
| 27 | |
| 28 void PrefMemberBase::Init(const char* pref_name, | |
| 29 PrefService* prefs, | |
| 30 content::NotificationObserver* observer) { | |
| 31 DCHECK(pref_name); | |
| 32 DCHECK(prefs); | |
| 33 DCHECK(pref_name_.empty()); // Check that Init is only called once. | |
| 34 observer_ = observer; | |
| 35 prefs_ = prefs; | |
| 36 pref_name_ = pref_name; | |
| 37 // Check that the preference is registered. | |
| 38 DCHECK(prefs_->FindPreference(pref_name_.c_str())) | |
| 39 << pref_name << " not registered."; | |
| 40 | |
| 41 // Add ourselves as a pref observer so we can keep our local value in sync. | |
| 42 prefs_->AddPrefObserver(pref_name, this); | |
| 43 } | |
| 44 | |
| 45 void PrefMemberBase::Destroy() { | |
| 46 if (prefs_ && !pref_name_.empty()) { | |
| 47 prefs_->RemovePrefObserver(pref_name_.c_str(), this); | |
| 48 prefs_ = NULL; | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 void PrefMemberBase::MoveToThread(BrowserThread::ID thread_id) { | |
| 53 VerifyValuePrefName(); | |
| 54 // Load the value from preferences if it hasn't been loaded so far. | |
| 55 if (!internal()) | |
| 56 UpdateValueFromPref(); | |
| 57 internal()->MoveToThread(thread_id); | |
| 58 } | |
| 59 | |
| 60 void PrefMemberBase::Observe(int type, | |
| 61 const content::NotificationSource& source, | |
| 62 const content::NotificationDetails& details) { | |
| 63 VerifyValuePrefName(); | |
| 64 DCHECK(chrome::NOTIFICATION_PREF_CHANGED == type); | |
| 65 UpdateValueFromPref(); | |
| 66 if (!setting_value_ && observer_) | |
| 67 observer_->Observe(type, source, details); | |
| 68 } | |
| 69 | |
| 70 void PrefMemberBase::UpdateValueFromPref() const { | |
| 71 VerifyValuePrefName(); | |
| 72 const PrefService::Preference* pref = | |
| 73 prefs_->FindPreference(pref_name_.c_str()); | |
| 74 DCHECK(pref); | |
| 75 if (!internal()) | |
| 76 CreateInternal(); | |
| 77 internal()->UpdateValue(pref->GetValue()->DeepCopy(), pref->IsManaged()); | |
| 78 } | |
| 79 | |
| 80 void PrefMemberBase::VerifyPref() const { | |
| 81 VerifyValuePrefName(); | |
| 82 if (!internal()) | |
| 83 UpdateValueFromPref(); | |
| 84 } | |
| 85 | |
| 86 PrefMemberBase::Internal::Internal() | |
| 87 : thread_id_(BrowserThread::UI), | |
| 88 is_managed_(false) { | |
| 89 } | |
| 90 PrefMemberBase::Internal::~Internal() { } | |
| 91 | |
| 92 bool PrefMemberBase::Internal::IsOnCorrectThread() const { | |
| 93 // In unit tests, there may not be a UI thread. | |
| 94 return (BrowserThread::CurrentlyOn(thread_id_) || | |
| 95 (thread_id_ == BrowserThread::UI && | |
| 96 !BrowserThread::IsMessageLoopValid(BrowserThread::UI))); | |
| 97 } | |
| 98 | |
| 99 void PrefMemberBase::Internal::UpdateValue(Value* v, bool is_managed) const { | |
| 100 scoped_ptr<Value> value(v); | |
| 101 if (IsOnCorrectThread()) { | |
| 102 bool rv = UpdateValueInternal(*value); | |
| 103 DCHECK(rv); | |
| 104 is_managed_ = is_managed; | |
| 105 } else { | |
| 106 bool rv = BrowserThread::PostTask( | |
| 107 thread_id_, FROM_HERE, | |
| 108 base::Bind(&PrefMemberBase::Internal::UpdateValue, this, | |
| 109 value.release(), is_managed)); | |
| 110 DCHECK(rv); | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 void PrefMemberBase::Internal::MoveToThread(BrowserThread::ID thread_id) { | |
| 115 CheckOnCorrectThread(); | |
| 116 thread_id_ = thread_id; | |
| 117 } | |
| 118 | |
| 119 } // namespace subtle | |
| 120 | |
| 121 template <> | |
| 122 void PrefMember<bool>::UpdatePref(const bool& value) { | |
| 123 prefs()->SetBoolean(pref_name().c_str(), value); | |
| 124 } | |
| 125 | |
| 126 template <> | |
| 127 bool PrefMember<bool>::Internal::UpdateValueInternal(const Value& value) const { | |
| 128 return value.GetAsBoolean(&value_); | |
| 129 } | |
| 130 | |
| 131 template <> | |
| 132 void PrefMember<int>::UpdatePref(const int& value) { | |
| 133 prefs()->SetInteger(pref_name().c_str(), value); | |
| 134 } | |
| 135 | |
| 136 template <> | |
| 137 bool PrefMember<int>::Internal::UpdateValueInternal(const Value& value) const { | |
| 138 return value.GetAsInteger(&value_); | |
| 139 } | |
| 140 | |
| 141 template <> | |
| 142 void PrefMember<double>::UpdatePref(const double& value) { | |
| 143 prefs()->SetDouble(pref_name().c_str(), value); | |
| 144 } | |
| 145 | |
| 146 template <> | |
| 147 bool PrefMember<double>::Internal::UpdateValueInternal(const Value& value) | |
| 148 const { | |
| 149 return value.GetAsDouble(&value_); | |
| 150 } | |
| 151 | |
| 152 template <> | |
| 153 void PrefMember<std::string>::UpdatePref(const std::string& value) { | |
| 154 prefs()->SetString(pref_name().c_str(), value); | |
| 155 } | |
| 156 | |
| 157 template <> | |
| 158 bool PrefMember<std::string>::Internal::UpdateValueInternal(const Value& value) | |
| 159 const { | |
| 160 return value.GetAsString(&value_); | |
| 161 } | |
| 162 | |
| 163 template <> | |
| 164 void PrefMember<FilePath>::UpdatePref(const FilePath& value) { | |
| 165 prefs()->SetFilePath(pref_name().c_str(), value); | |
| 166 } | |
| 167 | |
| 168 template <> | |
| 169 bool PrefMember<FilePath>::Internal::UpdateValueInternal(const Value& value) | |
| 170 const { | |
| 171 return base::GetValueAsFilePath(value, &value_); | |
| 172 } | |
| OLD | NEW |