Home | History | Annotate | Download | only in internal_api
      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::SyncEnums::INITIALIZATION_COMPLETE);
     55 }
     56 
     57 void DebugInfoEventListener::OnConnectionStatusChange(
     58     ConnectionStatus status) {
     59   DCHECK(thread_checker_.CalledOnValidThread());
     60   CreateAndAddEvent(sync_pb::SyncEnums::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::SyncEnums::PASSPHRASE_REQUIRED);
     68 }
     69 
     70 void DebugInfoEventListener::OnPassphraseAccepted() {
     71   DCHECK(thread_checker_.CalledOnValidThread());
     72   CreateAndAddEvent(sync_pb::SyncEnums::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::SyncEnums::BOOTSTRAP_TOKEN_UPDATED);
     80     return;
     81   }
     82   DCHECK_EQ(type, KEYSTORE_BOOTSTRAP_TOKEN);
     83   CreateAndAddEvent(sync_pb::SyncEnums::KEYSTORE_TOKEN_UPDATED);
     84 }
     85 
     86 void 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 
     93 void DebugInfoEventListener::OnEncryptionComplete() {
     94   DCHECK(thread_checker_.CalledOnValidThread());
     95   CreateAndAddEvent(sync_pb::SyncEnums::ENCRYPTION_COMPLETE);
     96 }
     97 
     98 void 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 
    105 void 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 
    112 void DebugInfoEventListener::OnActionableError(
    113     const SyncProtocolError& sync_error) {
    114   DCHECK(thread_checker_.CalledOnValidThread());
    115   CreateAndAddEvent(sync_pb::SyncEnums::ACTIONABLE_ERROR);
    116 }
    117 
    118 void DebugInfoEventListener::OnMigrationRequested(ModelTypeSet types) {}
    119 
    120 void DebugInfoEventListener::OnProtocolEvent(const ProtocolEvent& event) {}
    121 
    122 void 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 
    130 void 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 
    147 void DebugInfoEventListener::ClearDebugInfo() {
    148   DCHECK(thread_checker_.CalledOnValidThread());
    149   DCHECK_LE(events_.size(), kMaxEntries);
    150 
    151   events_.clear();
    152   events_dropped_ = false;
    153 }
    154 
    155 base::WeakPtr<DataTypeDebugInfoListener> DebugInfoEventListener::GetWeakPtr() {
    156   DCHECK(thread_checker_.CalledOnValidThread());
    157   return weak_ptr_factory_.GetWeakPtr();
    158 }
    159 
    160 void 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 
    232 void 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 
    240 void 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