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