Chromium Code Reviews| Index: sync/notifier/sync_notifier_registrar.cc |
| diff --git a/sync/notifier/sync_notifier_registrar.cc b/sync/notifier/sync_notifier_registrar.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..596cc6adc7dcb5759296132aa06dc4276556a10f |
| --- /dev/null |
| +++ b/sync/notifier/sync_notifier_registrar.cc |
| @@ -0,0 +1,127 @@ |
| +// Copyright (c) 2012 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 "sync/notifier/sync_notifier_registrar.h" |
| + |
| +#include <cstddef> |
| +#include <utility> |
| + |
| +#include "base/logging.h" |
| + |
| +namespace syncer { |
| + |
| +SyncNotifierRegistrar::SyncNotifierRegistrar() {} |
| + |
| +SyncNotifierRegistrar::~SyncNotifierRegistrar() { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| +} |
| + |
| +void SyncNotifierRegistrar::RegisterHandler(SyncNotifierObserver* handler) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + CHECK(handler); |
| + CHECK(!handlers_.HasObserver(handler)); |
| + handlers_.AddObserver(handler); |
| +} |
| + |
| +void SyncNotifierRegistrar::UpdateRegisteredIds( |
| + SyncNotifierObserver* handler, |
| + const ObjectIdSet& ids) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + CHECK(handler); |
| + CHECK(handlers_.HasObserver(handler)); |
| + // Remove all existing entries for |handler|. |
| + for (IdHandlerMap::iterator it = id_to_handler_map_.begin(); |
| + it != id_to_handler_map_.end(); ) { |
| + if (it->second == handler) { |
| + IdHandlerMap::iterator erase_it = it; |
| + ++it; |
| + id_to_handler_map_.erase(erase_it); |
| + } else { |
| + ++it; |
| + } |
| + } |
| + |
| + // Now add the entries for |handler|. We keep track of the last insertion |
| + // point so we only traverse the map once to insert all the new entries. |
| + IdHandlerMap::iterator insert_it = id_to_handler_map_.begin(); |
| + for (ObjectIdSet::const_iterator it = ids.begin(); it != ids.end(); ++it) { |
| + insert_it = |
| + id_to_handler_map_.insert(insert_it, std::make_pair(*it, handler)); |
| + CHECK_EQ(handler, insert_it->second) |
| + << "Duplicate registration: trying to register " |
| + << ObjectIdToString(insert_it->first) << " for " |
| + << handler << " when it's already registered for " |
| + << insert_it->second; |
| + } |
| +} |
| + |
| +void SyncNotifierRegistrar::UnregisterHandler(SyncNotifierObserver* handler) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + CHECK(handler); |
| + CHECK(handlers_.HasObserver(handler)); |
| + handlers_.RemoveObserver(handler); |
| +} |
| + |
| +ObjectIdSet SyncNotifierRegistrar::GetAllRegisteredIds() const { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + ObjectIdSet registered_ids; |
| + for (IdHandlerMap::const_iterator it = id_to_handler_map_.begin(); |
| + it != id_to_handler_map_.end(); ++it) { |
| + registered_ids.insert(it->first); |
| + } |
| + return registered_ids; |
| +} |
| + |
| +void SyncNotifierRegistrar::DispatchInvalidationsToHandlers( |
| + const ObjectIdPayloadMap& id_payloads, |
| + IncomingNotificationSource source) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + typedef std::map<SyncNotifierObserver*, ObjectIdPayloadMap> DispatchMap; |
| + DispatchMap dispatch_map; |
| + for (ObjectIdPayloadMap::const_iterator it = id_payloads.begin(); |
| + it != id_payloads.end(); ++it) { |
| + SyncNotifierObserver* const handler = ObjectIdToHandler(it->first); |
| + // Filter out invalidations for IDs with no handler. |
| + if (handler) |
| + dispatch_map[handler].insert(*it); |
| + } |
| + |
| + // Emit invalidations only for handlers in |handlers_|. |
| + if (handlers_.might_have_observers()) { |
|
msw
2012/08/09 05:20:26
nit: consider making this an early return up top,
akalin
2012/08/10 01:28:08
Done.
|
| + ObserverListBase<SyncNotifierObserver>::Iterator it(handlers_); |
| + SyncNotifierObserver* handler = NULL; |
| + while ((handler = it.GetNext()) != NULL) { |
| + DispatchMap::const_iterator dispatch_it = dispatch_map.find(handler); |
| + if (dispatch_it != dispatch_map.end()) { |
|
msw
2012/08/09 05:20:26
nit: remove unnecessary {}
akalin
2012/08/10 01:28:08
Done.
|
| + handler->OnIncomingNotification(dispatch_it->second, source); |
| + } |
| + } |
| + } |
| +} |
| + |
| +void SyncNotifierRegistrar::EmitOnNotificationsEnabled() { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + FOR_EACH_OBSERVER(SyncNotifierObserver, handlers_, OnNotificationsEnabled()); |
| +} |
| + |
| +void SyncNotifierRegistrar::EmitOnNotificationsDisabled( |
| + NotificationsDisabledReason reason) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + FOR_EACH_OBSERVER(SyncNotifierObserver, handlers_, |
| + OnNotificationsDisabled(reason)); |
| +} |
| + |
| +void SyncNotifierRegistrar::DetachFromThreadForTest() { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + thread_checker_.DetachFromThread(); |
| +} |
| + |
| +SyncNotifierObserver* SyncNotifierRegistrar::ObjectIdToHandler( |
| + const invalidation::ObjectId& id) { |
| + DCHECK(thread_checker_.CalledOnValidThread()); |
| + IdHandlerMap::const_iterator it = id_to_handler_map_.find(id); |
| + return (it == id_to_handler_map_.end()) ? NULL : it->second; |
| +} |
| + |
| +} // namespace syncer |