1 // Copyright 2014 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 "components/invalidation/invalidator_registrar.h" 6 7 #include <cstddef> 8 #include <iterator> 9 #include <utility> 10 11 #include "base/logging.h" 12 #include "components/invalidation/object_id_invalidation_map.h" 13 14 namespace syncer { 15 16 InvalidatorRegistrar::InvalidatorRegistrar() 17 : state_(DEFAULT_INVALIDATION_ERROR) {} 18 19 InvalidatorRegistrar::~InvalidatorRegistrar() { 20 DCHECK(thread_checker_.CalledOnValidThread()); 21 CHECK(handler_to_ids_map_.empty()); 22 } 23 24 void InvalidatorRegistrar::RegisterHandler(InvalidationHandler* handler) { 25 DCHECK(thread_checker_.CalledOnValidThread()); 26 CHECK(handler); 27 CHECK(!handlers_.HasObserver(handler)); 28 handlers_.AddObserver(handler); 29 } 30 31 void InvalidatorRegistrar::UpdateRegisteredIds( 32 InvalidationHandler* handler, 33 const ObjectIdSet& ids) { 34 DCHECK(thread_checker_.CalledOnValidThread()); 35 CHECK(handler); 36 CHECK(handlers_.HasObserver(handler)); 37 38 for (HandlerIdsMap::const_iterator it = handler_to_ids_map_.begin(); 39 it != handler_to_ids_map_.end(); ++it) { 40 if (it->first == handler) { 41 continue; 42 } 43 44 std::vector<invalidation::ObjectId> intersection; 45 std::set_intersection( 46 it->second.begin(), it->second.end(), 47 ids.begin(), ids.end(), 48 std::inserter(intersection, intersection.end()), 49 ObjectIdLessThan()); 50 CHECK(intersection.empty()) 51 << "Duplicate registration: trying to register " 52 << ObjectIdToString(*intersection.begin()) << " for " 53 << handler << " when it's already registered for " 54 << it->first; 55 } 56 57 if (ids.empty()) { 58 handler_to_ids_map_.erase(handler); 59 } else { 60 handler_to_ids_map_[handler] = ids; 61 } 62 } 63 64 void InvalidatorRegistrar::UnregisterHandler(InvalidationHandler* handler) { 65 DCHECK(thread_checker_.CalledOnValidThread()); 66 CHECK(handler); 67 CHECK(handlers_.HasObserver(handler)); 68 handlers_.RemoveObserver(handler); 69 handler_to_ids_map_.erase(handler); 70 } 71 72 ObjectIdSet InvalidatorRegistrar::GetRegisteredIds( 73 InvalidationHandler* handler) const { 74 DCHECK(thread_checker_.CalledOnValidThread()); 75 HandlerIdsMap::const_iterator lookup = handler_to_ids_map_.find(handler); 76 if (lookup != handler_to_ids_map_.end()) { 77 return lookup->second; 78 } else { 79 return ObjectIdSet(); 80 } 81 } 82 83 ObjectIdSet InvalidatorRegistrar::GetAllRegisteredIds() const { 84 DCHECK(thread_checker_.CalledOnValidThread()); 85 ObjectIdSet registered_ids; 86 for (HandlerIdsMap::const_iterator it = handler_to_ids_map_.begin(); 87 it != handler_to_ids_map_.end(); ++it) { 88 registered_ids.insert(it->second.begin(), it->second.end()); 89 } 90 return registered_ids; 91 } 92 93 void InvalidatorRegistrar::DispatchInvalidationsToHandlers( 94 const ObjectIdInvalidationMap& invalidation_map) { 95 DCHECK(thread_checker_.CalledOnValidThread()); 96 // If we have no handlers, there's nothing to do. 97 if (!handlers_.might_have_observers()) { 98 return; 99 } 100 101 for (HandlerIdsMap::iterator it = handler_to_ids_map_.begin(); 102 it != handler_to_ids_map_.end(); ++it) { 103 ObjectIdInvalidationMap to_emit = 104 invalidation_map.GetSubsetWithObjectIds(it->second); 105 if (!to_emit.Empty()) { 106 it->first->OnIncomingInvalidation(to_emit); 107 } 108 } 109 } 110 111 void InvalidatorRegistrar::UpdateInvalidatorState(InvalidatorState state) { 112 DCHECK(thread_checker_.CalledOnValidThread()); 113 DVLOG(1) << "New invalidator state: " << InvalidatorStateToString(state_) 114 << " -> " << InvalidatorStateToString(state); 115 state_ = state; 116 FOR_EACH_OBSERVER(InvalidationHandler, handlers_, 117 OnInvalidatorStateChange(state)); 118 } 119 120 InvalidatorState InvalidatorRegistrar::GetInvalidatorState() const { 121 DCHECK(thread_checker_.CalledOnValidThread()); 122 return state_; 123 } 124 125 std::map<std::string, ObjectIdSet> 126 InvalidatorRegistrar::GetSanitizedHandlersIdsMap() { 127 DCHECK(thread_checker_.CalledOnValidThread()); 128 std::map<std::string, ObjectIdSet> clean_handlers_to_ids; 129 for (HandlerIdsMap::const_iterator it = handler_to_ids_map_.begin(); 130 it != handler_to_ids_map_.end(); 131 ++it) { 132 clean_handlers_to_ids[it->first->GetOwnerName()] = ObjectIdSet(it->second); 133 } 134 return clean_handlers_to_ids; 135 } 136 137 bool InvalidatorRegistrar::IsHandlerRegisteredForTest( 138 InvalidationHandler* handler) const { 139 DCHECK(thread_checker_.CalledOnValidThread()); 140 return handlers_.HasObserver(handler); 141 } 142 143 void InvalidatorRegistrar::DetachFromThreadForTest() { 144 DCHECK(thread_checker_.CalledOnValidThread()); 145 thread_checker_.DetachFromThread(); 146 } 147 148 } // namespace syncer 149