1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/all_status.h" 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm> 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/logging.h" 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/port.h" 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/engine/net/server_connection_manager.h" 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/protocol/service_constants.h" 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/sessions/session_state.h" 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/sync/syncable/directory_manager.h" 15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace browser_sync { 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic const sync_api::SyncManager::Status init_status = 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen { sync_api::SyncManager::Status::OFFLINE }; 20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 21731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickAllStatus::AllStatus() : status_(init_status) { 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status_.initial_sync_ended = true; 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status_.notifications_enabled = false; 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochAllStatus::~AllStatus() { 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsensync_api::SyncManager::Status AllStatus::CreateBlankStatus() const { 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Status is initialized with the previous status value. Variables 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // whose values accumulate (e.g. lifetime counters like updates_received) 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // are not to be cleared here. 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sync_api::SyncManager::Status status = status_; 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.syncing = true; 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.unsynced_count = 0; 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.conflicting_count = 0; 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.initial_sync_ended = false; 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.syncer_stuck = false; 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.max_consecutive_errors = 0; 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.server_broken = false; 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.updates_available = 0; 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return status; 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsensync_api::SyncManager::Status AllStatus::CalcSyncing( 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const SyncEngineEvent &event) const { 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen sync_api::SyncManager::Status status = CreateBlankStatus(); 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sessions::SyncSessionSnapshot* snapshot = event.snapshot; 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.unsynced_count += static_cast<int>(snapshot->unsynced_count); 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.conflicting_count += snapshot->errors.num_conflicting_commits; 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // The syncer may not be done yet, which could cause conflicting updates. 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // But this is only used for status, so it is better to have visibility. 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.conflicting_count += snapshot->num_conflicting_updates; 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.syncing |= snapshot->syncer_status.syncing; 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.syncing = snapshot->has_more_to_sync && snapshot->is_silenced; 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.initial_sync_ended |= snapshot->is_share_usable; 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.syncer_stuck |= snapshot->syncer_status.syncer_stuck; 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const sessions::ErrorCounters& errors(snapshot->errors); 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (errors.consecutive_errors > status.max_consecutive_errors) 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.max_consecutive_errors = errors.consecutive_errors; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // 100 is an arbitrary limit. 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (errors.consecutive_transient_error_commits > 100) 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.server_broken = true; 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status.updates_available += snapshot->num_server_changes_remaining; 6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Accumulate update count only once per session to avoid double-counting. 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // TODO(ncarter): Make this realtime by having the syncer_status 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // counter preserve its value across sessions. http://crbug.com/26339 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (event.what_happened == SyncEngineEvent::SYNC_CYCLE_ENDED) { 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen status.updates_received += 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen snapshot->syncer_status.num_updates_downloaded_total; 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen status.tombstone_updates_received += 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen snapshot->syncer_status.num_tombstone_updates_downloaded_total; 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return status; 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 82731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AllStatus::CalcStatusChanges() { 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const bool unsynced_changes = status_.unsynced_count > 0; 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const bool online = status_.authenticated && 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status_.server_reachable && status_.server_up && !status_.server_broken; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (online) { 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (status_.syncer_stuck) 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen status_.summary = sync_api::SyncManager::Status::CONFLICT; 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else if (unsynced_changes || status_.syncing) 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen status_.summary = sync_api::SyncManager::Status::SYNCING; 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch else 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen status_.summary = sync_api::SyncManager::Status::READY; 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (!status_.initial_sync_ended) { 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen status_.summary = sync_api::SyncManager::Status::OFFLINE_UNUSABLE; 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else if (unsynced_changes) { 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen status_.summary = sync_api::SyncManager::Status::OFFLINE_UNSYNCED; 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } else { 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen status_.summary = sync_api::SyncManager::Status::OFFLINE; 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 102731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid AllStatus::OnSyncEngineEvent(const SyncEngineEvent& event) { 103731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ScopedStatusLock lock(this); 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch switch (event.what_happened) { 105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case SyncEngineEvent::SYNC_CYCLE_ENDED: 106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case SyncEngineEvent::STATUS_CHANGED: 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status_ = CalcSyncing(event); 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 109731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick case SyncEngineEvent::STOP_SYNCING_PERMANENTLY: 110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case SyncEngineEvent::UPDATED_TOKEN: 111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case SyncEngineEvent::CLEAR_SERVER_DATA_FAILED: 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen case SyncEngineEvent::CLEAR_SERVER_DATA_SUCCEEDED: 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch default: 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch LOG(ERROR) << "Unrecognized Syncer Event: " << event.what_happened; 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch break; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AllStatus::HandleServerConnectionEvent( 121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const ServerConnectionEvent& event) { 122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch if (ServerConnectionEvent::STATUS_CHANGED == event.what_happened) { 123731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ScopedStatusLock lock(this); 124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status_.server_up = IsGoodReplyFromServer(event.connection_code); 125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status_.server_reachable = event.server_reachable; 1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick if (event.connection_code == HttpResponse::SERVER_CONNECTION_OK) { 1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick status_.authenticated = true; 1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } else { 1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick status_.authenticated = false; 1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick } 132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch } 133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsensync_api::SyncManager::Status AllStatus::status() const { 13672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::AutoLock lock(mutex_); 137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch return status_; 138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AllStatus::SetNotificationsEnabled(bool notifications_enabled) { 141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ScopedStatusLock lock(this); 142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch status_.notifications_enabled = notifications_enabled; 143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AllStatus::IncrementNotificationsSent() { 146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ScopedStatusLock lock(this); 147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++status_.notifications_sent; 148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid AllStatus::IncrementNotificationsReceived() { 151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick ScopedStatusLock lock(this); 152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ++status_.notifications_received; 153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 155731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickScopedStatusLock::ScopedStatusLock(AllStatus* allstatus) 156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick : allstatus_(allstatus) { 157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch allstatus->mutex_.Acquire(); 158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 160731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickScopedStatusLock::~ScopedStatusLock() { 161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick allstatus_->CalcStatusChanges(); 162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch allstatus_->mutex_.Release(); 163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} 164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace browser_sync 166