12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2010 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_change_registrar.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrefChangeRegistrar::PrefChangeRegistrar() : service_(NULL) {}
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrefChangeRegistrar::~PrefChangeRegistrar() {
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // If you see an invalid memory access in this destructor, this
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // PrefChangeRegistrar might be subscribed to an OffTheRecordProfileImpl that
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // has been destroyed. This should not happen any more but be warned.
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Feel free to contact battre@chromium.org in case this happens.
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  RemoveAll();
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrefChangeRegistrar::Init(PrefService* service) {
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsEmpty() || service_ == service);
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service_ = service;
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrefChangeRegistrar::Add(const char* path,
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const base::Closure& obs) {
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Add(path, base::Bind(&PrefChangeRegistrar::InvokeUnnamedCallback, obs));
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrefChangeRegistrar::Add(const char* path,
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                              const NamedChangeCallback& obs) {
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!service_) {
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    NOTREACHED();
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!IsObserved(path)) << "Already had this pref registered.";
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service_->AddPrefObserver(path, this);
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_[path] = obs;
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrefChangeRegistrar::Remove(const char* path) {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(IsObserved(path));
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.erase(path);
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  service_->RemovePrefObserver(path, this);
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrefChangeRegistrar::RemoveAll() {
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ObserverMap::const_iterator it = observers_.begin();
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != observers_.end(); ++it) {
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    service_->RemovePrefObserver(it->first.c_str(), this);
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observers_.clear();
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PrefChangeRegistrar::IsEmpty() const {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return observers_.empty();
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PrefChangeRegistrar::IsObserved(const std::string& pref) {
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return observers_.find(pref) != observers_.end();
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PrefChangeRegistrar::IsManaged() {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (ObserverMap::const_iterator it = observers_.begin();
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != observers_.end(); ++it) {
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const PrefService::Preference* pref =
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        service_->FindPreference(it->first.c_str());
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (pref && pref->IsManaged())
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return true;
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrefChangeRegistrar::OnPreferenceChanged(PrefService* service,
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                              const std::string& pref) {
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (IsObserved(pref))
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    observers_[pref].Run(pref);
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void PrefChangeRegistrar::InvokeUnnamedCallback(const base::Closure& callback,
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                                const std::string& pref_name) {
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  callback.Run();
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)PrefService* PrefChangeRegistrar::prefs() {
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return service_;
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
9390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)const PrefService* PrefChangeRegistrar::prefs() const {
9490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return service_;
9590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
96