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 break; 105 case SyncEngineEvent::ACTIONABLE_ERROR: 106 status_ = CreateBlankStatus(); 107 status_.sync_protocol_error = 108 event.snapshot.model_neutral_state().sync_protocol_error; 109 break; 110 case SyncEngineEvent::RETRY_TIME_CHANGED: 111 status_.retry_time = event.retry_time; 112 break; 113 case SyncEngineEvent::THROTTLED_TYPES_CHANGED: 114 status_.throttled_types = event.throttled_types; 115 break; 116 default: 117 LOG(ERROR) << "Unrecognized Syncer Event: " << event.what_happened; 118 break; 119 } 120 } 121 122 SyncStatus AllStatus::status() const { 123 base::AutoLock lock(mutex_); 124 return status_; 125 } 126 127 void AllStatus::SetNotificationsEnabled(bool notifications_enabled) { 128 ScopedStatusLock lock(this); 129 status_.notifications_enabled = notifications_enabled; 130 } 131 132 void AllStatus::IncrementNotificationsReceived() { 133 ScopedStatusLock lock(this); 134 ++status_.notifications_received; 135 } 136 137 void AllStatus::SetEncryptedTypes(ModelTypeSet types) { 138 ScopedStatusLock lock(this); 139 status_.encrypted_types = types; 140 } 141 142 void AllStatus::SetCryptographerReady(bool ready) { 143 ScopedStatusLock lock(this); 144 status_.cryptographer_ready = ready; 145 } 146 147 void AllStatus::SetCryptoHasPendingKeys(bool has_pending_keys) { 148 ScopedStatusLock lock(this); 149 status_.crypto_has_pending_keys = has_pending_keys; 150 } 151 152 void AllStatus::SetPassphraseType(PassphraseType type) { 153 ScopedStatusLock lock(this); 154 status_.passphrase_type = type; 155 } 156 157 void AllStatus::SetHasKeystoreKey(bool has_keystore_key) { 158 ScopedStatusLock lock(this); 159 status_.has_keystore_key = has_keystore_key; 160 } 161 162 void AllStatus::SetKeystoreMigrationTime(const base::Time& migration_time) { 163 ScopedStatusLock lock(this); 164 status_.keystore_migration_time = migration_time; 165 } 166 167 void AllStatus::SetSyncId(const std::string& sync_id) { 168 ScopedStatusLock lock(this); 169 status_.sync_id = sync_id; 170 } 171 172 void AllStatus::SetInvalidatorClientId( 173 const std::string& invalidator_client_id) { 174 ScopedStatusLock lock(this); 175 status_.invalidator_client_id = invalidator_client_id; 176 } 177 178 void AllStatus::IncrementNudgeCounter(NudgeSource source) { 179 ScopedStatusLock lock(this); 180 switch(source) { 181 case NUDGE_SOURCE_LOCAL_REFRESH: 182 status_.nudge_source_local_refresh++; 183 return; 184 case NUDGE_SOURCE_LOCAL: 185 status_.nudge_source_local++; 186 return; 187 case NUDGE_SOURCE_NOTIFICATION: 188 status_.nudge_source_notification++; 189 return; 190 case NUDGE_SOURCE_UNKNOWN: 191 break; 192 } 193 // If we're here, the source is most likely 194 // NUDGE_SOURCE_UNKNOWN. That shouldn't happen. 195 NOTREACHED(); 196 } 197 198 ScopedStatusLock::ScopedStatusLock(AllStatus* allstatus) 199 : allstatus_(allstatus) { 200 allstatus->mutex_.Acquire(); 201 } 202 203 ScopedStatusLock::~ScopedStatusLock() { 204 allstatus_->mutex_.Release(); 205 } 206 207 } // namespace syncer 208