1 // Copyright (c) 2013 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 "chrome/browser/sync/sync_startup_tracker.h" 6 7 #include "chrome/browser/profiles/profile.h" 8 #include "chrome/browser/sync/profile_sync_service.h" 9 #include "chrome/browser/sync/profile_sync_service_factory.h" 10 11 SyncStartupTracker::SyncStartupTracker(Profile* profile, Observer* observer) 12 : profile_(profile), 13 observer_(observer) { 14 ProfileSyncService* service = ProfileSyncServiceFactory::GetForProfile( 15 profile_); 16 if (service) 17 service->AddObserver(this); 18 19 CheckServiceState(); 20 } 21 22 SyncStartupTracker::~SyncStartupTracker() { 23 ProfileSyncService* service = ProfileSyncServiceFactory::GetForProfile( 24 profile_); 25 if (service) 26 service->RemoveObserver(this); 27 } 28 29 void SyncStartupTracker::OnStateChanged() { 30 CheckServiceState(); 31 } 32 33 void SyncStartupTracker::CheckServiceState() { 34 // Note: the observer may free this object so it is not allowed to access 35 // this object after invoking the observer callback below. 36 switch (GetSyncServiceState(profile_)) { 37 case SYNC_STARTUP_ERROR: 38 observer_->SyncStartupFailed(); 39 break; 40 case SYNC_STARTUP_COMPLETE: 41 observer_->SyncStartupCompleted(); 42 break; 43 case SYNC_STARTUP_PENDING: 44 // Do nothing - still waiting for sync to finish starting up. 45 break; 46 } 47 } 48 49 // static 50 SyncStartupTracker::SyncServiceState SyncStartupTracker::GetSyncServiceState( 51 Profile* profile) { 52 // If sync is disabled, treat this as a startup error. 53 if (!profile->IsSyncAccessible()) 54 return SYNC_STARTUP_ERROR; 55 56 ProfileSyncService* service = 57 ProfileSyncServiceFactory::GetForProfile(profile); 58 59 // If no service exists or sync is disabled, treat as a startup error. 60 if (!profile->IsSyncAccessible() || !service || 61 !service->IsSyncEnabledAndLoggedIn()) { 62 return SYNC_STARTUP_ERROR; 63 } 64 65 // If the sync backend has started up, notify the callback. 66 if (service->sync_initialized()) 67 return SYNC_STARTUP_COMPLETE; 68 69 // If the sync service has some kind of error, report to the user. 70 if (service->HasUnrecoverableError()) 71 return SYNC_STARTUP_ERROR; 72 73 // If we have an auth error and sync is not still waiting for new auth tokens 74 // to be fetched, exit. 75 if (!service->waiting_for_auth() && 76 service->GetAuthError().state() != GoogleServiceAuthError::NONE) { 77 return SYNC_STARTUP_ERROR; 78 } 79 80 // No error detected yet, but the sync backend hasn't started up yet, so 81 // we're in the pending state. 82 return SYNC_STARTUP_PENDING; 83 } 84