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
SyncStartupTracker(Profile * profile,Observer * observer)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
~SyncStartupTracker()22 SyncStartupTracker::~SyncStartupTracker() {
23 ProfileSyncService* service = ProfileSyncServiceFactory::GetForProfile(
24 profile_);
25 if (service)
26 service->RemoveObserver(this);
27 }
28
OnStateChanged()29 void SyncStartupTracker::OnStateChanged() {
30 CheckServiceState();
31 }
32
CheckServiceState()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
GetSyncServiceState(Profile * profile)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