// Copyright (c) 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "chrome/browser/sync/sync_startup_tracker.h" #include "chrome/browser/profiles/profile.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_service_factory.h" SyncStartupTracker::SyncStartupTracker(Profile* profile, Observer* observer) : profile_(profile), observer_(observer) { ProfileSyncService* service = ProfileSyncServiceFactory::GetForProfile( profile_); if (service) service->AddObserver(this); CheckServiceState(); } SyncStartupTracker::~SyncStartupTracker() { ProfileSyncService* service = ProfileSyncServiceFactory::GetForProfile( profile_); if (service) service->RemoveObserver(this); } void SyncStartupTracker::OnStateChanged() { CheckServiceState(); } void SyncStartupTracker::CheckServiceState() { // Note: the observer may free this object so it is not allowed to access // this object after invoking the observer callback below. switch (GetSyncServiceState(profile_)) { case SYNC_STARTUP_ERROR: observer_->SyncStartupFailed(); break; case SYNC_STARTUP_COMPLETE: observer_->SyncStartupCompleted(); break; case SYNC_STARTUP_PENDING: // Do nothing - still waiting for sync to finish starting up. break; } } // static SyncStartupTracker::SyncServiceState SyncStartupTracker::GetSyncServiceState( Profile* profile) { // If sync is disabled, treat this as a startup error. if (!profile->IsSyncAccessible()) return SYNC_STARTUP_ERROR; ProfileSyncService* service = ProfileSyncServiceFactory::GetForProfile(profile); // If no service exists or sync is disabled, treat as a startup error. if (!profile->IsSyncAccessible() || !service || !service->IsSyncEnabledAndLoggedIn()) { return SYNC_STARTUP_ERROR; } // If the sync backend has started up, notify the callback. if (service->sync_initialized()) return SYNC_STARTUP_COMPLETE; // If the sync service has some kind of error, report to the user. if (service->HasUnrecoverableError()) return SYNC_STARTUP_ERROR; // If we have an auth error and sync is not still waiting for new auth tokens // to be fetched, exit. if (!service->waiting_for_auth() && service->GetAuthError().state() != GoogleServiceAuthError::NONE) { return SYNC_STARTUP_ERROR; } // No error detected yet, but the sync backend hasn't started up yet, so // we're in the pending state. return SYNC_STARTUP_PENDING; }