| // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 
 | // Use of this source code is governed by a BSD-style license that can be | 
 | // found in the LICENSE file. | 
 |  | 
 | #include "base/prefs/pref_change_registrar.h" | 
 |  | 
 | #include "base/bind.h" | 
 | #include "base/logging.h" | 
 | #include "base/prefs/pref_service.h" | 
 |  | 
 | PrefChangeRegistrar::PrefChangeRegistrar() : service_(NULL) {} | 
 |  | 
 | PrefChangeRegistrar::~PrefChangeRegistrar() { | 
 |   // If you see an invalid memory access in this destructor, this | 
 |   // PrefChangeRegistrar might be subscribed to an OffTheRecordProfileImpl that | 
 |   // has been destroyed. This should not happen any more but be warned. | 
 |   // Feel free to contact battre@chromium.org in case this happens. | 
 |   RemoveAll(); | 
 | } | 
 |  | 
 | void PrefChangeRegistrar::Init(PrefService* service) { | 
 |   DCHECK(IsEmpty() || service_ == service); | 
 |   service_ = service; | 
 | } | 
 |  | 
 | void PrefChangeRegistrar::Add(const std::string& path, | 
 |                               const base::Closure& obs) { | 
 |   Add(path, base::Bind(&PrefChangeRegistrar::InvokeUnnamedCallback, obs)); | 
 | } | 
 |  | 
 | void PrefChangeRegistrar::Add(const std::string& path, | 
 |                               const NamedChangeCallback& obs) { | 
 |   if (!service_) { | 
 |     NOTREACHED(); | 
 |     return; | 
 |   } | 
 |   DCHECK(!IsObserved(path)) << "Already had this pref registered."; | 
 |  | 
 |   service_->AddPrefObserver(path, this); | 
 |   observers_[path] = obs; | 
 | } | 
 |  | 
 | void PrefChangeRegistrar::Remove(const std::string& path) { | 
 |   DCHECK(IsObserved(path)); | 
 |  | 
 |   observers_.erase(path); | 
 |   service_->RemovePrefObserver(path, this); | 
 | } | 
 |  | 
 | void PrefChangeRegistrar::RemoveAll() { | 
 |   for (ObserverMap::const_iterator it = observers_.begin(); | 
 |        it != observers_.end(); ++it) { | 
 |     service_->RemovePrefObserver(it->first, this); | 
 |   } | 
 |  | 
 |   observers_.clear(); | 
 | } | 
 |  | 
 | bool PrefChangeRegistrar::IsEmpty() const { | 
 |   return observers_.empty(); | 
 | } | 
 |  | 
 | bool PrefChangeRegistrar::IsObserved(const std::string& pref) { | 
 |   return observers_.find(pref) != observers_.end(); | 
 | } | 
 |  | 
 | bool PrefChangeRegistrar::IsManaged() { | 
 |   for (ObserverMap::const_iterator it = observers_.begin(); | 
 |        it != observers_.end(); ++it) { | 
 |     const PrefService::Preference* pref = service_->FindPreference(it->first); | 
 |     if (pref && pref->IsManaged()) | 
 |       return true; | 
 |   } | 
 |   return false; | 
 | } | 
 |  | 
 | void PrefChangeRegistrar::OnPreferenceChanged(PrefService* service, | 
 |                                               const std::string& pref) { | 
 |   if (IsObserved(pref)) | 
 |     observers_[pref].Run(pref); | 
 | } | 
 |  | 
 | void PrefChangeRegistrar::InvokeUnnamedCallback(const base::Closure& callback, | 
 |                                                 const std::string& pref_name) { | 
 |   callback.Run(); | 
 | } | 
 |  | 
 | PrefService* PrefChangeRegistrar::prefs() { | 
 |   return service_; | 
 | } | 
 |  | 
 | const PrefService* PrefChangeRegistrar::prefs() const { | 
 |   return service_; | 
 | } |