• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
InvalidatorRegistrar()16 InvalidatorRegistrar::InvalidatorRegistrar()
17     : state_(DEFAULT_INVALIDATION_ERROR) {}
18 
~InvalidatorRegistrar()19 InvalidatorRegistrar::~InvalidatorRegistrar() {
20   DCHECK(thread_checker_.CalledOnValidThread());
21   CHECK(handler_to_ids_map_.empty());
22 }
23 
RegisterHandler(InvalidationHandler * handler)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 
UpdateRegisteredIds(InvalidationHandler * handler,const ObjectIdSet & ids)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 
UnregisterHandler(InvalidationHandler * handler)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 
GetRegisteredIds(InvalidationHandler * handler) const72 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 
GetAllRegisteredIds() const83 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 
DispatchInvalidationsToHandlers(const ObjectIdInvalidationMap & invalidation_map)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 
UpdateInvalidatorState(InvalidatorState state)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 
GetInvalidatorState() const120 InvalidatorState InvalidatorRegistrar::GetInvalidatorState() const {
121   DCHECK(thread_checker_.CalledOnValidThread());
122   return state_;
123 }
124 
125 std::map<std::string, ObjectIdSet>
GetSanitizedHandlersIdsMap()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 
IsHandlerRegisteredForTest(InvalidationHandler * handler) const137 bool InvalidatorRegistrar::IsHandlerRegisteredForTest(
138     InvalidationHandler* handler) const {
139   DCHECK(thread_checker_.CalledOnValidThread());
140   return handlers_.HasObserver(handler);
141 }
142 
DetachFromThreadForTest()143 void InvalidatorRegistrar::DetachFromThreadForTest() {
144   DCHECK(thread_checker_.CalledOnValidThread());
145   thread_checker_.DetachFromThread();
146 }
147 
148 }  // namespace syncer
149