Home | History | Annotate | Download | only in sync
      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