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.
5 #include "sync/internal_api/debug_info_event_listener.h"
7 #include "sync/util/cryptographer.h"
11 using sessions::SyncSessionSnapshot
;
13 DebugInfoEventListener::DebugInfoEventListener()
14 : events_dropped_(false),
15 cryptographer_has_pending_keys_(false),
16 cryptographer_ready_(false),
17 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
20 DebugInfoEventListener::~DebugInfoEventListener() {
23 void DebugInfoEventListener::OnSyncCycleCompleted(
24 const SyncSessionSnapshot
& snapshot
) {
25 DCHECK(thread_checker_
.CalledOnValidThread());
26 sync_pb::DebugEventInfo event_info
;
27 sync_pb::SyncCycleCompletedEventInfo
* sync_completed_event_info
=
28 event_info
.mutable_sync_cycle_completed_event_info();
30 sync_completed_event_info
->set_num_encryption_conflicts(
31 snapshot
.num_encryption_conflicts());
32 sync_completed_event_info
->set_num_hierarchy_conflicts(
33 snapshot
.num_hierarchy_conflicts());
34 sync_completed_event_info
->set_num_server_conflicts(
35 snapshot
.num_server_conflicts());
37 sync_completed_event_info
->set_num_updates_downloaded(
38 snapshot
.model_neutral_state().num_updates_downloaded_total
);
39 sync_completed_event_info
->set_num_reflected_updates_downloaded(
40 snapshot
.model_neutral_state().num_reflected_updates_downloaded_total
);
41 sync_completed_event_info
->mutable_caller_info()->set_source(
42 snapshot
.source().updates_source
);
43 sync_completed_event_info
->mutable_caller_info()->set_notifications_enabled(
44 snapshot
.notifications_enabled());
46 // Log the sources and per-type payloads coalesced into this session.
47 const std::vector
<sessions::SyncSourceInfo
>& snap_sources
=
48 snapshot
.debug_info_sources_list();
49 for (std::vector
<sessions::SyncSourceInfo
>::const_iterator source_iter
=
50 snap_sources
.begin(); source_iter
!= snap_sources
.end(); ++source_iter
) {
51 sync_pb::SourceInfo
* pb_source_info
=
52 sync_completed_event_info
->add_source_info();
54 pb_source_info
->set_source(source_iter
->updates_source
);
56 for (ModelTypeInvalidationMap::const_iterator type_iter
=
57 source_iter
->types
.begin();
58 type_iter
!= source_iter
->types
.end(); ++type_iter
) {
59 sync_pb::TypeHint
* pb_type_hint
= pb_source_info
->add_type_hint();
60 pb_type_hint
->set_data_type_id(
61 GetSpecificsFieldNumberFromModelType(type_iter
->first
));
62 pb_type_hint
->set_has_valid_hint(!type_iter
->second
.payload
.empty());
66 AddEventToQueue(event_info
);
69 void DebugInfoEventListener::OnInitializationComplete(
70 const WeakHandle
<JsBackend
>& js_backend
,
71 const WeakHandle
<DataTypeDebugInfoListener
>& debug_listener
,
72 bool success
, ModelTypeSet restored_types
) {
73 DCHECK(thread_checker_
.CalledOnValidThread());
74 CreateAndAddEvent(sync_pb::DebugEventInfo::INITIALIZATION_COMPLETE
);
77 void DebugInfoEventListener::OnConnectionStatusChange(
78 ConnectionStatus status
) {
79 DCHECK(thread_checker_
.CalledOnValidThread());
80 CreateAndAddEvent(sync_pb::DebugEventInfo::CONNECTION_STATUS_CHANGE
);
83 void DebugInfoEventListener::OnPassphraseRequired(
84 PassphraseRequiredReason reason
,
85 const sync_pb::EncryptedData
& pending_keys
) {
86 DCHECK(thread_checker_
.CalledOnValidThread());
87 CreateAndAddEvent(sync_pb::DebugEventInfo::PASSPHRASE_REQUIRED
);
90 void DebugInfoEventListener::OnPassphraseAccepted() {
91 DCHECK(thread_checker_
.CalledOnValidThread());
92 CreateAndAddEvent(sync_pb::DebugEventInfo::PASSPHRASE_ACCEPTED
);
95 void DebugInfoEventListener::OnBootstrapTokenUpdated(
96 const std::string
& bootstrap_token
, BootstrapTokenType type
) {
97 DCHECK(thread_checker_
.CalledOnValidThread());
98 if (type
== PASSPHRASE_BOOTSTRAP_TOKEN
) {
99 CreateAndAddEvent(sync_pb::DebugEventInfo::BOOTSTRAP_TOKEN_UPDATED
);
102 DCHECK_EQ(type
, KEYSTORE_BOOTSTRAP_TOKEN
);
103 CreateAndAddEvent(sync_pb::DebugEventInfo::KEYSTORE_TOKEN_UPDATED
);
106 void DebugInfoEventListener::OnStopSyncingPermanently() {
107 DCHECK(thread_checker_
.CalledOnValidThread());
108 CreateAndAddEvent(sync_pb::DebugEventInfo::STOP_SYNCING_PERMANENTLY
);
111 void DebugInfoEventListener::OnUpdatedToken(const std::string
& token
) {
112 DCHECK(thread_checker_
.CalledOnValidThread());
113 CreateAndAddEvent(sync_pb::DebugEventInfo::UPDATED_TOKEN
);
116 void DebugInfoEventListener::OnEncryptedTypesChanged(
117 ModelTypeSet encrypted_types
,
118 bool encrypt_everything
) {
119 DCHECK(thread_checker_
.CalledOnValidThread());
120 CreateAndAddEvent(sync_pb::DebugEventInfo::ENCRYPTED_TYPES_CHANGED
);
123 void DebugInfoEventListener::OnEncryptionComplete() {
124 DCHECK(thread_checker_
.CalledOnValidThread());
125 CreateAndAddEvent(sync_pb::DebugEventInfo::ENCRYPTION_COMPLETE
);
128 void DebugInfoEventListener::OnCryptographerStateChanged(
129 Cryptographer
* cryptographer
) {
130 DCHECK(thread_checker_
.CalledOnValidThread());
131 cryptographer_has_pending_keys_
= cryptographer
->has_pending_keys();
132 cryptographer_ready_
= cryptographer
->is_ready();
135 void DebugInfoEventListener::OnPassphraseTypeChanged(
137 base::Time explicit_passphrase_time
) {
138 DCHECK(thread_checker_
.CalledOnValidThread());
139 CreateAndAddEvent(sync_pb::DebugEventInfo::PASSPHRASE_TYPE_CHANGED
);
142 void DebugInfoEventListener::OnActionableError(
143 const SyncProtocolError
& sync_error
) {
144 DCHECK(thread_checker_
.CalledOnValidThread());
145 CreateAndAddEvent(sync_pb::DebugEventInfo::ACTIONABLE_ERROR
);
148 void DebugInfoEventListener::OnNudgeFromDatatype(ModelType datatype
) {
149 DCHECK(thread_checker_
.CalledOnValidThread());
150 sync_pb::DebugEventInfo event_info
;
151 event_info
.set_nudging_datatype(
152 GetSpecificsFieldNumberFromModelType(datatype
));
153 AddEventToQueue(event_info
);
156 void DebugInfoEventListener::OnIncomingNotification(
157 const ModelTypeInvalidationMap
& invalidation_map
) {
158 DCHECK(thread_checker_
.CalledOnValidThread());
159 sync_pb::DebugEventInfo event_info
;
160 ModelTypeSet types
= ModelTypeInvalidationMapToSet(invalidation_map
);
162 for (ModelTypeSet::Iterator it
= types
.First(); it
.Good(); it
.Inc()) {
163 event_info
.add_datatypes_notified_from_server(
164 GetSpecificsFieldNumberFromModelType(it
.Get()));
167 AddEventToQueue(event_info
);
170 void DebugInfoEventListener::GetAndClearDebugInfo(
171 sync_pb::DebugInfo
* debug_info
) {
172 DCHECK(thread_checker_
.CalledOnValidThread());
173 DCHECK_LE(events_
.size(), kMaxEntries
);
174 while (!events_
.empty()) {
175 sync_pb::DebugEventInfo
* event_info
= debug_info
->add_events();
176 const sync_pb::DebugEventInfo
& debug_event_info
= events_
.front();
177 event_info
->CopyFrom(debug_event_info
);
181 debug_info
->set_events_dropped(events_dropped_
);
182 debug_info
->set_cryptographer_ready(cryptographer_ready_
);
183 debug_info
->set_cryptographer_has_pending_keys(
184 cryptographer_has_pending_keys_
);
186 events_dropped_
= false;
189 base::WeakPtr
<DataTypeDebugInfoListener
> DebugInfoEventListener::GetWeakPtr() {
190 DCHECK(thread_checker_
.CalledOnValidThread());
191 return weak_ptr_factory_
.GetWeakPtr();
194 void DebugInfoEventListener::OnDataTypeAssociationComplete(
195 const DataTypeAssociationStats
& association_stats
) {
196 DCHECK(thread_checker_
.CalledOnValidThread());
197 DCHECK(ProtocolTypes().Has(association_stats
.model_type
));
198 sync_pb::DebugEventInfo association_event
;
199 sync_pb::DatatypeAssociationStats
* datatype_stats
=
200 association_event
.mutable_datatype_association_stats();
201 datatype_stats
->set_data_type_id(
202 GetSpecificsFieldNumberFromModelType(association_stats
.model_type
));
203 datatype_stats
->set_num_local_items_before_association(
204 association_stats
.num_local_items_before_association
);
205 datatype_stats
->set_num_sync_items_before_association(
206 association_stats
.num_sync_items_before_association
);
207 datatype_stats
->set_num_local_items_after_association(
208 association_stats
.num_local_items_after_association
);
209 datatype_stats
->set_num_sync_items_after_association(
210 association_stats
.num_sync_items_after_association
);
211 datatype_stats
->set_num_local_items_added(
212 association_stats
.num_local_items_added
);
213 datatype_stats
->set_num_local_items_deleted(
214 association_stats
.num_local_items_deleted
);
215 datatype_stats
->set_num_local_items_modified(
216 association_stats
.num_local_items_modified
);
217 datatype_stats
->set_num_sync_items_added(
218 association_stats
.num_sync_items_added
);
219 datatype_stats
->set_num_sync_items_deleted(
220 association_stats
.num_sync_items_deleted
);
221 datatype_stats
->set_num_sync_items_modified(
222 association_stats
.num_sync_items_modified
);
223 datatype_stats
->set_had_error(association_stats
.had_error
);
225 AddEventToQueue(association_event
);
228 void DebugInfoEventListener::OnConfigureComplete() {
229 DCHECK(thread_checker_
.CalledOnValidThread());
230 CreateAndAddEvent(sync_pb::DebugEventInfo::CONFIGURE_COMPLETE
);
233 void DebugInfoEventListener::CreateAndAddEvent(
234 sync_pb::DebugEventInfo::SingletonEventType type
) {
235 DCHECK(thread_checker_
.CalledOnValidThread());
236 sync_pb::DebugEventInfo event_info
;
237 event_info
.set_singleton_event(type
);
238 AddEventToQueue(event_info
);
241 void DebugInfoEventListener::AddEventToQueue(
242 const sync_pb::DebugEventInfo
& event_info
) {
243 DCHECK(thread_checker_
.CalledOnValidThread());
244 if (events_
.size() >= kMaxEntries
) {
245 DVLOG(1) << "DebugInfoEventListener::AddEventToQueue Dropping an old event "
246 << "because of full queue";
249 events_dropped_
= true;
251 events_
.push(event_info
);
254 } // namespace syncer