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/engine/all_status.h" 6 7 #include <algorithm> 8 9 #include "base/logging.h" 10 #include "base/port.h" 11 #include "sync/engine/net/server_connection_manager.h" 12 #include "sync/internal_api/public/base/model_type.h" 13 14 namespace syncer { 15 16 AllStatus::AllStatus() { 17 status_.notifications_enabled = false; 18 status_.cryptographer_ready = false; 19 status_.crypto_has_pending_keys = false; 20 } 21 22 AllStatus::~AllStatus() { 23 } 24 25 SyncStatus AllStatus::CreateBlankStatus() const { 26 // Status is initialized with the previous status value. Variables 27 // whose values accumulate (e.g. lifetime counters like updates_received) 28 // are not to be cleared here. 29 SyncStatus status = status_; 30 status.encryption_conflicts = 0; 31 status.hierarchy_conflicts = 0; 32 status.server_conflicts = 0; 33 status.committed_count = 0; 34 status.updates_available = 0; 35 return status; 36 } 37 38 SyncStatus AllStatus::CalcSyncing(const SyncEngineEvent &event) const { 39 SyncStatus status = CreateBlankStatus(); 40 const sessions::SyncSessionSnapshot& snapshot = event.snapshot; 41 status.encryption_conflicts = snapshot.num_encryption_conflicts(); 42 status.hierarchy_conflicts = snapshot.num_hierarchy_conflicts(); 43 status.server_conflicts = snapshot.num_server_conflicts(); 44 status.committed_count = 45 snapshot.model_neutral_state().num_successful_commits; 46 47 if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_BEGIN) { 48 status.syncing = true; 49 } else if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED) { 50 status.syncing = false; 51 } 52 53 status.updates_available += snapshot.num_server_changes_remaining(); 54 status.sync_protocol_error = 55 snapshot.model_neutral_state().sync_protocol_error; 56 57 status.num_entries_by_type = snapshot.num_entries_by_type(); 58 status.num_to_delete_entries_by_type = 59 snapshot.num_to_delete_entries_by_type(); 60 61 // Accumulate update count only once per session to avoid double-counting. 62 if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED) { 63 status.updates_received += 64 snapshot.model_neutral_state().num_updates_downloaded_total; 65 status.tombstone_updates_received += 66 snapshot.model_neutral_state().num_tombstone_updates_downloaded_total; 67 status.reflected_updates_received += 68 snapshot.model_neutral_state().num_reflected_updates_downloaded_total; 69 status.num_commits_total += 70 snapshot.model_neutral_state().num_successful_commits; 71 status.num_local_overwrites_total += 72 snapshot.model_neutral_state().num_local_overwrites; 73 status.num_server_overwrites_total += 74 snapshot.model_neutral_state().num_server_overwrites; 75 if (snapshot.model_neutral_state().num_updates_downloaded_total == 0) { 76 ++status.empty_get_updates; 77 } else { 78 ++status.nonempty_get_updates; 79 } 80 if (snapshot.model_neutral_state().num_successful_commits == 0) { 81 ++status.sync_cycles_without_commits; 82 } else { 83 ++status.sync_cycles_with_commits; 84 } 85 if (snapshot.model_neutral_state().num_successful_commits == 0 && 86 snapshot.model_neutral_state().num_updates_downloaded_total == 0) { 87 ++status.useless_sync_cycles; 88 } else { 89 ++status.useful_sync_cycles; 90 } 91 } 92 return status; 93 } 94 95 void AllStatus::OnSyncEngineEvent(const SyncEngineEvent& event) { 96 ScopedStatusLock lock(this); 97 switch (event.what_happened) { 98 case SyncEngineEvent::SYNC_CYCLE_BEGIN: 99 case SyncEngineEvent::STATUS_CHANGED: 100 case SyncEngineEvent::SYNC_CYCLE_ENDED: 101 status_ = CalcSyncing(event); 102 break; 103 case SyncEngineEvent::STOP_SYNCING_PERMANENTLY: 104 case SyncEngineEvent::UPDATED_TOKEN: 105 break; 106 case SyncEngineEvent::ACTIONABLE_ERROR: 107 status_ = CreateBlankStatus(); 108 status_.sync_protocol_error = 109 event.snapshot.model_neutral_state().sync_protocol_error; 110 break; 111 case SyncEngineEvent::RETRY_TIME_CHANGED: 112 status_.retry_time = event.retry_time; 113 break; 114 case SyncEngineEvent::THROTTLED_TYPES_CHANGED: 115 status_.throttled_types = event.throttled_types; 116 break; 117 default: 118 LOG(ERROR) << "Unrecognized Syncer Event: " << event.what_happened; 119 break; 120 } 121 } 122 123 SyncStatus AllStatus::status() const { 124 base::AutoLock lock(mutex_); 125 return status_; 126 } 127 128 void AllStatus::SetNotificationsEnabled(bool notifications_enabled) { 129 ScopedStatusLock lock(this); 130 status_.notifications_enabled = notifications_enabled; 131 } 132 133 void AllStatus::IncrementNotificationsReceived() { 134 ScopedStatusLock lock(this); 135 ++status_.notifications_received; 136 } 137 138 void AllStatus::SetEncryptedTypes(ModelTypeSet types) { 139 ScopedStatusLock lock(this); 140 status_.encrypted_types = types; 141 } 142 143 void AllStatus::SetCryptographerReady(bool ready) { 144 ScopedStatusLock lock(this); 145 status_.cryptographer_ready = ready; 146 } 147 148 void AllStatus::SetCryptoHasPendingKeys(bool has_pending_keys) { 149 ScopedStatusLock lock(this); 150 status_.crypto_has_pending_keys = has_pending_keys; 151 } 152 153 void AllStatus::SetPassphraseType(PassphraseType type) { 154 ScopedStatusLock lock(this); 155 status_.passphrase_type = type; 156 } 157 158 void AllStatus::SetHasKeystoreKey(bool has_keystore_key) { 159 ScopedStatusLock lock(this); 160 status_.has_keystore_key = has_keystore_key; 161 } 162 163 void AllStatus::SetKeystoreMigrationTime(const base::Time& migration_time) { 164 ScopedStatusLock lock(this); 165 status_.keystore_migration_time = migration_time; 166 } 167 168 void AllStatus::SetSyncId(const std::string& sync_id) { 169 ScopedStatusLock lock(this); 170 status_.sync_id = sync_id; 171 } 172 173 void AllStatus::SetInvalidatorClientId( 174 const std::string& invalidator_client_id) { 175 ScopedStatusLock lock(this); 176 status_.invalidator_client_id = invalidator_client_id; 177 } 178 179 void AllStatus::IncrementNudgeCounter(NudgeSource source) { 180 ScopedStatusLock lock(this); 181 switch(source) { 182 case NUDGE_SOURCE_LOCAL_REFRESH: 183 status_.nudge_source_local_refresh++; 184 return; 185 case NUDGE_SOURCE_LOCAL: 186 status_.nudge_source_local++; 187 return; 188 case NUDGE_SOURCE_NOTIFICATION: 189 status_.nudge_source_notification++; 190 return; 191 case NUDGE_SOURCE_UNKNOWN: 192 break; 193 } 194 // If we're here, the source is most likely 195 // NUDGE_SOURCE_UNKNOWN. That shouldn't happen. 196 NOTREACHED(); 197 } 198 199 ScopedStatusLock::ScopedStatusLock(AllStatus* allstatus) 200 : allstatus_(allstatus) { 201 allstatus->mutex_.Acquire(); 202 } 203 204 ScopedStatusLock::~ScopedStatusLock() { 205 allstatus_->mutex_.Release(); 206 } 207 208 } // namespace syncer 209