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