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/notifier/object_id_invalidation_map.h"
8 #include "sync/util/cryptographer.h"
12 using sessions::SyncSessionSnapshot;
14 DebugInfoEventListener::DebugInfoEventListener()
15 : events_dropped_(false),
16 cryptographer_has_pending_keys_(false),
17 cryptographer_ready_(false),
18 weak_ptr_factory_(this) {
21 DebugInfoEventListener::~DebugInfoEventListener() {
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();
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());
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());
47 AddEventToQueue(event_info);
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::DebugEventInfo::INITIALIZATION_COMPLETE);
58 void DebugInfoEventListener::OnConnectionStatusChange(
59 ConnectionStatus status) {
60 DCHECK(thread_checker_.CalledOnValidThread());
61 CreateAndAddEvent(sync_pb::DebugEventInfo::CONNECTION_STATUS_CHANGE);
64 void DebugInfoEventListener::OnPassphraseRequired(
65 PassphraseRequiredReason reason,
66 const sync_pb::EncryptedData& pending_keys) {
67 DCHECK(thread_checker_.CalledOnValidThread());
68 CreateAndAddEvent(sync_pb::DebugEventInfo::PASSPHRASE_REQUIRED);
71 void DebugInfoEventListener::OnPassphraseAccepted() {
72 DCHECK(thread_checker_.CalledOnValidThread());
73 CreateAndAddEvent(sync_pb::DebugEventInfo::PASSPHRASE_ACCEPTED);
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::DebugEventInfo::BOOTSTRAP_TOKEN_UPDATED);
83 DCHECK_EQ(type, KEYSTORE_BOOTSTRAP_TOKEN);
84 CreateAndAddEvent(sync_pb::DebugEventInfo::KEYSTORE_TOKEN_UPDATED);
87 void DebugInfoEventListener::OnStopSyncingPermanently() {
88 DCHECK(thread_checker_.CalledOnValidThread());
89 CreateAndAddEvent(sync_pb::DebugEventInfo::STOP_SYNCING_PERMANENTLY);
92 void DebugInfoEventListener::OnEncryptedTypesChanged(
93 ModelTypeSet encrypted_types,
94 bool encrypt_everything) {
95 DCHECK(thread_checker_.CalledOnValidThread());
96 CreateAndAddEvent(sync_pb::DebugEventInfo::ENCRYPTED_TYPES_CHANGED);
99 void DebugInfoEventListener::OnEncryptionComplete() {
100 DCHECK(thread_checker_.CalledOnValidThread());
101 CreateAndAddEvent(sync_pb::DebugEventInfo::ENCRYPTION_COMPLETE);
104 void DebugInfoEventListener::OnCryptographerStateChanged(
105 Cryptographer* cryptographer) {
106 DCHECK(thread_checker_.CalledOnValidThread());
107 cryptographer_has_pending_keys_ = cryptographer->has_pending_keys();
108 cryptographer_ready_ = cryptographer->is_ready();
111 void DebugInfoEventListener::OnPassphraseTypeChanged(
113 base::Time explicit_passphrase_time) {
114 DCHECK(thread_checker_.CalledOnValidThread());
115 CreateAndAddEvent(sync_pb::DebugEventInfo::PASSPHRASE_TYPE_CHANGED);
118 void DebugInfoEventListener::OnActionableError(
119 const SyncProtocolError& sync_error) {
120 DCHECK(thread_checker_.CalledOnValidThread());
121 CreateAndAddEvent(sync_pb::DebugEventInfo::ACTIONABLE_ERROR);
124 void DebugInfoEventListener::OnNudgeFromDatatype(ModelType datatype) {
125 DCHECK(thread_checker_.CalledOnValidThread());
126 sync_pb::DebugEventInfo event_info;
127 event_info.set_nudging_datatype(
128 GetSpecificsFieldNumberFromModelType(datatype));
129 AddEventToQueue(event_info);
132 void DebugInfoEventListener::OnIncomingNotification(
133 const ObjectIdInvalidationMap& invalidation_map) {
134 DCHECK(thread_checker_.CalledOnValidThread());
135 sync_pb::DebugEventInfo event_info;
137 ObjectIdSetToModelTypeSet(invalidation_map.GetObjectIds());
139 for (ModelTypeSet::Iterator it = types.First(); it.Good(); it.Inc()) {
140 event_info.add_datatypes_notified_from_server(
141 GetSpecificsFieldNumberFromModelType(it.Get()));
144 AddEventToQueue(event_info);
147 void DebugInfoEventListener::GetAndClearDebugInfo(
148 sync_pb::DebugInfo* debug_info) {
149 DCHECK(thread_checker_.CalledOnValidThread());
150 DCHECK_LE(events_.size(), kMaxEntries);
151 while (!events_.empty()) {
152 sync_pb::DebugEventInfo* event_info = debug_info->add_events();
153 const sync_pb::DebugEventInfo& debug_event_info = events_.front();
154 event_info->CopyFrom(debug_event_info);
158 debug_info->set_events_dropped(events_dropped_);
159 debug_info->set_cryptographer_ready(cryptographer_ready_);
160 debug_info->set_cryptographer_has_pending_keys(
161 cryptographer_has_pending_keys_);
163 events_dropped_ = false;
166 base::WeakPtr<DataTypeDebugInfoListener> DebugInfoEventListener::GetWeakPtr() {
167 DCHECK(thread_checker_.CalledOnValidThread());
168 return weak_ptr_factory_.GetWeakPtr();
171 void DebugInfoEventListener::OnDataTypeConfigureComplete(
172 const std::vector<DataTypeConfigurationStats>& configuration_stats) {
173 DCHECK(thread_checker_.CalledOnValidThread());
175 for (size_t i = 0; i < configuration_stats.size(); ++i) {
176 DCHECK(ProtocolTypes().Has(configuration_stats[i].model_type));
177 const DataTypeAssociationStats& association_stats =
178 configuration_stats[i].association_stats;
180 sync_pb::DebugEventInfo association_event;
181 sync_pb::DatatypeAssociationStats* datatype_stats =
182 association_event.mutable_datatype_association_stats();
183 datatype_stats->set_data_type_id(
184 GetSpecificsFieldNumberFromModelType(
185 configuration_stats[i].model_type));
186 datatype_stats->set_num_local_items_before_association(
187 association_stats.num_local_items_before_association);
188 datatype_stats->set_num_sync_items_before_association(
189 association_stats.num_sync_items_before_association);
190 datatype_stats->set_num_local_items_after_association(
191 association_stats.num_local_items_after_association);
192 datatype_stats->set_num_sync_items_after_association(
193 association_stats.num_sync_items_after_association);
194 datatype_stats->set_num_local_items_added(
195 association_stats.num_local_items_added);
196 datatype_stats->set_num_local_items_deleted(
197 association_stats.num_local_items_deleted);
198 datatype_stats->set_num_local_items_modified(
199 association_stats.num_local_items_modified);
200 datatype_stats->set_num_sync_items_added(
201 association_stats.num_sync_items_added);
202 datatype_stats->set_num_sync_items_deleted(
203 association_stats.num_sync_items_deleted);
204 datatype_stats->set_num_sync_items_modified(
205 association_stats.num_sync_items_modified);
206 datatype_stats->set_local_version_pre_association(
207 association_stats.local_version_pre_association);
208 datatype_stats->set_sync_version_pre_association(
209 association_stats.sync_version_pre_association);
210 datatype_stats->set_had_error(association_stats.had_error);
211 datatype_stats->set_association_wait_time_for_same_priority_us(
212 association_stats.association_wait_time.InMicroseconds());
213 datatype_stats->set_association_time_us(
214 association_stats.association_time.InMicroseconds());
215 datatype_stats->set_download_wait_time_us(
216 configuration_stats[i].download_wait_time.InMicroseconds());
217 datatype_stats->set_download_time_us(
218 configuration_stats[i].download_time.InMicroseconds());
219 datatype_stats->set_association_wait_time_for_high_priority_us(
220 configuration_stats[i].association_wait_time_for_high_priority
223 for (ModelTypeSet::Iterator it =
224 configuration_stats[i].high_priority_types_configured_before
226 it.Good(); it.Inc()) {
227 datatype_stats->add_high_priority_type_configured_before(
228 GetSpecificsFieldNumberFromModelType(it.Get()));
231 for (ModelTypeSet::Iterator it =
232 configuration_stats[i].same_priority_types_configured_before
234 it.Good(); it.Inc()) {
235 datatype_stats->add_same_priority_type_configured_before(
236 GetSpecificsFieldNumberFromModelType(it.Get()));
239 AddEventToQueue(association_event);
243 void DebugInfoEventListener::CreateAndAddEvent(
244 sync_pb::DebugEventInfo::SingletonEventType type) {
245 DCHECK(thread_checker_.CalledOnValidThread());
246 sync_pb::DebugEventInfo event_info;
247 event_info.set_singleton_event(type);
248 AddEventToQueue(event_info);
251 void DebugInfoEventListener::AddEventToQueue(
252 const sync_pb::DebugEventInfo& event_info) {
253 DCHECK(thread_checker_.CalledOnValidThread());
254 if (events_.size() >= kMaxEntries) {
255 DVLOG(1) << "DebugInfoEventListener::AddEventToQueue Dropping an old event "
256 << "because of full queue";
259 events_dropped_ = true;
261 events_.push(event_info);
264 } // namespace syncer