| 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 |