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