OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/signin/signin_tracker.h" | 5 #include "chrome/browser/signin/signin_tracker.h" |
6 | 6 |
7 #include "chrome/browser/profiles/profile.h" | 7 #include "chrome/browser/profiles/profile.h" |
8 #include "chrome/browser/signin/token_service.h" | 8 #include "chrome/browser/signin/token_service.h" |
9 #include "chrome/browser/signin/token_service_factory.h" | 9 #include "chrome/browser/signin/token_service_factory.h" |
10 #include "chrome/browser/sync/profile_sync_service.h" | 10 #include "chrome/browser/sync/profile_sync_service.h" |
11 #include "chrome/browser/sync/profile_sync_service_factory.h" | 11 #include "chrome/browser/sync/profile_sync_service_factory.h" |
12 #include "chrome/common/chrome_notification_types.h" | 12 #include "chrome/common/chrome_notification_types.h" |
13 #include "chrome/common/net/gaia/gaia_constants.h" | 13 #include "chrome/common/net/gaia/gaia_constants.h" |
14 #include "content/public/browser/notification_details.h" | 14 #include "content/public/browser/notification_details.h" |
15 #include "content/public/browser/notification_source.h" | 15 #include "content/public/browser/notification_source.h" |
16 | 16 |
17 static const char* kSignedInServices[] = { | 17 static const char* kSignedInServices[] = { |
18 GaiaConstants::kSyncService, | 18 GaiaConstants::kSyncService, |
19 GaiaConstants::kGaiaOAuth2LoginRefreshToken | 19 GaiaConstants::kGaiaOAuth2LoginRefreshToken |
20 }; | 20 }; |
21 static const int kNumSignedInServices = | 21 static const int kNumSignedInServices = |
22 arraysize(kSignedInServices); | 22 arraysize(kSignedInServices); |
23 | 23 |
24 // Helper to check if the given token service is relevant for sync. | 24 // Helper to check if the given token service is relevant for sync. |
25 SigninTracker::SigninTracker(Profile* profile, Observer* observer) | 25 SigninTracker::SigninTracker(Profile* profile, Observer* observer) |
26 : state_(WAITING_FOR_GAIA_VALIDATION), | 26 : |
27 #if !defined(OS_CHROMEOS) | |
28 state_(WAITING_FOR_GAIA_VALIDATION), | |
Andrew T Wilson (Slow)
2012/04/03 17:45:13
I think it would be better to have an alternate co
kochi
2012/04/03 21:55:29
Done.
| |
29 #else | |
30 state_(SERVICES_INITIALIZING), | |
31 #endif | |
27 profile_(profile), | 32 profile_(profile), |
28 observer_(observer), | 33 observer_(observer), |
29 credentials_valid_(false) { | 34 credentials_valid_(false) { |
30 DCHECK(observer_); | 35 DCHECK(observer_); |
31 // Register for notifications from the SigninManager. | 36 // Register for notifications from the SigninManager. |
37 // On ChromeOS, we don't register sign in notification because we don't | |
38 // use it in SyncSetupHandler. | |
39 #if !defined(OS_CHROMEOS) | |
Andrew T Wilson (Slow)
2012/04/03 17:45:13
I'd say you should probably just register for all
kochi
2012/04/03 21:55:29
Done.
| |
32 registrar_.Add(this, | 40 registrar_.Add(this, |
33 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, | 41 chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL, |
34 content::Source<Profile>(profile_)); | 42 content::Source<Profile>(profile_)); |
43 #endif | |
35 registrar_.Add(this, | 44 registrar_.Add(this, |
36 chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED, | 45 chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED, |
37 content::Source<Profile>(profile_)); | 46 content::Source<Profile>(profile_)); |
38 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); | 47 TokenService* token_service = TokenServiceFactory::GetForProfile(profile_); |
39 registrar_.Add(this, | 48 registrar_.Add(this, |
40 chrome::NOTIFICATION_TOKEN_AVAILABLE, | 49 chrome::NOTIFICATION_TOKEN_AVAILABLE, |
41 content::Source<TokenService>(token_service)); | 50 content::Source<TokenService>(token_service)); |
42 registrar_.Add(this, | 51 registrar_.Add(this, |
43 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, | 52 chrome::NOTIFICATION_TOKEN_REQUEST_FAILED, |
44 content::Source<TokenService>(token_service)); | 53 content::Source<TokenService>(token_service)); |
45 | 54 |
46 // Also listen for notifications from the various signed in services (only | 55 // Also listen for notifications from the various signed in services (only |
47 // sync for now). | 56 // sync for now). |
48 ProfileSyncService* service = | 57 ProfileSyncService* service = |
49 ProfileSyncServiceFactory::GetForProfile(profile_); | 58 ProfileSyncServiceFactory::GetForProfile(profile_); |
50 service->AddObserver(this); | 59 service->AddObserver(this); |
60 | |
61 #if defined(OS_CHROMEOS) | |
62 DCHECK_EQ(state_, SERVICES_INITIALIZING); | |
Andrew T Wilson (Slow)
2012/04/03 17:45:13
When you change the constructor to allow setting t
kochi
2012/04/03 21:55:29
Done.
| |
63 HandleServiceStateChange(); | |
64 #endif | |
51 } | 65 } |
52 | 66 |
53 SigninTracker::~SigninTracker() { | 67 SigninTracker::~SigninTracker() { |
54 ProfileSyncService* service = | 68 ProfileSyncService* service = |
55 ProfileSyncServiceFactory::GetForProfile(profile_); | 69 ProfileSyncServiceFactory::GetForProfile(profile_); |
56 service->RemoveObserver(this); | 70 service->RemoveObserver(this); |
57 } | 71 } |
58 | 72 |
59 void SigninTracker::Observe(int type, | 73 void SigninTracker::Observe(int type, |
60 const content::NotificationSource& source, | 74 const content::NotificationSource& source, |
61 const content::NotificationDetails& details) { | 75 const content::NotificationDetails& details) { |
62 // We should not get more than one of these notifications. | 76 // We should not get more than one of these notifications. |
63 switch (type) { | 77 switch (type) { |
64 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: | 78 case chrome::NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL: |
79 LOG(WARNING) << "Got NOTIFICATION_GOOGLE_SIGNIN_SUCCESSFUL"; | |
65 DCHECK_EQ(state_, WAITING_FOR_GAIA_VALIDATION); | 80 DCHECK_EQ(state_, WAITING_FOR_GAIA_VALIDATION); |
66 state_ = SERVICES_INITIALIZING; | 81 state_ = SERVICES_INITIALIZING; |
67 observer_->GaiaCredentialsValid(); | 82 observer_->GaiaCredentialsValid(); |
68 // If our services are already signed in, see if it's possible to | 83 // If our services are already signed in, see if it's possible to |
69 // transition to the SIGNIN_COMPLETE state. | 84 // transition to the SIGNIN_COMPLETE state. |
70 if (AreServicesSignedIn(profile_)) | 85 if (AreServicesSignedIn(profile_)) |
71 HandleServiceStateChange(); | 86 HandleServiceStateChange(); |
72 break; | 87 break; |
73 case chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED: { | 88 case chrome::NOTIFICATION_GOOGLE_SIGNIN_FAILED: { |
89 LOG(WARNING) << "Got NOTIFICATION_GOOGLE_SIGNIN_FAILED"; | |
74 DCHECK_EQ(state_, WAITING_FOR_GAIA_VALIDATION); | 90 DCHECK_EQ(state_, WAITING_FOR_GAIA_VALIDATION); |
75 const GoogleServiceAuthError& error = | 91 const GoogleServiceAuthError& error = |
76 *(content::Details<const GoogleServiceAuthError>(details).ptr()); | 92 *(content::Details<const GoogleServiceAuthError>(details).ptr()); |
77 observer_->SigninFailed(error); | 93 observer_->SigninFailed(error); |
78 break; | 94 break; |
79 } | 95 } |
80 case chrome::NOTIFICATION_TOKEN_AVAILABLE: | 96 case chrome::NOTIFICATION_TOKEN_AVAILABLE: |
97 LOG(WARNING) << "Got NOTIFICATION_TOKEN_AVAILABLE"; | |
81 // A new token is available - check to see if we're all signed in now. | 98 // A new token is available - check to see if we're all signed in now. |
82 HandleServiceStateChange(); | 99 HandleServiceStateChange(); |
83 break; | 100 break; |
84 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: | 101 case chrome::NOTIFICATION_TOKEN_REQUEST_FAILED: |
102 LOG(WARNING) << "Got NOTIFICATION_TOKEN_REQUEST_FAILED"; | |
85 if (state_ == SERVICES_INITIALIZING) { | 103 if (state_ == SERVICES_INITIALIZING) { |
86 const TokenService::TokenRequestFailedDetails& token_details = | 104 const TokenService::TokenRequestFailedDetails& token_details = |
87 *(content::Details<const TokenService::TokenRequestFailedDetails>( | 105 *(content::Details<const TokenService::TokenRequestFailedDetails>( |
88 details).ptr()); | 106 details).ptr()); |
89 for (int i = 0; i < kNumSignedInServices; ++i) { | 107 for (int i = 0; i < kNumSignedInServices; ++i) { |
90 if (token_details.service() == kSignedInServices[i]) { | 108 if (token_details.service() == kSignedInServices[i]) { |
91 // We got an error loading one of our tokens, so notify our | 109 // We got an error loading one of our tokens, so notify our |
92 // observer. | 110 // observer. |
111 LOG(WARNING) << "resetting state_ to WAITING_FOR_GAIA_VALIDATION"; | |
93 state_ = WAITING_FOR_GAIA_VALIDATION; | 112 state_ = WAITING_FOR_GAIA_VALIDATION; |
94 observer_->SigninFailed(token_details.error()); | 113 observer_->SigninFailed(token_details.error()); |
95 } | 114 } |
96 } | 115 } |
97 } | 116 } |
98 break; | 117 break; |
99 default: | 118 default: |
100 NOTREACHED(); | 119 NOTREACHED(); |
101 } | 120 } |
102 } | 121 } |
103 | 122 |
104 // Called when the ProfileSyncService state changes. | 123 // Called when the ProfileSyncService state changes. |
105 void SigninTracker::OnStateChanged() { | 124 void SigninTracker::OnStateChanged() { |
106 HandleServiceStateChange(); | 125 HandleServiceStateChange(); |
107 } | 126 } |
108 | 127 |
109 void SigninTracker::HandleServiceStateChange() { | 128 void SigninTracker::HandleServiceStateChange() { |
110 if (state_ != SERVICES_INITIALIZING) { | 129 if (state_ != SERVICES_INITIALIZING) { |
130 LOG(WARNING) << "HandleServiceStateChange: state!=SERVICES_INITIALIZING" << (int)state_; | |
111 // Ignore service updates until after our GAIA credentials are validated. | 131 // Ignore service updates until after our GAIA credentials are validated. |
112 return; | 132 return; |
113 } | 133 } |
114 // Wait until all of our services are logged in. For now this just means sync. | 134 // Wait until all of our services are logged in. For now this just means sync. |
115 // Long term, we should separate out service auth failures from the signin | 135 // Long term, we should separate out service auth failures from the signin |
116 // process, but for the current UI flow we'll validate service signin status | 136 // process, but for the current UI flow we'll validate service signin status |
117 // also. | 137 // also. |
118 // TODO(atwilson): Move the code to wait for app notification oauth tokens out | 138 // TODO(atwilson): Move the code to wait for app notification oauth tokens out |
119 // of ProfileSyncService and over to here (http://crbug.com/114209). | 139 // of ProfileSyncService and over to here (http://crbug.com/114209). |
120 ProfileSyncService* service = | 140 ProfileSyncService* service = |
121 ProfileSyncServiceFactory::GetForProfile(profile_); | 141 ProfileSyncServiceFactory::GetForProfile(profile_); |
122 if (service->waiting_for_auth()) { | 142 if (service->waiting_for_auth()) { |
143 LOG(WARNING) << "HandleServiceStateChange: service is waiting for auth"; | |
Andrew T Wilson (Slow)
2012/04/03 17:45:13
BTW, it might be useful to keep some of these mess
kochi
2012/04/03 21:55:29
I'm planning to clean all these LOG(WARNING) messa
| |
123 // Still waiting for an auth token to come in so stay in the INITIALIZING | 144 // Still waiting for an auth token to come in so stay in the INITIALIZING |
124 // state (we do this to avoid triggering an early signin error in the case | 145 // state (we do this to avoid triggering an early signin error in the case |
125 // where there's a previous auth error in the sync service that hasn't | 146 // where there's a previous auth error in the sync service that hasn't |
126 // been cleared yet). | 147 // been cleared yet). |
127 return; | 148 return; |
128 } | 149 } |
129 // If we haven't loaded all our service tokens yet, just exit (we'll be called | 150 // If we haven't loaded all our service tokens yet, just exit (we'll be called |
130 // again when another token is loaded, or will transition to SigninFailed if | 151 // again when another token is loaded, or will transition to SigninFailed if |
131 // the loading fails). | 152 // the loading fails). |
132 if (!AreServiceTokensLoaded(profile_)) | 153 if (!AreServiceTokensLoaded(profile_)) { |
154 LOG(WARNING) << "HandleServiceStateChange: ServiceToken not loaded"; | |
133 return; | 155 return; |
156 } | |
134 if (!AreServicesSignedIn(profile_)) { | 157 if (!AreServicesSignedIn(profile_)) { |
158 LOG(WARNING) << "HandleServiceStateChange: not signed in to services"; | |
135 state_ = WAITING_FOR_GAIA_VALIDATION; | 159 state_ = WAITING_FOR_GAIA_VALIDATION; |
136 observer_->SigninFailed(service->GetAuthError()); | 160 observer_->SigninFailed(service->GetAuthError()); |
137 } else if (service->sync_initialized()) { | 161 } else if (service->sync_initialized()) { |
162 LOG(WARNING) << "HandleServiceStateChange: sign in complete!"; | |
138 state_ = SIGNIN_COMPLETE; | 163 state_ = SIGNIN_COMPLETE; |
139 observer_->SigninSuccess(); | 164 observer_->SigninSuccess(); |
140 } | 165 } |
141 } | 166 } |
142 | 167 |
143 // static | 168 // static |
144 bool SigninTracker::AreServiceTokensLoaded(Profile* profile) { | 169 bool SigninTracker::AreServiceTokensLoaded(Profile* profile) { |
145 // See if we have all of the tokens required. | 170 // See if we have all of the tokens required. |
146 TokenService* token_service = TokenServiceFactory::GetForProfile(profile); | 171 TokenService* token_service = TokenServiceFactory::GetForProfile(profile); |
147 for (int i = 0; i < kNumSignedInServices; ++i) { | 172 for (int i = 0; i < kNumSignedInServices; ++i) { |
148 if (!token_service->HasTokenForService(kSignedInServices[i])) { | 173 if (!token_service->HasTokenForService(kSignedInServices[i])) { |
174 LOG(WARNING) << "Token not available for service " << kSignedInServices[i] ; | |
149 // Don't have a token for one of our signed-in services. | 175 // Don't have a token for one of our signed-in services. |
150 return false; | 176 return false; |
151 } | 177 } |
152 } | 178 } |
153 return true; | 179 return true; |
154 } | 180 } |
155 | 181 |
156 // static | 182 // static |
157 bool SigninTracker::AreServicesSignedIn(Profile* profile) { | 183 bool SigninTracker::AreServicesSignedIn(Profile* profile) { |
158 if (!AreServiceTokensLoaded(profile)) | 184 if (!AreServiceTokensLoaded(profile)) |
159 return false; | 185 return false; |
160 ProfileSyncService* service = | 186 ProfileSyncService* service = |
161 ProfileSyncServiceFactory::GetForProfile(profile); | 187 ProfileSyncServiceFactory::GetForProfile(profile); |
188 LOG(WARNING) << "AreServicesSignedIn: AreCredentialsAvailable() : " << (servic e->AreCredentialsAvailable() ? "YES" : "NO"); | |
189 LOG(WARNING) << "AreServicesSignedIn: GetAuthError() : " << (int)service->GetA uthError().state(); | |
190 LOG(WARNING) << "AreServicesSignedIn: unrecoverable error? : " << (service->un recoverable_error_detected() ? "YES" : "NO"); | |
162 return (service->AreCredentialsAvailable() && | 191 return (service->AreCredentialsAvailable() && |
163 service->GetAuthError().state() == GoogleServiceAuthError::NONE && | 192 service->GetAuthError().state() == GoogleServiceAuthError::NONE && |
164 !service->unrecoverable_error_detected()); | 193 !service->unrecoverable_error_detected()); |
165 } | 194 } |
166 | |
OLD | NEW |