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::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