• 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/internal_api/debug_info_event_listener.h"
6 
7 #include "sync/notifier/object_id_invalidation_map.h"
8 #include "sync/util/cryptographer.h"
9 
10 namespace syncer {
11 
12 using sessions::SyncSessionSnapshot;
13 
DebugInfoEventListener()14 DebugInfoEventListener::DebugInfoEventListener()
15     : events_dropped_(false),
16       cryptographer_has_pending_keys_(false),
17       cryptographer_ready_(false),
18       weak_ptr_factory_(this) {
19 }
20 
~DebugInfoEventListener()21 DebugInfoEventListener::~DebugInfoEventListener() {
22 }
23 
OnSyncCycleCompleted(const SyncSessionSnapshot & snapshot)24 void DebugInfoEventListener::OnSyncCycleCompleted(
25     const SyncSessionSnapshot& snapshot) {
26   DCHECK(thread_checker_.CalledOnValidThread());
27   sync_pb::DebugEventInfo event_info;
28   sync_pb::SyncCycleCompletedEventInfo* sync_completed_event_info =
29       event_info.mutable_sync_cycle_completed_event_info();
30 
31   sync_completed_event_info->set_num_encryption_conflicts(
32       snapshot.num_encryption_conflicts());
33   sync_completed_event_info->set_num_hierarchy_conflicts(
34       snapshot.num_hierarchy_conflicts());
35   sync_completed_event_info->set_num_server_conflicts(
36       snapshot.num_server_conflicts());
37 
38   sync_completed_event_info->set_num_updates_downloaded(
39       snapshot.model_neutral_state().num_updates_downloaded_total);
40   sync_completed_event_info->set_num_reflected_updates_downloaded(
41       snapshot.model_neutral_state().num_reflected_updates_downloaded_total);
42   sync_completed_event_info->mutable_caller_info()->set_source(
43       snapshot.legacy_updates_source());
44   sync_completed_event_info->mutable_caller_info()->set_notifications_enabled(
45       snapshot.notifications_enabled());
46 
47   AddEventToQueue(event_info);
48 }
49 
OnInitializationComplete(const WeakHandle<JsBackend> & js_backend,const WeakHandle<DataTypeDebugInfoListener> & debug_listener,bool success,ModelTypeSet restored_types)50 void DebugInfoEventListener::OnInitializationComplete(
51     const WeakHandle<JsBackend>& js_backend,
52     const WeakHandle<DataTypeDebugInfoListener>& debug_listener,
53     bool success, ModelTypeSet restored_types) {
54   DCHECK(thread_checker_.CalledOnValidThread());
55   CreateAndAddEvent(sync_pb::SyncEnums::INITIALIZATION_COMPLETE);
56 }
57 
OnConnectionStatusChange(ConnectionStatus status)58 void DebugInfoEventListener::OnConnectionStatusChange(
59     ConnectionStatus status) {
60   DCHECK(thread_checker_.CalledOnValidThread());
61   CreateAndAddEvent(sync_pb::SyncEnums::CONNECTION_STATUS_CHANGE);
62 }
63 
OnPassphraseRequired(PassphraseRequiredReason reason,const sync_pb::EncryptedData & pending_keys)64 void DebugInfoEventListener::OnPassphraseRequired(
65     PassphraseRequiredReason reason,
66     const sync_pb::EncryptedData& pending_keys) {
67   DCHECK(thread_checker_.CalledOnValidThread());
68   CreateAndAddEvent(sync_pb::SyncEnums::PASSPHRASE_REQUIRED);
69 }
70 
OnPassphraseAccepted()71 void DebugInfoEventListener::OnPassphraseAccepted() {
72   DCHECK(thread_checker_.CalledOnValidThread());
73   CreateAndAddEvent(sync_pb::SyncEnums::PASSPHRASE_ACCEPTED);
74 }
75 
OnBootstrapTokenUpdated(const std::string & bootstrap_token,BootstrapTokenType type)76 void DebugInfoEventListener::OnBootstrapTokenUpdated(
77     const std::string& bootstrap_token, BootstrapTokenType type) {
78   DCHECK(thread_checker_.CalledOnValidThread());
79   if (type == PASSPHRASE_BOOTSTRAP_TOKEN) {
80     CreateAndAddEvent(sync_pb::SyncEnums::BOOTSTRAP_TOKEN_UPDATED);
81     return;
82   }
83   DCHECK_EQ(type, KEYSTORE_BOOTSTRAP_TOKEN);
84   CreateAndAddEvent(sync_pb::SyncEnums::KEYSTORE_TOKEN_UPDATED);
85 }
86 
OnEncryptedTypesChanged(ModelTypeSet encrypted_types,bool encrypt_everything)87 void DebugInfoEventListener::OnEncryptedTypesChanged(
88     ModelTypeSet encrypted_types,
89     bool encrypt_everything) {
90   DCHECK(thread_checker_.CalledOnValidThread());
91   CreateAndAddEvent(sync_pb::SyncEnums::ENCRYPTED_TYPES_CHANGED);
92 }
93 
OnEncryptionComplete()94 void DebugInfoEventListener::OnEncryptionComplete() {
95   DCHECK(thread_checker_.CalledOnValidThread());
96   CreateAndAddEvent(sync_pb::SyncEnums::ENCRYPTION_COMPLETE);
97 }
98 
OnCryptographerStateChanged(Cryptographer * cryptographer)99 void DebugInfoEventListener::OnCryptographerStateChanged(
100     Cryptographer* cryptographer) {
101   DCHECK(thread_checker_.CalledOnValidThread());
102   cryptographer_has_pending_keys_ = cryptographer->has_pending_keys();
103   cryptographer_ready_ = cryptographer->is_ready();
104 }
105 
OnPassphraseTypeChanged(PassphraseType type,base::Time explicit_passphrase_time)106 void DebugInfoEventListener::OnPassphraseTypeChanged(
107     PassphraseType type,
108     base::Time explicit_passphrase_time) {
109   DCHECK(thread_checker_.CalledOnValidThread());
110   CreateAndAddEvent(sync_pb::SyncEnums::PASSPHRASE_TYPE_CHANGED);
111 }
112 
OnActionableError(const SyncProtocolError & sync_error)113 void DebugInfoEventListener::OnActionableError(
114     const SyncProtocolError& sync_error) {
115   DCHECK(thread_checker_.CalledOnValidThread());
116   CreateAndAddEvent(sync_pb::SyncEnums::ACTIONABLE_ERROR);
117 }
118 
OnMigrationRequested(ModelTypeSet types)119 void DebugInfoEventListener::OnMigrationRequested(ModelTypeSet types) {}
120 
OnProtocolEvent(const ProtocolEvent & event)121 void DebugInfoEventListener::OnProtocolEvent(const ProtocolEvent& event) {}
122 
OnNudgeFromDatatype(ModelType datatype)123 void DebugInfoEventListener::OnNudgeFromDatatype(ModelType datatype) {
124   DCHECK(thread_checker_.CalledOnValidThread());
125   sync_pb::DebugEventInfo event_info;
126   event_info.set_nudging_datatype(
127       GetSpecificsFieldNumberFromModelType(datatype));
128   AddEventToQueue(event_info);
129 }
130 
OnIncomingNotification(const ObjectIdInvalidationMap & invalidation_map)131 void DebugInfoEventListener::OnIncomingNotification(
132     const ObjectIdInvalidationMap& invalidation_map) {
133   DCHECK(thread_checker_.CalledOnValidThread());
134   sync_pb::DebugEventInfo event_info;
135   ModelTypeSet types =
136       ObjectIdSetToModelTypeSet(invalidation_map.GetObjectIds());
137 
138   for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
139     event_info.add_datatypes_notified_from_server(
140         GetSpecificsFieldNumberFromModelType(it.Get()));
141   }
142 
143   AddEventToQueue(event_info);
144 }
145 
GetDebugInfo(sync_pb::DebugInfo * debug_info)146 void DebugInfoEventListener::GetDebugInfo(sync_pb::DebugInfo* debug_info) {
147   DCHECK(thread_checker_.CalledOnValidThread());
148   DCHECK_LE(events_.size(), kMaxEntries);
149 
150   for (DebugEventInfoQueue::const_iterator iter = events_.begin();
151        iter != events_.end();
152        ++iter) {
153     sync_pb::DebugEventInfo* event_info = debug_info->add_events();
154     event_info->CopyFrom(*iter);
155   }
156 
157   debug_info->set_events_dropped(events_dropped_);
158   debug_info->set_cryptographer_ready(cryptographer_ready_);
159   debug_info->set_cryptographer_has_pending_keys(
160       cryptographer_has_pending_keys_);
161 }
162 
ClearDebugInfo()163 void DebugInfoEventListener::ClearDebugInfo() {
164   DCHECK(thread_checker_.CalledOnValidThread());
165   DCHECK_LE(events_.size(), kMaxEntries);
166 
167   events_.clear();
168   events_dropped_ = false;
169 }
170 
GetWeakPtr()171 base::WeakPtr<DataTypeDebugInfoListener> DebugInfoEventListener::GetWeakPtr() {
172   DCHECK(thread_checker_.CalledOnValidThread());
173   return weak_ptr_factory_.GetWeakPtr();
174 }
175 
OnDataTypeConfigureComplete(const std::vector<DataTypeConfigurationStats> & configuration_stats)176 void DebugInfoEventListener::OnDataTypeConfigureComplete(
177     const std::vector<DataTypeConfigurationStats>& configuration_stats) {
178   DCHECK(thread_checker_.CalledOnValidThread());
179 
180   for (size_t i = 0; i < configuration_stats.size(); ++i) {
181     DCHECK(ProtocolTypes().Has(configuration_stats[i].model_type));
182     const DataTypeAssociationStats& association_stats =
183         configuration_stats[i].association_stats;
184 
185     sync_pb::DebugEventInfo association_event;
186     sync_pb::DatatypeAssociationStats* datatype_stats =
187         association_event.mutable_datatype_association_stats();
188     datatype_stats->set_data_type_id(
189         GetSpecificsFieldNumberFromModelType(
190             configuration_stats[i].model_type));
191     datatype_stats->set_num_local_items_before_association(
192         association_stats.num_local_items_before_association);
193     datatype_stats->set_num_sync_items_before_association(
194         association_stats.num_sync_items_before_association);
195     datatype_stats->set_num_local_items_after_association(
196         association_stats.num_local_items_after_association);
197     datatype_stats->set_num_sync_items_after_association(
198         association_stats.num_sync_items_after_association);
199     datatype_stats->set_num_local_items_added(
200         association_stats.num_local_items_added);
201     datatype_stats->set_num_local_items_deleted(
202         association_stats.num_local_items_deleted);
203     datatype_stats->set_num_local_items_modified(
204         association_stats.num_local_items_modified);
205     datatype_stats->set_num_sync_items_added(
206         association_stats.num_sync_items_added);
207     datatype_stats->set_num_sync_items_deleted(
208         association_stats.num_sync_items_deleted);
209     datatype_stats->set_num_sync_items_modified(
210         association_stats.num_sync_items_modified);
211     datatype_stats->set_local_version_pre_association(
212         association_stats.local_version_pre_association);
213     datatype_stats->set_sync_version_pre_association(
214         association_stats.sync_version_pre_association);
215     datatype_stats->set_had_error(association_stats.had_error);
216     datatype_stats->set_association_wait_time_for_same_priority_us(
217           association_stats.association_wait_time.InMicroseconds());
218     datatype_stats->set_association_time_us(
219         association_stats.association_time.InMicroseconds());
220     datatype_stats->set_download_wait_time_us(
221         configuration_stats[i].download_wait_time.InMicroseconds());
222     datatype_stats->set_download_time_us(
223         configuration_stats[i].download_time.InMicroseconds());
224     datatype_stats->set_association_wait_time_for_high_priority_us(
225         configuration_stats[i].association_wait_time_for_high_priority
226             .InMicroseconds());
227 
228     for (ModelTypeSet::Iterator it =
229              configuration_stats[i].high_priority_types_configured_before
230                  .First();
231          it.Good(); it.Inc()) {
232       datatype_stats->add_high_priority_type_configured_before(
233           GetSpecificsFieldNumberFromModelType(it.Get()));
234     }
235 
236     for (ModelTypeSet::Iterator it =
237              configuration_stats[i].same_priority_types_configured_before
238                  .First();
239         it.Good(); it.Inc()) {
240       datatype_stats->add_same_priority_type_configured_before(
241           GetSpecificsFieldNumberFromModelType(it.Get()));
242     }
243 
244     AddEventToQueue(association_event);
245   }
246 }
247 
CreateAndAddEvent(sync_pb::SyncEnums::SingletonDebugEventType type)248 void DebugInfoEventListener::CreateAndAddEvent(
249     sync_pb::SyncEnums::SingletonDebugEventType type) {
250   DCHECK(thread_checker_.CalledOnValidThread());
251   sync_pb::DebugEventInfo event_info;
252   event_info.set_singleton_event(type);
253   AddEventToQueue(event_info);
254 }
255 
AddEventToQueue(const sync_pb::DebugEventInfo & event_info)256 void DebugInfoEventListener::AddEventToQueue(
257   const sync_pb::DebugEventInfo& event_info) {
258   DCHECK(thread_checker_.CalledOnValidThread());
259   if (events_.size() >= kMaxEntries) {
260     DVLOG(1) << "DebugInfoEventListener::AddEventToQueue Dropping an old event "
261              << "because of full queue";
262 
263     events_.pop_front();
264     events_dropped_ = true;
265   }
266   events_.push_back(event_info);
267 }
268 
269 }  // namespace syncer
270