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 "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