Home | History | Annotate | Download | only in invalidation
      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 "sync/notifier/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(!handlers_.might_have_observers());
     22   CHECK(handler_to_ids_map_.empty());
     23 }
     24 
     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 
     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 
     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 
     73 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 
     84 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 
     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 
    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 
    121 InvalidatorState InvalidatorRegistrar::GetInvalidatorState() const {
    122   DCHECK(thread_checker_.CalledOnValidThread());
    123   return state_;
    124 }
    125 
    126 std::map<std::string, ObjectIdSet>
    127 InvalidatorRegistrar::GetSanitizedHandlersIdsMap() {
    128   DCHECK(thread_checker_.CalledOnValidThread());
    129   std::map<std::string, ObjectIdSet> clean_handlers_to_ids;
    130   for (HandlerIdsMap::const_iterator it = handler_to_ids_map_.begin();
    131        it != handler_to_ids_map_.end();
    132        ++it) {
    133     clean_handlers_to_ids[it->first->GetOwnerName()] = ObjectIdSet(it->second);
    134   }
    135   return clean_handlers_to_ids;
    136 }
    137 
    138 bool InvalidatorRegistrar::IsHandlerRegisteredForTest(
    139     InvalidationHandler* handler) const {
    140   DCHECK(thread_checker_.CalledOnValidThread());
    141   return handlers_.HasObserver(handler);
    142 }
    143 
    144 void InvalidatorRegistrar::DetachFromThreadForTest() {
    145   DCHECK(thread_checker_.CalledOnValidThread());
    146   thread_checker_.DetachFromThread();
    147 }
    148 
    149 }  // namespace syncer
    150