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