15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file.
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
50de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "components/invalidation/invalidation_logger.h"
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/values.h"
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/invalidation/invalidation_handler.h"
100de6073388f4e2780db8536178b129cd8f6ab386Torne (Richard Coles)#include "components/invalidation/invalidation_logger_observer.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace invalidation {
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class InvalidationLoggerObserver;
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)InvalidationLogger::InvalidationLogger()
16c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    : last_invalidator_state_(syncer::TRANSIENT_INVALIDATION_ERROR),
17c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      last_invalidator_state_timestamp_(base::Time::Now()) { }
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)InvalidationLogger::~InvalidationLogger() {}
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InvalidationLogger::OnRegistration(const std::string& registrar_name) {
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  registered_handlers_.insert(registrar_name);
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EmitRegisteredHandlers();
245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InvalidationLogger::OnUnregistration(const std::string& registrar_name) {
27a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  DCHECK(registered_handlers_.find(registrar_name) !=
28a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)         registered_handlers_.end());
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  std::multiset<std::string>::iterator it =
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      registered_handlers_.find(registrar_name);
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  // Delete only one instance of registrar_name.
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  registered_handlers_.erase(it);
33a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EmitRegisteredHandlers();
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
36a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InvalidationLogger::EmitRegisteredHandlers() {
37a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  FOR_EACH_OBSERVER(InvalidationLoggerObserver, observer_list_,
38a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                    OnRegistrationChange(registered_handlers_));
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InvalidationLogger::OnStateChange(
42c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    const syncer::InvalidatorState& new_state) {
43c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  // Prevent spurious same state emissions from updating the timestamp.
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  if (new_state != last_invalidator_state_)
45c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    last_invalidator_state_timestamp_ = base::Time::Now();
46c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  last_invalidator_state_ = new_state;
475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EmitState();
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InvalidationLogger::EmitState() {
515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FOR_EACH_OBSERVER(InvalidationLoggerObserver,
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                    observer_list_,
53c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                    OnStateChange(last_invalidator_state_,
54c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch                                  last_invalidator_state_timestamp_));
555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InvalidationLogger::OnUpdateIds(
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    std::map<std::string, syncer::ObjectIdSet> updated_ids) {
59a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (std::map<std::string, syncer::ObjectIdSet>::const_iterator it =
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       updated_ids.begin(); it != updated_ids.end(); ++it) {
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    latest_ids_[it->first] = syncer::ObjectIdSet(it->second);
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EmitUpdatedIds();
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
65a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
66a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InvalidationLogger::EmitUpdatedIds() {
67a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  for (std::map<std::string, syncer::ObjectIdSet>::const_iterator it =
68a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)       latest_ids_.begin(); it != latest_ids_.end(); ++it) {
69e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    const syncer::ObjectIdSet& object_ids_for_handler = it->second;
70e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    syncer::ObjectIdCountMap per_object_invalidation_count;
71e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    for (syncer::ObjectIdSet::const_iterator oid_it =
72e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch             object_ids_for_handler.begin();
73e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch         oid_it != object_ids_for_handler.end();
74e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch         ++oid_it) {
75e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch      per_object_invalidation_count[*oid_it] = invalidation_count_[*oid_it];
76e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    }
77a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    FOR_EACH_OBSERVER(InvalidationLoggerObserver,
78a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      observer_list_,
79e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch                      OnUpdateIds(it->first, per_object_invalidation_count));
80a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  }
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InvalidationLogger::OnDebugMessage(const base::DictionaryValue& details) {
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FOR_EACH_OBSERVER(
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      InvalidationLoggerObserver, observer_list_, OnDebugMessage(details));
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InvalidationLogger::OnInvalidation(
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const syncer::ObjectIdInvalidationMap& details) {
90e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  std::vector<syncer::Invalidation> internal_invalidations;
91e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  details.GetAllInvalidations(&internal_invalidations);
92e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  for (std::vector<syncer::Invalidation>::const_iterator it =
93e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch           internal_invalidations.begin();
94e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch       it != internal_invalidations.end();
95e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch       ++it) {
96e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch    invalidation_count_[it->object_id()]++;
97e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch  }
985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  FOR_EACH_OBSERVER(
995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      InvalidationLoggerObserver, observer_list_, OnInvalidation(details));
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void InvalidationLogger::EmitContent() {
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EmitState();
104a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EmitUpdatedIds();
105a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  EmitRegisteredHandlers();
1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InvalidationLogger::RegisterObserver(
1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    InvalidationLoggerObserver* debug_observer) {
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  observer_list_.AddObserver(debug_observer);
1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)void InvalidationLogger::UnregisterObserver(
1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    InvalidationLoggerObserver* debug_observer) {
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  observer_list_.RemoveObserver(debug_observer);
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
117a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)bool InvalidationLogger::IsObserverRegistered(
119a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    InvalidationLoggerObserver* debug_observer) {
120a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return observer_list_.HasObserver(debug_observer);
121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
1225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}  // namespace invalidation
123