15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_notifier_impl.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/prefs/pref_service.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/stl_util.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrefNotifierImpl::PrefNotifierImpl() 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : pref_service_(NULL) { 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrefNotifierImpl::PrefNotifierImpl(PrefService* service) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : pref_service_(service) { 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PrefNotifierImpl::~PrefNotifierImpl() { 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that there are no pref observers when we shut down. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PrefObserverMap::iterator it = pref_observers_.begin(); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != pref_observers_.end(); ++it) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefObserverList::Iterator obs_iterator(*(it->second)); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (obs_iterator.GetNext()) { 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "pref observer found at shutdown " << it->first; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Same for initialization observers. 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!init_observers_.empty()) 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Init observer found at shutdown."; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) STLDeleteContainerPairSecondPointers(pref_observers_.begin(), 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_observers_.end()); 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_observers_.clear(); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_observers_.clear(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrefNotifierImpl::AddPrefObserver(const char* path, 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefObserver* obs) { 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Get the pref observer list associated with the path. 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefObserverList* observer_list = NULL; 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PrefObserverMap::iterator observer_iterator = 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_observers_.find(path); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_iterator == pref_observers_.end()) { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list = new PrefObserverList; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_observers_[path] = observer_list; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list = observer_iterator->second; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add the pref observer. ObserverList will DCHECK if it already is 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in the list. 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list->AddObserver(obs); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrefNotifierImpl::RemovePrefObserver(const char* path, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefObserver* obs) { 61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PrefObserverMap::iterator observer_iterator = 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_observers_.find(path); 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_iterator == pref_observers_.end()) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefObserverList* observer_list = observer_iterator->second; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer_list->RemoveObserver(obs); 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrefNotifierImpl::AddInitObserver(base::Callback<void(bool)> obs) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_observers_.push_back(obs); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrefNotifierImpl::OnPreferenceChanged(const std::string& path) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FireObservers(path); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrefNotifierImpl::OnInitializationCompleted(bool succeeded) { 82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We must make a copy of init_observers_ and clear it before we run 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // observers, or we can end up in this method re-entrantly before 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // clearing the observers list. 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PrefInitObserverList observers(init_observers_); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_observers_.clear(); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PrefInitObserverList::iterator it = observers.begin(); 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != observers.end(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it) { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it->Run(succeeded); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrefNotifierImpl::FireObservers(const std::string& path) { 98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(thread_checker_.CalledOnValidThread()); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Only send notifications for registered preferences. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!pref_service_->FindPreference(path.c_str())) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PrefObserverMap::iterator observer_iterator = 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_observers_.find(path); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (observer_iterator == pref_observers_.end()) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FOR_EACH_OBSERVER(PrefObserver, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *(observer_iterator->second), 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OnPreferenceChanged(pref_service_, path)); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PrefNotifierImpl::SetPrefService(PrefService* pref_service) { 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(pref_service_ == NULL); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pref_service_ = pref_service; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 118