| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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/account_reconcilor.h" | 5 #include "components/signin/core/browser/account_reconcilor.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| 11 #include "base/logging.h" | 11 #include "base/logging.h" |
| 12 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
| 13 #include "base/message_loop/message_loop_proxy.h" | 13 #include "base/message_loop/message_loop_proxy.h" |
| 14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 16 #include "chrome/browser/profiles/profile.h" | |
| 17 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" | |
| 18 #include "chrome/browser/signin/signin_manager_factory.h" | |
| 19 #include "chrome/browser/signin/signin_oauth_helper.h" | |
| 20 #include "components/signin/core/browser/profile_oauth2_token_service.h" | 16 #include "components/signin/core/browser/profile_oauth2_token_service.h" |
| 21 #include "components/signin/core/browser/signin_client.h" | 17 #include "components/signin/core/browser/signin_client.h" |
| 18 #include "components/signin/core/browser/signin_oauth_helper.h" |
| 22 #include "google_apis/gaia/gaia_auth_fetcher.h" | 19 #include "google_apis/gaia/gaia_auth_fetcher.h" |
| 23 #include "google_apis/gaia/gaia_auth_util.h" | 20 #include "google_apis/gaia/gaia_auth_util.h" |
| 24 #include "google_apis/gaia/gaia_constants.h" | 21 #include "google_apis/gaia/gaia_constants.h" |
| 25 #include "google_apis/gaia/gaia_oauth_client.h" | 22 #include "google_apis/gaia/gaia_oauth_client.h" |
| 26 #include "google_apis/gaia/gaia_urls.h" | 23 #include "google_apis/gaia/gaia_urls.h" |
| 27 | 24 |
| 28 // Fetches a refresh token from the given session in the GAIA cookie. This is | 25 // Fetches a refresh token from the given session in the GAIA cookie. This is |
| 29 // a best effort only. If it should fail, another reconcile action will occur | 26 // a best effort only. If it should fail, another reconcile action will occur |
| 30 // shortly anyway. | 27 // shortly anyway. |
| 31 class AccountReconcilor::RefreshTokenFetcher | 28 class AccountReconcilor::RefreshTokenFetcher |
| (...skipping 20 matching lines...) Expand all Loading... |
| 52 const std::string account_id_; | 49 const std::string account_id_; |
| 53 int session_index_; | 50 int session_index_; |
| 54 | 51 |
| 55 DISALLOW_COPY_AND_ASSIGN(RefreshTokenFetcher); | 52 DISALLOW_COPY_AND_ASSIGN(RefreshTokenFetcher); |
| 56 }; | 53 }; |
| 57 | 54 |
| 58 AccountReconcilor::RefreshTokenFetcher::RefreshTokenFetcher( | 55 AccountReconcilor::RefreshTokenFetcher::RefreshTokenFetcher( |
| 59 AccountReconcilor* reconcilor, | 56 AccountReconcilor* reconcilor, |
| 60 const std::string& account_id, | 57 const std::string& account_id, |
| 61 int session_index) | 58 int session_index) |
| 62 : SigninOAuthHelper(reconcilor->profile()->GetRequestContext(), | 59 : SigninOAuthHelper(reconcilor->client()->GetURLRequestContext(), |
| 63 base::IntToString(session_index), this), | 60 base::IntToString(session_index), |
| 61 this), |
| 64 reconcilor_(reconcilor), | 62 reconcilor_(reconcilor), |
| 65 account_id_(account_id), | 63 account_id_(account_id), |
| 66 session_index_(session_index) { | 64 session_index_(session_index) { |
| 67 DCHECK(reconcilor_); | 65 DCHECK(reconcilor_); |
| 68 DCHECK(!account_id.empty()); | 66 DCHECK(!account_id.empty()); |
| 69 } | 67 } |
| 70 | 68 |
| 71 void AccountReconcilor::RefreshTokenFetcher::OnSigninOAuthInformationAvailable( | 69 void AccountReconcilor::RefreshTokenFetcher::OnSigninOAuthInformationAvailable( |
| 72 const std::string& email, | 70 const std::string& email, |
| 73 const std::string& display_email, | 71 const std::string& display_email, |
| 74 const std::string& refresh_token) { | 72 const std::string& refresh_token) { |
| 75 VLOG(1) << "RefreshTokenFetcher::OnSigninOAuthInformationAvailable:" | 73 VLOG(1) << "RefreshTokenFetcher::OnSigninOAuthInformationAvailable:" |
| 76 << " account=" << account_id_ | 74 << " account=" << account_id_ << " email=" << email |
| 77 << " email=" << email | |
| 78 << " displayEmail=" << display_email; | 75 << " displayEmail=" << display_email; |
| 79 | 76 |
| 80 // TODO(rogerta): because of the problem with email vs displayEmail and | 77 // TODO(rogerta): because of the problem with email vs displayEmail and |
| 81 // emails that have been canonicalized, the argument |email| is used here | 78 // emails that have been canonicalized, the argument |email| is used here |
| 82 // to make sure the correct string is used when calling the token service. | 79 // to make sure the correct string is used when calling the token service. |
| 83 // This will be cleaned up when chrome moves to using gaia obfuscated id. | 80 // This will be cleaned up when chrome moves to using gaia obfuscated id. |
| 84 reconcilor_->HandleRefreshTokenFetched(email, refresh_token); | 81 reconcilor_->HandleRefreshTokenFetched(email, refresh_token); |
| 85 } | 82 } |
| 86 | 83 |
| 87 void AccountReconcilor::RefreshTokenFetcher::OnSigninOAuthInformationFailure( | 84 void AccountReconcilor::RefreshTokenFetcher::OnSigninOAuthInformationFailure( |
| 88 const GoogleServiceAuthError& error) { | 85 const GoogleServiceAuthError& error) { |
| 89 VLOG(1) << "RefreshTokenFetcher::OnSigninOAuthInformationFailure:" | 86 VLOG(1) << "RefreshTokenFetcher::OnSigninOAuthInformationFailure:" |
| 90 << " account=" << account_id_ | 87 << " account=" << account_id_ << " session_index=" << session_index_; |
| 91 << " session_index=" << session_index_; | |
| 92 reconcilor_->HandleRefreshTokenFetched(account_id_, std::string()); | 88 reconcilor_->HandleRefreshTokenFetched(account_id_, std::string()); |
| 93 } | 89 } |
| 94 | 90 |
| 95 | |
| 96 bool AccountReconcilor::EmailLessFunc::operator()(const std::string& s1, | 91 bool AccountReconcilor::EmailLessFunc::operator()(const std::string& s1, |
| 97 const std::string& s2) const { | 92 const std::string& s2) const { |
| 98 return gaia::CanonicalizeEmail(s1) < gaia::CanonicalizeEmail(s2); | 93 return gaia::CanonicalizeEmail(s1) < gaia::CanonicalizeEmail(s2); |
| 99 } | 94 } |
| 100 | 95 |
| 101 class AccountReconcilor::UserIdFetcher | 96 class AccountReconcilor::UserIdFetcher |
| 102 : public gaia::GaiaOAuthClient::Delegate { | 97 : public gaia::GaiaOAuthClient::Delegate { |
| 103 public: | 98 public: |
| 104 UserIdFetcher(AccountReconcilor* reconcilor, | 99 UserIdFetcher(AccountReconcilor* reconcilor, |
| 105 const std::string& access_token, | 100 const std::string& access_token, |
| (...skipping 15 matching lines...) Expand all Loading... |
| 121 | 116 |
| 122 DISALLOW_COPY_AND_ASSIGN(UserIdFetcher); | 117 DISALLOW_COPY_AND_ASSIGN(UserIdFetcher); |
| 123 }; | 118 }; |
| 124 | 119 |
| 125 AccountReconcilor::UserIdFetcher::UserIdFetcher(AccountReconcilor* reconcilor, | 120 AccountReconcilor::UserIdFetcher::UserIdFetcher(AccountReconcilor* reconcilor, |
| 126 const std::string& access_token, | 121 const std::string& access_token, |
| 127 const std::string& account_id) | 122 const std::string& account_id) |
| 128 : reconcilor_(reconcilor), | 123 : reconcilor_(reconcilor), |
| 129 account_id_(account_id), | 124 account_id_(account_id), |
| 130 access_token_(access_token), | 125 access_token_(access_token), |
| 131 gaia_auth_client_(reconcilor_->profile()->GetRequestContext()) { | 126 gaia_auth_client_(reconcilor_->client()->GetURLRequestContext()) { |
| 132 DCHECK(reconcilor_); | 127 DCHECK(reconcilor_); |
| 133 DCHECK(!account_id_.empty()); | 128 DCHECK(!account_id_.empty()); |
| 134 | 129 |
| 135 const int kMaxRetries = 5; | 130 const int kMaxRetries = 5; |
| 136 gaia_auth_client_.GetUserId(access_token_, kMaxRetries, this); | 131 gaia_auth_client_.GetUserId(access_token_, kMaxRetries, this); |
| 137 } | 132 } |
| 138 | 133 |
| 139 // static | 134 // static |
| 140 OAuth2TokenService::ScopeSet AccountReconcilor::UserIdFetcher::GetScopes() { | 135 OAuth2TokenService::ScopeSet AccountReconcilor::UserIdFetcher::GetScopes() { |
| 141 OAuth2TokenService::ScopeSet scopes; | 136 OAuth2TokenService::ScopeSet scopes; |
| 142 scopes.insert("https://www.googleapis.com/auth/userinfo.profile"); | 137 scopes.insert("https://www.googleapis.com/auth/userinfo.profile"); |
| 143 return scopes; | 138 return scopes; |
| 144 } | 139 } |
| 145 | 140 |
| 146 void AccountReconcilor::UserIdFetcher::OnGetUserIdResponse( | 141 void AccountReconcilor::UserIdFetcher::OnGetUserIdResponse( |
| 147 const std::string& user_id) { | 142 const std::string& user_id) { |
| 148 VLOG(1) << "AccountReconcilor::OnGetUserIdResponse: " << account_id_; | 143 VLOG(1) << "AccountReconcilor::OnGetUserIdResponse: " << account_id_; |
| 149 | 144 |
| 150 // HandleSuccessfulAccountIdCheck() may delete |this|, so call it last. | 145 // HandleSuccessfulAccountIdCheck() may delete |this|, so call it last. |
| 151 reconcilor_->HandleSuccessfulAccountIdCheck(account_id_); | 146 reconcilor_->HandleSuccessfulAccountIdCheck(account_id_); |
| 152 } | 147 } |
| 153 | 148 |
| 154 void AccountReconcilor::UserIdFetcher::OnOAuthError() { | 149 void AccountReconcilor::UserIdFetcher::OnOAuthError() { |
| 155 VLOG(1) << "AccountReconcilor::OnOAuthError: " << account_id_; | 150 VLOG(1) << "AccountReconcilor::OnOAuthError: " << account_id_; |
| 156 | 151 |
| 157 // Invalidate the access token to force a refetch next time. | 152 // Invalidate the access token to force a refetch next time. |
| 158 ProfileOAuth2TokenService* token_service = | 153 reconcilor_->token_service()->InvalidateToken( |
| 159 ProfileOAuth2TokenServiceFactory::GetForProfile(reconcilor_->profile()); | 154 account_id_, GetScopes(), access_token_); |
| 160 token_service->InvalidateToken(account_id_, GetScopes(), access_token_); | |
| 161 | 155 |
| 162 // HandleFailedAccountIdCheck() may delete |this|, so call it last. | 156 // HandleFailedAccountIdCheck() may delete |this|, so call it last. |
| 163 reconcilor_->HandleFailedAccountIdCheck(account_id_); | 157 reconcilor_->HandleFailedAccountIdCheck(account_id_); |
| 164 } | 158 } |
| 165 | 159 |
| 166 void AccountReconcilor::UserIdFetcher::OnNetworkError(int response_code) { | 160 void AccountReconcilor::UserIdFetcher::OnNetworkError(int response_code) { |
| 167 VLOG(1) << "AccountReconcilor::OnNetworkError: " << account_id_ | 161 VLOG(1) << "AccountReconcilor::OnNetworkError: " << account_id_ |
| 168 << " response_code=" << response_code; | 162 << " response_code=" << response_code; |
| 169 | 163 |
| 170 // TODO(rogerta): some response error should not be treated like | 164 // TODO(rogerta): some response error should not be treated like |
| 171 // permanent errors. Figure out appropriate ones. | 165 // permanent errors. Figure out appropriate ones. |
| 172 // HandleFailedAccountIdCheck() may delete |this|, so call it last. | 166 // HandleFailedAccountIdCheck() may delete |this|, so call it last. |
| 173 reconcilor_->HandleFailedAccountIdCheck(account_id_); | 167 reconcilor_->HandleFailedAccountIdCheck(account_id_); |
| 174 } | 168 } |
| 175 | 169 |
| 176 AccountReconcilor::AccountReconcilor(Profile* profile, SigninClient* client) | 170 AccountReconcilor::AccountReconcilor(ProfileOAuth2TokenService* token_service, |
| 171 SigninManager* signin_manager, |
| 172 SigninClient* client) |
| 177 : OAuth2TokenService::Consumer("account_reconcilor"), | 173 : OAuth2TokenService::Consumer("account_reconcilor"), |
| 178 profile_(profile), | 174 token_service_(token_service), |
| 175 signin_manager_(signin_manager), |
| 179 client_(client), | 176 client_(client), |
| 180 merge_session_helper_( | 177 merge_session_helper_(token_service_, |
| 181 ProfileOAuth2TokenServiceFactory::GetForProfile(profile), | 178 client->GetURLRequestContext(), |
| 182 profile->GetRequestContext(), | 179 this), |
| 183 this), | |
| 184 registered_with_token_service_(false), | 180 registered_with_token_service_(false), |
| 185 is_reconcile_started_(false), | 181 is_reconcile_started_(false), |
| 186 are_gaia_accounts_set_(false), | 182 are_gaia_accounts_set_(false), |
| 187 requests_(NULL) { | 183 requests_(NULL) { |
| 188 VLOG(1) << "AccountReconcilor::AccountReconcilor"; | 184 VLOG(1) << "AccountReconcilor::AccountReconcilor"; |
| 189 } | 185 } |
| 190 | 186 |
| 191 AccountReconcilor::~AccountReconcilor() { | 187 AccountReconcilor::~AccountReconcilor() { |
| 192 VLOG(1) << "AccountReconcilor::~AccountReconcilor"; | 188 VLOG(1) << "AccountReconcilor::~AccountReconcilor"; |
| 193 // Make sure shutdown was called first. | 189 // Make sure shutdown was called first. |
| 194 DCHECK(!registered_with_token_service_); | 190 DCHECK(!registered_with_token_service_); |
| 195 DCHECK(!reconciliation_timer_.IsRunning()); | 191 DCHECK(!reconciliation_timer_.IsRunning()); |
| 196 DCHECK(!requests_); | 192 DCHECK(!requests_); |
| 197 DCHECK_EQ(0u, user_id_fetchers_.size()); | 193 DCHECK_EQ(0u, user_id_fetchers_.size()); |
| 198 DCHECK_EQ(0u, refresh_token_fetchers_.size()); | 194 DCHECK_EQ(0u, refresh_token_fetchers_.size()); |
| 199 } | 195 } |
| 200 | 196 |
| 201 void AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) { | 197 void AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) { |
| 202 VLOG(1) << "AccountReconcilor::Initialize"; | 198 VLOG(1) << "AccountReconcilor::Initialize"; |
| 203 RegisterWithSigninManager(); | 199 RegisterWithSigninManager(); |
| 204 | 200 |
| 205 // If this profile is not connected, the reconcilor should do nothing but | 201 // If this user is not signed in, the reconcilor should do nothing but |
| 206 // wait for the connection. | 202 // wait for signin. |
| 207 if (IsProfileConnected()) { | 203 if (IsUserSignedIn()) { |
| 208 RegisterForCookieChanges(); | 204 RegisterForCookieChanges(); |
| 209 RegisterWithTokenService(); | 205 RegisterWithTokenService(); |
| 210 StartPeriodicReconciliation(); | 206 StartPeriodicReconciliation(); |
| 211 | 207 |
| 212 // Start a reconcile if the tokens are already loaded. | 208 // Start a reconcile if the tokens are already loaded. |
| 213 ProfileOAuth2TokenService* token_service = | |
| 214 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); | |
| 215 if (start_reconcile_if_tokens_available && | 209 if (start_reconcile_if_tokens_available && |
| 216 token_service->GetAccounts().size() > 0) { | 210 token_service_->GetAccounts().size() > 0) { |
| 217 StartReconcile(); | 211 StartReconcile(); |
| 218 } | 212 } |
| 219 } | 213 } |
| 220 } | 214 } |
| 221 | 215 |
| 222 void AccountReconcilor::Shutdown() { | 216 void AccountReconcilor::Shutdown() { |
| 223 VLOG(1) << "AccountReconcilor::Shutdown"; | 217 VLOG(1) << "AccountReconcilor::Shutdown"; |
| 224 merge_session_helper_.CancelAll(); | 218 merge_session_helper_.CancelAll(); |
| 225 merge_session_helper_.RemoveObserver(this); | 219 merge_session_helper_.RemoveObserver(this); |
| 226 gaia_fetcher_.reset(); | 220 gaia_fetcher_.reset(); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 244 void AccountReconcilor::DeleteFetchers() { | 238 void AccountReconcilor::DeleteFetchers() { |
| 245 delete[] requests_; | 239 delete[] requests_; |
| 246 requests_ = NULL; | 240 requests_ = NULL; |
| 247 | 241 |
| 248 user_id_fetchers_.clear(); | 242 user_id_fetchers_.clear(); |
| 249 refresh_token_fetchers_.clear(); | 243 refresh_token_fetchers_.clear(); |
| 250 } | 244 } |
| 251 | 245 |
| 252 bool AccountReconcilor::AreAllRefreshTokensChecked() const { | 246 bool AccountReconcilor::AreAllRefreshTokensChecked() const { |
| 253 return chrome_accounts_.size() == | 247 return chrome_accounts_.size() == |
| 254 (valid_chrome_accounts_.size() + invalid_chrome_accounts_.size()); | 248 (valid_chrome_accounts_.size() + invalid_chrome_accounts_.size()); |
| 255 } | 249 } |
| 256 | 250 |
| 257 void AccountReconcilor::RegisterForCookieChanges() { | 251 void AccountReconcilor::RegisterForCookieChanges() { |
| 258 client_->SetCookieChangedCallback( | 252 client_->SetCookieChangedCallback( |
| 259 base::Bind(&AccountReconcilor::OnCookieChanged, base::Unretained(this))); | 253 base::Bind(&AccountReconcilor::OnCookieChanged, base::Unretained(this))); |
| 260 } | 254 } |
| 261 | 255 |
| 262 void AccountReconcilor::UnregisterForCookieChanges() { | 256 void AccountReconcilor::UnregisterForCookieChanges() { |
| 263 client_->SetCookieChangedCallback(SigninClient::CookieChangedCallback()); | 257 client_->SetCookieChangedCallback(SigninClient::CookieChangedCallback()); |
| 264 } | 258 } |
| 265 | 259 |
| 266 void AccountReconcilor::RegisterWithSigninManager() { | 260 void AccountReconcilor::RegisterWithSigninManager() { |
| 267 SigninManagerBase* signin_manager = | 261 signin_manager_->AddObserver(this); |
| 268 SigninManagerFactory::GetForProfile(profile_); | |
| 269 signin_manager->AddObserver(this); | |
| 270 } | 262 } |
| 271 | 263 |
| 272 void AccountReconcilor::UnregisterWithSigninManager() { | 264 void AccountReconcilor::UnregisterWithSigninManager() { |
| 273 SigninManagerBase* signin_manager = | 265 signin_manager_->RemoveObserver(this); |
| 274 SigninManagerFactory::GetForProfile(profile_); | |
| 275 signin_manager->RemoveObserver(this); | |
| 276 } | 266 } |
| 277 | 267 |
| 278 void AccountReconcilor::RegisterWithTokenService() { | 268 void AccountReconcilor::RegisterWithTokenService() { |
| 279 VLOG(1) << "AccountReconcilor::RegisterWithTokenService"; | 269 VLOG(1) << "AccountReconcilor::RegisterWithTokenService"; |
| 280 // During re-auth, the reconcilor will get a callback about successful signin | 270 // During re-auth, the reconcilor will get a callback about successful signin |
| 281 // even when the profile is already connected. Avoid re-registering | 271 // even when the profile is already connected. Avoid re-registering |
| 282 // with the token service since this will DCHECK. | 272 // with the token service since this will DCHECK. |
| 283 if (registered_with_token_service_) | 273 if (registered_with_token_service_) |
| 284 return; | 274 return; |
| 285 | 275 |
| 286 ProfileOAuth2TokenService* token_service = | 276 token_service_->AddObserver(this); |
| 287 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); | |
| 288 token_service->AddObserver(this); | |
| 289 registered_with_token_service_ = true; | 277 registered_with_token_service_ = true; |
| 290 } | 278 } |
| 291 | 279 |
| 292 void AccountReconcilor::UnregisterWithTokenService() { | 280 void AccountReconcilor::UnregisterWithTokenService() { |
| 293 if (!registered_with_token_service_) | 281 if (!registered_with_token_service_) |
| 294 return; | 282 return; |
| 295 | 283 |
| 296 ProfileOAuth2TokenService* token_service = | 284 token_service_->RemoveObserver(this); |
| 297 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); | |
| 298 token_service->RemoveObserver(this); | |
| 299 registered_with_token_service_ = false; | 285 registered_with_token_service_ = false; |
| 300 } | 286 } |
| 301 | 287 |
| 302 bool AccountReconcilor::IsProfileConnected() { | 288 bool AccountReconcilor::IsUserSignedIn() { |
| 303 return !SigninManagerFactory::GetForProfile(profile_)-> | 289 return !signin_manager_->GetAuthenticatedUsername().empty(); |
| 304 GetAuthenticatedUsername().empty(); | |
| 305 } | 290 } |
| 306 | 291 |
| 307 void AccountReconcilor::StartPeriodicReconciliation() { | 292 void AccountReconcilor::StartPeriodicReconciliation() { |
| 308 VLOG(1) << "AccountReconcilor::StartPeriodicReconciliation"; | 293 VLOG(1) << "AccountReconcilor::StartPeriodicReconciliation"; |
| 309 // TODO(rogerta): pick appropriate thread and timeout value. | 294 // TODO(rogerta): pick appropriate thread and timeout value. |
| 310 reconciliation_timer_.Start( | 295 reconciliation_timer_.Start(FROM_HERE, |
| 311 FROM_HERE, | 296 base::TimeDelta::FromSeconds(300), |
| 312 base::TimeDelta::FromSeconds(300), | 297 this, |
| 313 this, | 298 &AccountReconcilor::PeriodicReconciliation); |
| 314 &AccountReconcilor::PeriodicReconciliation); | |
| 315 } | 299 } |
| 316 | 300 |
| 317 void AccountReconcilor::StopPeriodicReconciliation() { | 301 void AccountReconcilor::StopPeriodicReconciliation() { |
| 318 VLOG(1) << "AccountReconcilor::StopPeriodicReconciliation"; | 302 VLOG(1) << "AccountReconcilor::StopPeriodicReconciliation"; |
| 319 reconciliation_timer_.Stop(); | 303 reconciliation_timer_.Stop(); |
| 320 } | 304 } |
| 321 | 305 |
| 322 void AccountReconcilor::PeriodicReconciliation() { | 306 void AccountReconcilor::PeriodicReconciliation() { |
| 323 VLOG(1) << "AccountReconcilor::PeriodicReconciliation"; | 307 VLOG(1) << "AccountReconcilor::PeriodicReconciliation"; |
| 324 StartReconcile(); | 308 StartReconcile(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 338 StartReconcile(); | 322 StartReconcile(); |
| 339 } | 323 } |
| 340 | 324 |
| 341 void AccountReconcilor::OnRefreshTokenRevoked(const std::string& account_id) { | 325 void AccountReconcilor::OnRefreshTokenRevoked(const std::string& account_id) { |
| 342 VLOG(1) << "AccountReconcilor::OnRefreshTokenRevoked: " << account_id; | 326 VLOG(1) << "AccountReconcilor::OnRefreshTokenRevoked: " << account_id; |
| 343 StartRemoveAction(account_id); | 327 StartRemoveAction(account_id); |
| 344 } | 328 } |
| 345 | 329 |
| 346 void AccountReconcilor::OnRefreshTokensLoaded() {} | 330 void AccountReconcilor::OnRefreshTokensLoaded() {} |
| 347 | 331 |
| 348 void AccountReconcilor::GoogleSigninSucceeded( | 332 void AccountReconcilor::GoogleSigninSucceeded(const std::string& username, |
| 349 const std::string& username, const std::string& password) { | 333 const std::string& password) { |
| 350 VLOG(1) << "AccountReconcilor::GoogleSigninSucceeded: signed in"; | 334 VLOG(1) << "AccountReconcilor::GoogleSigninSucceeded: signed in"; |
| 351 RegisterForCookieChanges(); | 335 RegisterForCookieChanges(); |
| 352 RegisterWithTokenService(); | 336 RegisterWithTokenService(); |
| 353 StartPeriodicReconciliation(); | 337 StartPeriodicReconciliation(); |
| 354 } | 338 } |
| 355 | 339 |
| 356 void AccountReconcilor::GoogleSignedOut(const std::string& username) { | 340 void AccountReconcilor::GoogleSignedOut(const std::string& username) { |
| 357 VLOG(1) << "AccountReconcilor::GoogleSignedOut: signed out"; | 341 VLOG(1) << "AccountReconcilor::GoogleSignedOut: signed out"; |
| 358 UnregisterWithTokenService(); | 342 UnregisterWithTokenService(); |
| 359 UnregisterForCookieChanges(); | 343 UnregisterForCookieChanges(); |
| 360 StopPeriodicReconciliation(); | 344 StopPeriodicReconciliation(); |
| 361 } | 345 } |
| 362 | 346 |
| 363 void AccountReconcilor::PerformMergeAction(const std::string& account_id) { | 347 void AccountReconcilor::PerformMergeAction(const std::string& account_id) { |
| 364 VLOG(1) << "AccountReconcilor::PerformMergeAction: " << account_id; | 348 VLOG(1) << "AccountReconcilor::PerformMergeAction: " << account_id; |
| 365 merge_session_helper_.LogIn(account_id); | 349 merge_session_helper_.LogIn(account_id); |
| 366 } | 350 } |
| 367 | 351 |
| 368 void AccountReconcilor::StartRemoveAction(const std::string& account_id) { | 352 void AccountReconcilor::StartRemoveAction(const std::string& account_id) { |
| 369 VLOG(1) << "AccountReconcilor::StartRemoveAction: " << account_id; | 353 VLOG(1) << "AccountReconcilor::StartRemoveAction: " << account_id; |
| 370 GetAccountsFromCookie( | 354 GetAccountsFromCookie(base::Bind(&AccountReconcilor::FinishRemoveAction, |
| 371 base::Bind(&AccountReconcilor::FinishRemoveAction, | 355 base::Unretained(this), |
| 372 base::Unretained(this), | 356 account_id)); |
| 373 account_id)); | |
| 374 } | 357 } |
| 375 | 358 |
| 376 void AccountReconcilor::FinishRemoveAction( | 359 void AccountReconcilor::FinishRemoveAction( |
| 377 const std::string& account_id, | 360 const std::string& account_id, |
| 378 const GoogleServiceAuthError& error, | 361 const GoogleServiceAuthError& error, |
| 379 const std::vector<std::pair<std::string, bool> >& accounts) { | 362 const std::vector<std::pair<std::string, bool> >& accounts) { |
| 380 VLOG(1) << "AccountReconcilor::FinishRemoveAction:" | 363 VLOG(1) << "AccountReconcilor::FinishRemoveAction:" |
| 381 << " account=" << account_id | 364 << " account=" << account_id << " error=" << error.ToString(); |
| 382 << " error=" << error.ToString(); | |
| 383 if (error.state() == GoogleServiceAuthError::NONE) { | 365 if (error.state() == GoogleServiceAuthError::NONE) { |
| 384 AbortReconcile(); | 366 AbortReconcile(); |
| 385 std::vector<std::string> accounts_only; | 367 std::vector<std::string> accounts_only; |
| 386 for (std::vector<std::pair<std::string, bool> >::const_iterator i = | 368 for (std::vector<std::pair<std::string, bool> >::const_iterator i = |
| 387 accounts.begin(); i != accounts.end(); ++i) { | 369 accounts.begin(); |
| 370 i != accounts.end(); |
| 371 ++i) { |
| 388 accounts_only.push_back(i->first); | 372 accounts_only.push_back(i->first); |
| 389 } | 373 } |
| 390 merge_session_helper_.LogOut(account_id, accounts_only); | 374 merge_session_helper_.LogOut(account_id, accounts_only); |
| 391 } | 375 } |
| 392 // Wait for the next ReconcileAction if there is an error. | 376 // Wait for the next ReconcileAction if there is an error. |
| 393 } | 377 } |
| 394 | 378 |
| 395 void AccountReconcilor::PerformAddToChromeAction( | 379 void AccountReconcilor::PerformAddToChromeAction(const std::string& account_id, |
| 396 const std::string& account_id, | 380 int session_index) { |
| 397 int session_index) { | |
| 398 VLOG(1) << "AccountReconcilor::PerformAddToChromeAction:" | 381 VLOG(1) << "AccountReconcilor::PerformAddToChromeAction:" |
| 399 << " account=" << account_id | 382 << " account=" << account_id << " session_index=" << session_index; |
| 400 << " session_index=" << session_index; | |
| 401 | 383 |
| 402 #if !defined(OS_ANDROID) && !defined(OS_IOS) | 384 #if !defined(OS_ANDROID) && !defined(OS_IOS) |
| 403 refresh_token_fetchers_.push_back( | 385 refresh_token_fetchers_.push_back( |
| 404 new RefreshTokenFetcher(this, account_id, session_index)); | 386 new RefreshTokenFetcher(this, account_id, session_index)); |
| 405 #endif | 387 #endif |
| 406 } | 388 } |
| 407 | 389 |
| 408 void AccountReconcilor::PerformLogoutAllAccountsAction() { | 390 void AccountReconcilor::PerformLogoutAllAccountsAction() { |
| 409 VLOG(1) << "AccountReconcilor::PerformLogoutAllAccountsAction"; | 391 VLOG(1) << "AccountReconcilor::PerformLogoutAllAccountsAction"; |
| 410 merge_session_helper_.LogOutAllAccounts(); | 392 merge_session_helper_.LogOutAllAccounts(); |
| 411 } | 393 } |
| 412 | 394 |
| 413 void AccountReconcilor::StartReconcile() { | 395 void AccountReconcilor::StartReconcile() { |
| 414 if (!IsProfileConnected() || is_reconcile_started_) | 396 if (!IsUserSignedIn() || is_reconcile_started_) |
| 415 return; | 397 return; |
| 416 | 398 |
| 417 is_reconcile_started_ = true; | 399 is_reconcile_started_ = true; |
| 418 | 400 |
| 419 // Reset state for validating gaia cookie. | 401 // Reset state for validating gaia cookie. |
| 420 are_gaia_accounts_set_ = false; | 402 are_gaia_accounts_set_ = false; |
| 421 gaia_accounts_.clear(); | 403 gaia_accounts_.clear(); |
| 422 GetAccountsFromCookie(base::Bind( | 404 GetAccountsFromCookie(base::Bind( |
| 423 &AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts, | 405 &AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts, |
| 424 base::Unretained(this))); | 406 base::Unretained(this))); |
| 425 | 407 |
| 426 // Reset state for validating oauth2 tokens. | 408 // Reset state for validating oauth2 tokens. |
| 427 primary_account_.clear(); | 409 primary_account_.clear(); |
| 428 chrome_accounts_.clear(); | 410 chrome_accounts_.clear(); |
| 429 DeleteFetchers(); | 411 DeleteFetchers(); |
| 430 valid_chrome_accounts_.clear(); | 412 valid_chrome_accounts_.clear(); |
| 431 invalid_chrome_accounts_.clear(); | 413 invalid_chrome_accounts_.clear(); |
| 432 add_to_cookie_.clear(); | 414 add_to_cookie_.clear(); |
| 433 add_to_chrome_.clear(); | 415 add_to_chrome_.clear(); |
| 434 ValidateAccountsFromTokenService(); | 416 ValidateAccountsFromTokenService(); |
| 435 } | 417 } |
| 436 | 418 |
| 437 void AccountReconcilor::GetAccountsFromCookie( | 419 void AccountReconcilor::GetAccountsFromCookie( |
| 438 GetAccountsFromCookieCallback callback) { | 420 GetAccountsFromCookieCallback callback) { |
| 439 get_gaia_accounts_callbacks_.push_back(callback); | 421 get_gaia_accounts_callbacks_.push_back(callback); |
| 440 if (!gaia_fetcher_) { | 422 if (!gaia_fetcher_) { |
| 441 // There is no list account request in flight. | 423 // There is no list account request in flight. |
| 442 gaia_fetcher_.reset(new GaiaAuthFetcher(this, GaiaConstants::kChromeSource, | 424 gaia_fetcher_.reset(new GaiaAuthFetcher( |
| 443 profile_->GetRequestContext())); | 425 this, GaiaConstants::kChromeSource, client_->GetURLRequestContext())); |
| 444 gaia_fetcher_->StartListAccounts(); | 426 gaia_fetcher_->StartListAccounts(); |
| 445 } | 427 } |
| 446 } | 428 } |
| 447 | 429 |
| 448 void AccountReconcilor::OnListAccountsSuccess(const std::string& data) { | 430 void AccountReconcilor::OnListAccountsSuccess(const std::string& data) { |
| 449 gaia_fetcher_.reset(); | 431 gaia_fetcher_.reset(); |
| 450 | 432 |
| 451 // Get account information from response data. | 433 // Get account information from response data. |
| 452 std::vector<std::pair<std::string, bool> > gaia_accounts; | 434 std::vector<std::pair<std::string, bool> > gaia_accounts; |
| 453 bool valid_json = gaia::ParseListAccountsData(data, &gaia_accounts); | 435 bool valid_json = gaia::ParseListAccountsData(data, &gaia_accounts); |
| 454 if (!valid_json) { | 436 if (!valid_json) { |
| 455 VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: parsing error"; | 437 VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: parsing error"; |
| 456 } else if (gaia_accounts.size() > 0) { | 438 } else if (gaia_accounts.size() > 0) { |
| 457 VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: " | 439 VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: " |
| 458 << "Gaia " << gaia_accounts.size() << " accounts, " | 440 << "Gaia " << gaia_accounts.size() << " accounts, " |
| 459 << "Primary is '" << gaia_accounts[0].first << "'"; | 441 << "Primary is '" << gaia_accounts[0].first << "'"; |
| 460 } else { | 442 } else { |
| 461 VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: No accounts"; | 443 VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: No accounts"; |
| 462 } | 444 } |
| 463 | 445 |
| 464 // There must be at least one callback waiting for result. | 446 // There must be at least one callback waiting for result. |
| 465 DCHECK(!get_gaia_accounts_callbacks_.empty()); | 447 DCHECK(!get_gaia_accounts_callbacks_.empty()); |
| 466 | 448 |
| 467 GoogleServiceAuthError error = !valid_json | 449 GoogleServiceAuthError error = |
| 468 ? GoogleServiceAuthError( | 450 !valid_json ? GoogleServiceAuthError( |
| 469 GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE) | 451 GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE) |
| 470 : GoogleServiceAuthError::AuthErrorNone(); | 452 : GoogleServiceAuthError::AuthErrorNone(); |
| 471 get_gaia_accounts_callbacks_.front().Run(error, gaia_accounts); | 453 get_gaia_accounts_callbacks_.front().Run(error, gaia_accounts); |
| 472 get_gaia_accounts_callbacks_.pop_front(); | 454 get_gaia_accounts_callbacks_.pop_front(); |
| 473 | 455 |
| 474 MayBeDoNextListAccounts(); | 456 MayBeDoNextListAccounts(); |
| 475 } | 457 } |
| 476 | 458 |
| 477 void AccountReconcilor::OnListAccountsFailure( | 459 void AccountReconcilor::OnListAccountsFailure( |
| 478 const GoogleServiceAuthError& error) { | 460 const GoogleServiceAuthError& error) { |
| 479 gaia_fetcher_.reset(); | 461 gaia_fetcher_.reset(); |
| 480 VLOG(1) << "AccountReconcilor::OnListAccountsFailure: " << error.ToString(); | 462 VLOG(1) << "AccountReconcilor::OnListAccountsFailure: " << error.ToString(); |
| 481 std::vector<std::pair<std::string, bool> > empty_accounts; | 463 std::vector<std::pair<std::string, bool> > empty_accounts; |
| 482 | 464 |
| 483 // There must be at least one callback waiting for result. | 465 // There must be at least one callback waiting for result. |
| 484 DCHECK(!get_gaia_accounts_callbacks_.empty()); | 466 DCHECK(!get_gaia_accounts_callbacks_.empty()); |
| 485 | 467 |
| 486 get_gaia_accounts_callbacks_.front().Run(error, empty_accounts); | 468 get_gaia_accounts_callbacks_.front().Run(error, empty_accounts); |
| 487 get_gaia_accounts_callbacks_.pop_front(); | 469 get_gaia_accounts_callbacks_.pop_front(); |
| 488 | 470 |
| 489 MayBeDoNextListAccounts(); | 471 MayBeDoNextListAccounts(); |
| 490 } | 472 } |
| 491 | 473 |
| 492 void AccountReconcilor::MayBeDoNextListAccounts() { | 474 void AccountReconcilor::MayBeDoNextListAccounts() { |
| 493 if (!get_gaia_accounts_callbacks_.empty()) { | 475 if (!get_gaia_accounts_callbacks_.empty()) { |
| 494 gaia_fetcher_.reset(new GaiaAuthFetcher(this, GaiaConstants::kChromeSource, | 476 gaia_fetcher_.reset(new GaiaAuthFetcher( |
| 495 profile_->GetRequestContext())); | 477 this, GaiaConstants::kChromeSource, client_->GetURLRequestContext())); |
| 496 gaia_fetcher_->StartListAccounts(); | 478 gaia_fetcher_->StartListAccounts(); |
| 497 } | 479 } |
| 498 } | 480 } |
| 499 | 481 |
| 500 void AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts( | 482 void AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts( |
| 501 const GoogleServiceAuthError& error, | 483 const GoogleServiceAuthError& error, |
| 502 const std::vector<std::pair<std::string, bool> >& accounts) { | 484 const std::vector<std::pair<std::string, bool> >& accounts) { |
| 503 if (error.state() == GoogleServiceAuthError::NONE) { | 485 if (error.state() == GoogleServiceAuthError::NONE) { |
| 504 gaia_accounts_ = accounts; | 486 gaia_accounts_ = accounts; |
| 505 are_gaia_accounts_set_ = true; | 487 are_gaia_accounts_set_ = true; |
| 506 FinishReconcile(); | 488 FinishReconcile(); |
| 507 } else { | 489 } else { |
| 508 AbortReconcile(); | 490 AbortReconcile(); |
| 509 } | 491 } |
| 510 } | 492 } |
| 511 | 493 |
| 512 void AccountReconcilor::ValidateAccountsFromTokenService() { | 494 void AccountReconcilor::ValidateAccountsFromTokenService() { |
| 513 primary_account_ = | 495 primary_account_ = signin_manager_->GetAuthenticatedUsername(); |
| 514 SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername(); | |
| 515 DCHECK(!primary_account_.empty()); | 496 DCHECK(!primary_account_.empty()); |
| 516 | 497 |
| 517 ProfileOAuth2TokenService* token_service = | 498 chrome_accounts_ = token_service_->GetAccounts(); |
| 518 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); | |
| 519 chrome_accounts_ = token_service->GetAccounts(); | |
| 520 DCHECK_GT(chrome_accounts_.size(), 0u); | 499 DCHECK_GT(chrome_accounts_.size(), 0u); |
| 521 | 500 |
| 522 VLOG(1) << "AccountReconcilor::ValidateAccountsFromTokenService: " | 501 VLOG(1) << "AccountReconcilor::ValidateAccountsFromTokenService: " |
| 523 << "Chrome " << chrome_accounts_.size() << " accounts, " | 502 << "Chrome " << chrome_accounts_.size() << " accounts, " |
| 524 << "Primary is '" << primary_account_ << "'"; | 503 << "Primary is '" << primary_account_ << "'"; |
| 525 | 504 |
| 526 DCHECK(!requests_); | 505 DCHECK(!requests_); |
| 527 requests_ = | 506 requests_ = |
| 528 new scoped_ptr<OAuth2TokenService::Request>[chrome_accounts_.size()]; | 507 new scoped_ptr<OAuth2TokenService::Request>[chrome_accounts_.size()]; |
| 529 const OAuth2TokenService::ScopeSet scopes = | 508 const OAuth2TokenService::ScopeSet scopes = |
| 530 AccountReconcilor::UserIdFetcher::GetScopes(); | 509 AccountReconcilor::UserIdFetcher::GetScopes(); |
| 531 for (size_t i = 0; i < chrome_accounts_.size(); ++i) { | 510 for (size_t i = 0; i < chrome_accounts_.size(); ++i) { |
| 532 requests_[i] = token_service->StartRequest(chrome_accounts_[i], | 511 requests_[i] = |
| 533 scopes, | 512 token_service_->StartRequest(chrome_accounts_[i], scopes, this); |
| 534 this); | |
| 535 } | 513 } |
| 536 | 514 |
| 537 DCHECK_EQ(0u, user_id_fetchers_.size()); | 515 DCHECK_EQ(0u, user_id_fetchers_.size()); |
| 538 user_id_fetchers_.resize(chrome_accounts_.size()); | 516 user_id_fetchers_.resize(chrome_accounts_.size()); |
| 539 } | 517 } |
| 540 | 518 |
| 541 void AccountReconcilor::OnGetTokenSuccess( | 519 void AccountReconcilor::OnGetTokenSuccess( |
| 542 const OAuth2TokenService::Request* request, | 520 const OAuth2TokenService::Request* request, |
| 543 const std::string& access_token, | 521 const std::string& access_token, |
| 544 const base::Time& expiration_time) { | 522 const base::Time& expiration_time) { |
| 545 size_t index; | 523 size_t index; |
| 546 for (index = 0; index < chrome_accounts_.size(); ++index) { | 524 for (index = 0; index < chrome_accounts_.size(); ++index) { |
| 547 if (request == requests_[index].get()) | 525 if (request == requests_[index].get()) |
| 548 break; | 526 break; |
| 549 } | 527 } |
| 550 DCHECK(index < chrome_accounts_.size()); | 528 DCHECK(index < chrome_accounts_.size()); |
| 551 | 529 |
| 552 const std::string& account_id = chrome_accounts_[index]; | 530 const std::string& account_id = chrome_accounts_[index]; |
| 553 | 531 |
| 554 VLOG(1) << "AccountReconcilor::OnGetTokenSuccess: valid " << account_id; | 532 VLOG(1) << "AccountReconcilor::OnGetTokenSuccess: valid " << account_id; |
| 555 | 533 |
| 556 DCHECK(!user_id_fetchers_[index]); | 534 DCHECK(!user_id_fetchers_[index]); |
| 557 user_id_fetchers_[index] = | 535 user_id_fetchers_[index] = new UserIdFetcher(this, access_token, account_id); |
| 558 new UserIdFetcher(this, access_token, account_id); | |
| 559 } | 536 } |
| 560 | 537 |
| 561 void AccountReconcilor::OnGetTokenFailure( | 538 void AccountReconcilor::OnGetTokenFailure( |
| 562 const OAuth2TokenService::Request* request, | 539 const OAuth2TokenService::Request* request, |
| 563 const GoogleServiceAuthError& error) { | 540 const GoogleServiceAuthError& error) { |
| 564 size_t index; | 541 size_t index; |
| 565 for (index = 0; index < chrome_accounts_.size(); ++index) { | 542 for (index = 0; index < chrome_accounts_.size(); ++index) { |
| 566 if (request == requests_[index].get()) | 543 if (request == requests_[index].get()) |
| 567 break; | 544 break; |
| 568 } | 545 } |
| 569 DCHECK(index < chrome_accounts_.size()); | 546 DCHECK(index < chrome_accounts_.size()); |
| 570 | 547 |
| 571 const std::string& account_id = chrome_accounts_[index]; | 548 const std::string& account_id = chrome_accounts_[index]; |
| 572 | 549 |
| 573 VLOG(1) << "AccountReconcilor::OnGetTokenFailure: invalid " | 550 VLOG(1) << "AccountReconcilor::OnGetTokenFailure: invalid " << account_id; |
| 574 << account_id; | |
| 575 HandleFailedAccountIdCheck(account_id); | 551 HandleFailedAccountIdCheck(account_id); |
| 576 } | 552 } |
| 577 | 553 |
| 578 void AccountReconcilor::FinishReconcile() { | 554 void AccountReconcilor::FinishReconcile() { |
| 579 // Make sure that the process of validating the gaia cookie and the oauth2 | 555 // Make sure that the process of validating the gaia cookie and the oauth2 |
| 580 // tokens individually is done before proceeding with reconciliation. | 556 // tokens individually is done before proceeding with reconciliation. |
| 581 if (!are_gaia_accounts_set_ || !AreAllRefreshTokensChecked()) | 557 if (!are_gaia_accounts_set_ || !AreAllRefreshTokensChecked()) |
| 582 return; | 558 return; |
| 583 | 559 |
| 584 VLOG(1) << "AccountReconcilor::FinishReconcile"; | 560 VLOG(1) << "AccountReconcilor::FinishReconcile"; |
| 585 | 561 |
| 586 DeleteFetchers(); | 562 DeleteFetchers(); |
| 587 | 563 |
| 588 DCHECK(add_to_cookie_.empty()); | 564 DCHECK(add_to_cookie_.empty()); |
| 589 DCHECK(add_to_chrome_.empty()); | 565 DCHECK(add_to_chrome_.empty()); |
| 590 bool are_primaries_equal = | 566 bool are_primaries_equal = |
| 591 gaia_accounts_.size() > 0 && | 567 gaia_accounts_.size() > 0 && |
| 592 gaia::AreEmailsSame(primary_account_, gaia_accounts_[0].first); | 568 gaia::AreEmailsSame(primary_account_, gaia_accounts_[0].first); |
| 593 | 569 |
| 594 if (are_primaries_equal) { | 570 if (are_primaries_equal) { |
| 595 // Determine if we need to merge accounts from gaia cookie to chrome. | 571 // Determine if we need to merge accounts from gaia cookie to chrome. |
| 596 for (size_t i = 0; i < gaia_accounts_.size(); ++i) { | 572 for (size_t i = 0; i < gaia_accounts_.size(); ++i) { |
| 597 const std::string& gaia_account = gaia_accounts_[i].first; | 573 const std::string& gaia_account = gaia_accounts_[i].first; |
| 598 if (gaia_accounts_[i].second && | 574 if (gaia_accounts_[i].second && |
| 599 valid_chrome_accounts_.find(gaia_account) == | 575 valid_chrome_accounts_.find(gaia_account) == |
| 600 valid_chrome_accounts_.end()) { | 576 valid_chrome_accounts_.end()) { |
| 601 add_to_chrome_.push_back(std::make_pair(gaia_account, i)); | 577 add_to_chrome_.push_back(std::make_pair(gaia_account, i)); |
| 602 } | 578 } |
| 603 } | 579 } |
| 604 | 580 |
| 605 // Determine if we need to merge accounts from chrome into gaia cookie. | 581 // Determine if we need to merge accounts from chrome into gaia cookie. |
| 606 for (EmailSet::const_iterator i = valid_chrome_accounts_.begin(); | 582 for (EmailSet::const_iterator i = valid_chrome_accounts_.begin(); |
| 607 i != valid_chrome_accounts_.end(); ++i) { | 583 i != valid_chrome_accounts_.end(); |
| 584 ++i) { |
| 608 bool add_to_cookie = true; | 585 bool add_to_cookie = true; |
| 609 for (size_t j = 0; j < gaia_accounts_.size(); ++j) { | 586 for (size_t j = 0; j < gaia_accounts_.size(); ++j) { |
| 610 if (gaia::AreEmailsSame(gaia_accounts_[j].first, *i)) { | 587 if (gaia::AreEmailsSame(gaia_accounts_[j].first, *i)) { |
| 611 add_to_cookie = !gaia_accounts_[j].second; | 588 add_to_cookie = !gaia_accounts_[j].second; |
| 612 break; | 589 break; |
| 613 } | 590 } |
| 614 } | 591 } |
| 615 if (add_to_cookie) | 592 if (add_to_cookie) |
| 616 add_to_cookie_.push_back(*i); | 593 add_to_cookie_.push_back(*i); |
| 617 } | 594 } |
| 618 } else { | 595 } else { |
| 619 VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie"; | 596 VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie"; |
| 620 // Really messed up state. Blow away the gaia cookie completely and | 597 // Really messed up state. Blow away the gaia cookie completely and |
| 621 // rebuild it, making sure the primary account as specified by the | 598 // rebuild it, making sure the primary account as specified by the |
| 622 // SigninManager is the first session in the gaia cookie. | 599 // SigninManager is the first session in the gaia cookie. |
| 623 PerformLogoutAllAccountsAction(); | 600 PerformLogoutAllAccountsAction(); |
| 624 add_to_cookie_.push_back(primary_account_); | 601 add_to_cookie_.push_back(primary_account_); |
| 625 for (EmailSet::const_iterator i = valid_chrome_accounts_.begin(); | 602 for (EmailSet::const_iterator i = valid_chrome_accounts_.begin(); |
| 626 i != valid_chrome_accounts_.end(); ++i) { | 603 i != valid_chrome_accounts_.end(); |
| 604 ++i) { |
| 627 if (*i != primary_account_) | 605 if (*i != primary_account_) |
| 628 add_to_cookie_.push_back(*i); | 606 add_to_cookie_.push_back(*i); |
| 629 } | 607 } |
| 630 } | 608 } |
| 631 | 609 |
| 632 // For each account known to chrome but not in the gaia cookie, | 610 // For each account known to chrome but not in the gaia cookie, |
| 633 // PerformMergeAction(). | 611 // PerformMergeAction(). |
| 634 for (size_t i = 0; i < add_to_cookie_.size(); ++i) | 612 for (size_t i = 0; i < add_to_cookie_.size(); ++i) |
| 635 PerformMergeAction(add_to_cookie_[i]); | 613 PerformMergeAction(add_to_cookie_[i]); |
| 636 | 614 |
| 637 // For each account in the gaia cookie not known to chrome, | 615 // For each account in the gaia cookie not known to chrome, |
| 638 // PerformAddToChromeAction. | 616 // PerformAddToChromeAction. |
| 639 for (std::vector<std::pair<std::string, int> >::const_iterator i = | 617 for (std::vector<std::pair<std::string, int> >::const_iterator i = |
| 640 add_to_chrome_.begin(); | 618 add_to_chrome_.begin(); |
| 641 i != add_to_chrome_.end(); ++i) { | 619 i != add_to_chrome_.end(); |
| 620 ++i) { |
| 642 PerformAddToChromeAction(i->first, i->second); | 621 PerformAddToChromeAction(i->first, i->second); |
| 643 } | 622 } |
| 644 | 623 |
| 645 CalculateIfReconcileIsDone(); | 624 CalculateIfReconcileIsDone(); |
| 646 ScheduleStartReconcileIfChromeAccountsChanged(); | 625 ScheduleStartReconcileIfChromeAccountsChanged(); |
| 647 } | 626 } |
| 648 | 627 |
| 649 void AccountReconcilor::AbortReconcile() { | 628 void AccountReconcilor::AbortReconcile() { |
| 650 VLOG(1) << "AccountReconcilor::AbortReconcile: we'll try again later"; | 629 VLOG(1) << "AccountReconcilor::AbortReconcile: we'll try again later"; |
| 651 DeleteFetchers(); | 630 DeleteFetchers(); |
| 652 add_to_cookie_.clear(); | 631 add_to_cookie_.clear(); |
| 653 add_to_chrome_.clear(); | 632 add_to_chrome_.clear(); |
| 654 CalculateIfReconcileIsDone(); | 633 CalculateIfReconcileIsDone(); |
| 655 } | 634 } |
| 656 | 635 |
| 657 void AccountReconcilor::CalculateIfReconcileIsDone() { | 636 void AccountReconcilor::CalculateIfReconcileIsDone() { |
| 658 is_reconcile_started_ = !add_to_cookie_.empty() || !add_to_chrome_.empty(); | 637 is_reconcile_started_ = !add_to_cookie_.empty() || !add_to_chrome_.empty(); |
| 659 if (!is_reconcile_started_) | 638 if (!is_reconcile_started_) |
| 660 VLOG(1) << "AccountReconcilor::CalculateIfReconcileIsDone: done"; | 639 VLOG(1) << "AccountReconcilor::CalculateIfReconcileIsDone: done"; |
| 661 } | 640 } |
| 662 | 641 |
| 663 void AccountReconcilor::ScheduleStartReconcileIfChromeAccountsChanged() { | 642 void AccountReconcilor::ScheduleStartReconcileIfChromeAccountsChanged() { |
| 664 if (is_reconcile_started_) | 643 if (is_reconcile_started_) |
| 665 return; | 644 return; |
| 666 | 645 |
| 667 // Start a reconcile as the token accounts have changed. | 646 // Start a reconcile as the token accounts have changed. |
| 668 VLOG(1) << "AccountReconcilor::StartReconcileIfChromeAccountsChanged"; | 647 VLOG(1) << "AccountReconcilor::StartReconcileIfChromeAccountsChanged"; |
| 669 std::vector<std::string> reconciled_accounts(chrome_accounts_); | 648 std::vector<std::string> reconciled_accounts(chrome_accounts_); |
| 670 std::vector<std::string> new_chrome_accounts( | 649 std::vector<std::string> new_chrome_accounts(token_service_->GetAccounts()); |
| 671 ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->GetAccounts()); | |
| 672 std::sort(reconciled_accounts.begin(), reconciled_accounts.end()); | 650 std::sort(reconciled_accounts.begin(), reconciled_accounts.end()); |
| 673 std::sort(new_chrome_accounts.begin(), new_chrome_accounts.end()); | 651 std::sort(new_chrome_accounts.begin(), new_chrome_accounts.end()); |
| 674 if (reconciled_accounts != new_chrome_accounts) { | 652 if (reconciled_accounts != new_chrome_accounts) { |
| 675 base::MessageLoop::current()->PostTask( | 653 base::MessageLoop::current()->PostTask( |
| 676 FROM_HERE, | 654 FROM_HERE, |
| 677 base::Bind(&AccountReconcilor::StartReconcile, base::Unretained(this))); | 655 base::Bind(&AccountReconcilor::StartReconcile, base::Unretained(this))); |
| 678 } | 656 } |
| 679 } | 657 } |
| 680 | 658 |
| 681 void AccountReconcilor::MergeSessionCompleted( | 659 void AccountReconcilor::MergeSessionCompleted( |
| 682 const std::string& account_id, | 660 const std::string& account_id, |
| 683 const GoogleServiceAuthError& error) { | 661 const GoogleServiceAuthError& error) { |
| 684 VLOG(1) << "AccountReconcilor::MergeSessionCompleted: account_id=" | 662 VLOG(1) << "AccountReconcilor::MergeSessionCompleted: account_id=" |
| 685 << account_id; | 663 << account_id; |
| 686 | 664 |
| 687 // Remove the account from the list that is being merged. | 665 // Remove the account from the list that is being merged. |
| 688 for (std::vector<std::string>::iterator i = add_to_cookie_.begin(); | 666 for (std::vector<std::string>::iterator i = add_to_cookie_.begin(); |
| 689 i != add_to_cookie_.end(); ++i) { | 667 i != add_to_cookie_.end(); |
| 668 ++i) { |
| 690 if (account_id == *i) { | 669 if (account_id == *i) { |
| 691 add_to_cookie_.erase(i); | 670 add_to_cookie_.erase(i); |
| 692 break; | 671 break; |
| 693 } | 672 } |
| 694 } | 673 } |
| 695 | 674 |
| 696 CalculateIfReconcileIsDone(); | 675 CalculateIfReconcileIsDone(); |
| 697 ScheduleStartReconcileIfChromeAccountsChanged(); | 676 ScheduleStartReconcileIfChromeAccountsChanged(); |
| 698 } | 677 } |
| 699 | 678 |
| 700 void AccountReconcilor::HandleSuccessfulAccountIdCheck( | 679 void AccountReconcilor::HandleSuccessfulAccountIdCheck( |
| 701 const std::string& account_id) { | 680 const std::string& account_id) { |
| 702 valid_chrome_accounts_.insert(account_id); | 681 valid_chrome_accounts_.insert(account_id); |
| 703 FinishReconcile(); | 682 FinishReconcile(); |
| 704 } | 683 } |
| 705 | 684 |
| 706 void AccountReconcilor::HandleFailedAccountIdCheck( | 685 void AccountReconcilor::HandleFailedAccountIdCheck( |
| 707 const std::string& account_id) { | 686 const std::string& account_id) { |
| 708 invalid_chrome_accounts_.insert(account_id); | 687 invalid_chrome_accounts_.insert(account_id); |
| 709 FinishReconcile(); | 688 FinishReconcile(); |
| 710 } | 689 } |
| 711 | 690 |
| 712 void AccountReconcilor::HandleRefreshTokenFetched( | 691 void AccountReconcilor::HandleRefreshTokenFetched( |
| 713 const std::string& account_id, | 692 const std::string& account_id, |
| 714 const std::string& refresh_token) { | 693 const std::string& refresh_token) { |
| 715 if (!refresh_token.empty()) { | 694 if (!refresh_token.empty()) { |
| 716 ProfileOAuth2TokenService* token_service = | 695 token_service_->UpdateCredentials(account_id, refresh_token); |
| 717 ProfileOAuth2TokenServiceFactory::GetForProfile(profile()); | |
| 718 token_service->UpdateCredentials(account_id, refresh_token); | |
| 719 } | 696 } |
| 720 | 697 |
| 721 // Remove the account from the list that is being updated. | 698 // Remove the account from the list that is being updated. |
| 722 for (std::vector<std::pair<std::string, int> >::iterator i = | 699 for (std::vector<std::pair<std::string, int> >::iterator i = |
| 723 add_to_chrome_.begin(); | 700 add_to_chrome_.begin(); |
| 724 i != add_to_chrome_.end(); ++i) { | 701 i != add_to_chrome_.end(); |
| 702 ++i) { |
| 725 if (gaia::AreEmailsSame(account_id, i->first)) { | 703 if (gaia::AreEmailsSame(account_id, i->first)) { |
| 726 add_to_chrome_.erase(i); | 704 add_to_chrome_.erase(i); |
| 727 break; | 705 break; |
| 728 } | 706 } |
| 729 } | 707 } |
| 730 | 708 |
| 731 CalculateIfReconcileIsDone(); | 709 CalculateIfReconcileIsDone(); |
| 732 } | 710 } |
| OLD | NEW |