Index: chrome/browser/signin/account_reconcilor.cc |
diff --git a/chrome/browser/signin/account_reconcilor.cc b/chrome/browser/signin/account_reconcilor.cc |
deleted file mode 100644 |
index 7c1afbac74ac3abc1ee38b93bb414b2f6beadd69..0000000000000000000000000000000000000000 |
--- a/chrome/browser/signin/account_reconcilor.cc |
+++ /dev/null |
@@ -1,746 +0,0 @@ |
-// Copyright 2013 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "chrome/browser/signin/account_reconcilor.h" |
- |
-#include <algorithm> |
- |
-#include "base/bind.h" |
-#include "base/json/json_reader.h" |
-#include "base/logging.h" |
-#include "base/message_loop/message_loop.h" |
-#include "base/message_loop/message_loop_proxy.h" |
-#include "base/strings/string_number_conversions.h" |
-#include "base/time/time.h" |
-#include "chrome/browser/profiles/profile.h" |
-#include "chrome/browser/signin/profile_oauth2_token_service_factory.h" |
-#include "chrome/browser/signin/signin_manager_factory.h" |
-#include "chrome/browser/signin/signin_oauth_helper.h" |
-#include "components/signin/core/browser/profile_oauth2_token_service.h" |
-#include "components/signin/core/browser/signin_client.h" |
-#include "google_apis/gaia/gaia_auth_fetcher.h" |
-#include "google_apis/gaia/gaia_auth_util.h" |
-#include "google_apis/gaia/gaia_constants.h" |
-#include "google_apis/gaia/gaia_oauth_client.h" |
-#include "google_apis/gaia/gaia_urls.h" |
- |
-// Fetches a refresh token from the given session in the GAIA cookie. This is |
-// a best effort only. If it should fail, another reconcile action will occur |
-// shortly anyway. |
-class AccountReconcilor::RefreshTokenFetcher |
- : public SigninOAuthHelper, |
- public SigninOAuthHelper::Consumer { |
- public: |
- RefreshTokenFetcher(AccountReconcilor* reconcilor, |
- const std::string& account_id, |
- int session_index); |
- virtual ~RefreshTokenFetcher() {} |
- |
- private: |
- // Overridden from GaiaAuthConsumer: |
- virtual void OnSigninOAuthInformationAvailable( |
- const std::string& email, |
- const std::string& display_email, |
- const std::string& refresh_token) OVERRIDE; |
- |
- // Called when an error occurs while getting the information. |
- virtual void OnSigninOAuthInformationFailure( |
- const GoogleServiceAuthError& error) OVERRIDE; |
- |
- AccountReconcilor* reconcilor_; |
- const std::string account_id_; |
- int session_index_; |
- |
- DISALLOW_COPY_AND_ASSIGN(RefreshTokenFetcher); |
-}; |
- |
-AccountReconcilor::RefreshTokenFetcher::RefreshTokenFetcher( |
- AccountReconcilor* reconcilor, |
- const std::string& account_id, |
- int session_index) |
- : SigninOAuthHelper(reconcilor->profile()->GetRequestContext(), |
- base::IntToString(session_index), this), |
- reconcilor_(reconcilor), |
- account_id_(account_id), |
- session_index_(session_index) { |
- DCHECK(reconcilor_); |
- DCHECK(!account_id.empty()); |
-} |
- |
-void AccountReconcilor::RefreshTokenFetcher::OnSigninOAuthInformationAvailable( |
- const std::string& email, |
- const std::string& display_email, |
- const std::string& refresh_token) { |
- VLOG(1) << "RefreshTokenFetcher::OnSigninOAuthInformationAvailable:" |
- << " account=" << account_id_ |
- << " email=" << email |
- << " displayEmail=" << display_email; |
- |
- // TODO(rogerta): because of the problem with email vs displayEmail and |
- // emails that have been canonicalized, the argument |email| is used here |
- // to make sure the correct string is used when calling the token service. |
- // This will be cleaned up when chrome moves to using gaia obfuscated id. |
- reconcilor_->HandleRefreshTokenFetched(email, refresh_token); |
-} |
- |
-void AccountReconcilor::RefreshTokenFetcher::OnSigninOAuthInformationFailure( |
- const GoogleServiceAuthError& error) { |
- VLOG(1) << "RefreshTokenFetcher::OnSigninOAuthInformationFailure:" |
- << " account=" << account_id_ |
- << " session_index=" << session_index_; |
- reconcilor_->HandleRefreshTokenFetched(account_id_, std::string()); |
-} |
- |
- |
-bool AccountReconcilor::EmailLessFunc::operator()(const std::string& s1, |
- const std::string& s2) const { |
- return gaia::CanonicalizeEmail(s1) < gaia::CanonicalizeEmail(s2); |
-} |
- |
-class AccountReconcilor::UserIdFetcher |
- : public gaia::GaiaOAuthClient::Delegate { |
- public: |
- UserIdFetcher(AccountReconcilor* reconcilor, |
- const std::string& access_token, |
- const std::string& account_id); |
- |
- // Returns the scopes needed by the UserIdFetcher. |
- static OAuth2TokenService::ScopeSet GetScopes(); |
- |
- private: |
- // Overriden from gaia::GaiaOAuthClient::Delegate. |
- virtual void OnGetUserIdResponse(const std::string& user_id) OVERRIDE; |
- virtual void OnOAuthError() OVERRIDE; |
- virtual void OnNetworkError(int response_code) OVERRIDE; |
- |
- AccountReconcilor* const reconcilor_; |
- const std::string account_id_; |
- const std::string access_token_; |
- gaia::GaiaOAuthClient gaia_auth_client_; |
- |
- DISALLOW_COPY_AND_ASSIGN(UserIdFetcher); |
-}; |
- |
-AccountReconcilor::UserIdFetcher::UserIdFetcher(AccountReconcilor* reconcilor, |
- const std::string& access_token, |
- const std::string& account_id) |
- : reconcilor_(reconcilor), |
- account_id_(account_id), |
- access_token_(access_token), |
- gaia_auth_client_(reconcilor_->profile()->GetRequestContext()) { |
- DCHECK(reconcilor_); |
- DCHECK(!account_id_.empty()); |
- |
- const int kMaxRetries = 5; |
- gaia_auth_client_.GetUserId(access_token_, kMaxRetries, this); |
-} |
- |
-// static |
-OAuth2TokenService::ScopeSet AccountReconcilor::UserIdFetcher::GetScopes() { |
- OAuth2TokenService::ScopeSet scopes; |
- scopes.insert("https://www.googleapis.com/auth/userinfo.profile"); |
- return scopes; |
-} |
- |
-void AccountReconcilor::UserIdFetcher::OnGetUserIdResponse( |
- const std::string& user_id) { |
- VLOG(1) << "AccountReconcilor::OnGetUserIdResponse: " << account_id_; |
- |
- // HandleSuccessfulAccountIdCheck() may delete |this|, so call it last. |
- reconcilor_->HandleSuccessfulAccountIdCheck(account_id_); |
-} |
- |
-void AccountReconcilor::UserIdFetcher::OnOAuthError() { |
- VLOG(1) << "AccountReconcilor::OnOAuthError: " << account_id_; |
- |
- // Invalidate the access token to force a refetch next time. |
- ProfileOAuth2TokenService* token_service = |
- ProfileOAuth2TokenServiceFactory::GetForProfile(reconcilor_->profile()); |
- token_service->InvalidateToken(account_id_, GetScopes(), access_token_); |
- |
- // HandleFailedAccountIdCheck() may delete |this|, so call it last. |
- reconcilor_->HandleFailedAccountIdCheck(account_id_); |
-} |
- |
-void AccountReconcilor::UserIdFetcher::OnNetworkError(int response_code) { |
- VLOG(1) << "AccountReconcilor::OnNetworkError: " << account_id_ |
- << " response_code=" << response_code; |
- |
- // TODO(rogerta): some response error should not be treated like |
- // permanent errors. Figure out appropriate ones. |
- // HandleFailedAccountIdCheck() may delete |this|, so call it last. |
- reconcilor_->HandleFailedAccountIdCheck(account_id_); |
-} |
- |
-AccountReconcilor::AccountReconcilor(Profile* profile, SigninClient* client) |
- : OAuth2TokenService::Consumer("account_reconcilor"), |
- profile_(profile), |
- client_(client), |
- merge_session_helper_( |
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile), |
- profile->GetRequestContext(), |
- this), |
- registered_with_token_service_(false), |
- is_reconcile_started_(false), |
- are_gaia_accounts_set_(false), |
- requests_(NULL) { |
- VLOG(1) << "AccountReconcilor::AccountReconcilor"; |
-} |
- |
-AccountReconcilor::~AccountReconcilor() { |
- VLOG(1) << "AccountReconcilor::~AccountReconcilor"; |
- // Make sure shutdown was called first. |
- DCHECK(!registered_with_token_service_); |
- DCHECK(!reconciliation_timer_.IsRunning()); |
- DCHECK(!requests_); |
- DCHECK_EQ(0u, user_id_fetchers_.size()); |
- DCHECK_EQ(0u, refresh_token_fetchers_.size()); |
-} |
- |
-void AccountReconcilor::Initialize(bool start_reconcile_if_tokens_available) { |
- VLOG(1) << "AccountReconcilor::Initialize"; |
- RegisterWithSigninManager(); |
- |
- // If this profile is not connected, the reconcilor should do nothing but |
- // wait for the connection. |
- if (IsProfileConnected()) { |
- RegisterForCookieChanges(); |
- RegisterWithTokenService(); |
- StartPeriodicReconciliation(); |
- |
- // Start a reconcile if the tokens are already loaded. |
- ProfileOAuth2TokenService* token_service = |
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
- if (start_reconcile_if_tokens_available && |
- token_service->GetAccounts().size() > 0) { |
- StartReconcile(); |
- } |
- } |
-} |
- |
-void AccountReconcilor::Shutdown() { |
- VLOG(1) << "AccountReconcilor::Shutdown"; |
- merge_session_helper_.CancelAll(); |
- merge_session_helper_.RemoveObserver(this); |
- gaia_fetcher_.reset(); |
- DeleteFetchers(); |
- UnregisterWithSigninManager(); |
- UnregisterWithTokenService(); |
- UnregisterForCookieChanges(); |
- StopPeriodicReconciliation(); |
-} |
- |
-void AccountReconcilor::AddMergeSessionObserver( |
- MergeSessionHelper::Observer* observer) { |
- merge_session_helper_.AddObserver(observer); |
-} |
- |
-void AccountReconcilor::RemoveMergeSessionObserver( |
- MergeSessionHelper::Observer* observer) { |
- merge_session_helper_.RemoveObserver(observer); |
-} |
- |
-void AccountReconcilor::DeleteFetchers() { |
- delete[] requests_; |
- requests_ = NULL; |
- |
- user_id_fetchers_.clear(); |
- refresh_token_fetchers_.clear(); |
-} |
- |
-bool AccountReconcilor::AreAllRefreshTokensChecked() const { |
- return chrome_accounts_.size() == |
- (valid_chrome_accounts_.size() + invalid_chrome_accounts_.size()); |
-} |
- |
-void AccountReconcilor::RegisterForCookieChanges() { |
- // First clear any existing registration to avoid DCHECKs that can otherwise |
- // go off in some embedders on reauth (e.g., ChromeSigninClient). |
- UnregisterForCookieChanges(); |
- client_->SetCookieChangedCallback( |
- base::Bind(&AccountReconcilor::OnCookieChanged, base::Unretained(this))); |
-} |
- |
-void AccountReconcilor::UnregisterForCookieChanges() { |
- client_->SetCookieChangedCallback(SigninClient::CookieChangedCallback()); |
-} |
- |
-void AccountReconcilor::RegisterWithSigninManager() { |
- SigninManagerBase* signin_manager = |
- SigninManagerFactory::GetForProfile(profile_); |
- signin_manager->AddObserver(this); |
-} |
- |
-void AccountReconcilor::UnregisterWithSigninManager() { |
- SigninManagerBase* signin_manager = |
- SigninManagerFactory::GetForProfile(profile_); |
- signin_manager->RemoveObserver(this); |
-} |
- |
-void AccountReconcilor::RegisterWithTokenService() { |
- VLOG(1) << "AccountReconcilor::RegisterWithTokenService"; |
- // During re-auth, the reconcilor will get a callback about successful signin |
- // even when the profile is already connected. Avoid re-registering |
- // with the token service since this will DCHECK. |
- if (registered_with_token_service_) |
- return; |
- |
- ProfileOAuth2TokenService* token_service = |
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
- token_service->AddObserver(this); |
- registered_with_token_service_ = true; |
-} |
- |
-void AccountReconcilor::UnregisterWithTokenService() { |
- if (!registered_with_token_service_) |
- return; |
- |
- ProfileOAuth2TokenService* token_service = |
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
- token_service->RemoveObserver(this); |
- registered_with_token_service_ = false; |
-} |
- |
-bool AccountReconcilor::IsProfileConnected() { |
- return !SigninManagerFactory::GetForProfile(profile_)-> |
- GetAuthenticatedUsername().empty(); |
-} |
- |
-void AccountReconcilor::StartPeriodicReconciliation() { |
- VLOG(1) << "AccountReconcilor::StartPeriodicReconciliation"; |
- // TODO(rogerta): pick appropriate thread and timeout value. |
- reconciliation_timer_.Start( |
- FROM_HERE, |
- base::TimeDelta::FromSeconds(300), |
- this, |
- &AccountReconcilor::PeriodicReconciliation); |
-} |
- |
-void AccountReconcilor::StopPeriodicReconciliation() { |
- VLOG(1) << "AccountReconcilor::StopPeriodicReconciliation"; |
- reconciliation_timer_.Stop(); |
-} |
- |
-void AccountReconcilor::PeriodicReconciliation() { |
- VLOG(1) << "AccountReconcilor::PeriodicReconciliation"; |
- StartReconcile(); |
-} |
- |
-void AccountReconcilor::OnCookieChanged(const net::CanonicalCookie* cookie) { |
- if (cookie->Name() == "LSID" && |
- cookie->Domain() == GaiaUrls::GetInstance()->gaia_url().host() && |
- cookie->IsSecure() && cookie->IsHttpOnly()) { |
- VLOG(1) << "AccountReconcilor::OnCookieChanged: LSID changed"; |
-#ifdef OS_CHROMEOS |
- // On Chrome OS it is possible that O2RT is not available at this moment |
- // because profile data transfer is still in progress. |
- ProfileOAuth2TokenService* token_service = |
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
- if (!token_service->GetAccounts().size()) { |
- VLOG(1) << "AccountReconcilor::OnCookieChanged: cookie change is ingored" |
- "because profile data transfer is in progress."; |
- return; |
- } |
-#endif |
- StartReconcile(); |
- } |
-} |
- |
-void AccountReconcilor::OnRefreshTokenAvailable(const std::string& account_id) { |
- VLOG(1) << "AccountReconcilor::OnRefreshTokenAvailable: " << account_id; |
- StartReconcile(); |
-} |
- |
-void AccountReconcilor::OnRefreshTokenRevoked(const std::string& account_id) { |
- VLOG(1) << "AccountReconcilor::OnRefreshTokenRevoked: " << account_id; |
- StartRemoveAction(account_id); |
-} |
- |
-void AccountReconcilor::OnRefreshTokensLoaded() {} |
- |
-void AccountReconcilor::GoogleSigninSucceeded( |
- const std::string& username, const std::string& password) { |
- VLOG(1) << "AccountReconcilor::GoogleSigninSucceeded: signed in"; |
- RegisterForCookieChanges(); |
- RegisterWithTokenService(); |
- StartPeriodicReconciliation(); |
-} |
- |
-void AccountReconcilor::GoogleSignedOut(const std::string& username) { |
- VLOG(1) << "AccountReconcilor::GoogleSignedOut: signed out"; |
- UnregisterWithTokenService(); |
- UnregisterForCookieChanges(); |
- StopPeriodicReconciliation(); |
-} |
- |
-void AccountReconcilor::PerformMergeAction(const std::string& account_id) { |
- VLOG(1) << "AccountReconcilor::PerformMergeAction: " << account_id; |
- merge_session_helper_.LogIn(account_id); |
-} |
- |
-void AccountReconcilor::StartRemoveAction(const std::string& account_id) { |
- VLOG(1) << "AccountReconcilor::StartRemoveAction: " << account_id; |
- GetAccountsFromCookie( |
- base::Bind(&AccountReconcilor::FinishRemoveAction, |
- base::Unretained(this), |
- account_id)); |
-} |
- |
-void AccountReconcilor::FinishRemoveAction( |
- const std::string& account_id, |
- const GoogleServiceAuthError& error, |
- const std::vector<std::pair<std::string, bool> >& accounts) { |
- VLOG(1) << "AccountReconcilor::FinishRemoveAction:" |
- << " account=" << account_id |
- << " error=" << error.ToString(); |
- if (error.state() == GoogleServiceAuthError::NONE) { |
- AbortReconcile(); |
- std::vector<std::string> accounts_only; |
- for (std::vector<std::pair<std::string, bool> >::const_iterator i = |
- accounts.begin(); i != accounts.end(); ++i) { |
- accounts_only.push_back(i->first); |
- } |
- merge_session_helper_.LogOut(account_id, accounts_only); |
- } |
- // Wait for the next ReconcileAction if there is an error. |
-} |
- |
-void AccountReconcilor::PerformAddToChromeAction( |
- const std::string& account_id, |
- int session_index) { |
- VLOG(1) << "AccountReconcilor::PerformAddToChromeAction:" |
- << " account=" << account_id |
- << " session_index=" << session_index; |
- |
-#if !defined(OS_ANDROID) && !defined(OS_IOS) |
- refresh_token_fetchers_.push_back( |
- new RefreshTokenFetcher(this, account_id, session_index)); |
-#endif |
-} |
- |
-void AccountReconcilor::PerformLogoutAllAccountsAction() { |
- VLOG(1) << "AccountReconcilor::PerformLogoutAllAccountsAction"; |
- merge_session_helper_.LogOutAllAccounts(); |
-} |
- |
-void AccountReconcilor::StartReconcile() { |
- if (!IsProfileConnected() || is_reconcile_started_) |
- return; |
- |
- is_reconcile_started_ = true; |
- |
- // Reset state for validating gaia cookie. |
- are_gaia_accounts_set_ = false; |
- gaia_accounts_.clear(); |
- GetAccountsFromCookie(base::Bind( |
- &AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts, |
- base::Unretained(this))); |
- |
- // Reset state for validating oauth2 tokens. |
- primary_account_.clear(); |
- chrome_accounts_.clear(); |
- DeleteFetchers(); |
- valid_chrome_accounts_.clear(); |
- invalid_chrome_accounts_.clear(); |
- add_to_cookie_.clear(); |
- add_to_chrome_.clear(); |
- ValidateAccountsFromTokenService(); |
-} |
- |
-void AccountReconcilor::GetAccountsFromCookie( |
- GetAccountsFromCookieCallback callback) { |
- get_gaia_accounts_callbacks_.push_back(callback); |
- if (!gaia_fetcher_) { |
- // There is no list account request in flight. |
- gaia_fetcher_.reset(new GaiaAuthFetcher(this, GaiaConstants::kChromeSource, |
- profile_->GetRequestContext())); |
- gaia_fetcher_->StartListAccounts(); |
- } |
-} |
- |
-void AccountReconcilor::OnListAccountsSuccess(const std::string& data) { |
- gaia_fetcher_.reset(); |
- |
- // Get account information from response data. |
- std::vector<std::pair<std::string, bool> > gaia_accounts; |
- bool valid_json = gaia::ParseListAccountsData(data, &gaia_accounts); |
- if (!valid_json) { |
- VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: parsing error"; |
- } else if (gaia_accounts.size() > 0) { |
- VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: " |
- << "Gaia " << gaia_accounts.size() << " accounts, " |
- << "Primary is '" << gaia_accounts[0].first << "'"; |
- } else { |
- VLOG(1) << "AccountReconcilor::OnListAccountsSuccess: No accounts"; |
- } |
- |
- // There must be at least one callback waiting for result. |
- DCHECK(!get_gaia_accounts_callbacks_.empty()); |
- |
- GoogleServiceAuthError error = !valid_json |
- ? GoogleServiceAuthError( |
- GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE) |
- : GoogleServiceAuthError::AuthErrorNone(); |
- get_gaia_accounts_callbacks_.front().Run(error, gaia_accounts); |
- get_gaia_accounts_callbacks_.pop_front(); |
- |
- MayBeDoNextListAccounts(); |
-} |
- |
-void AccountReconcilor::OnListAccountsFailure( |
- const GoogleServiceAuthError& error) { |
- gaia_fetcher_.reset(); |
- VLOG(1) << "AccountReconcilor::OnListAccountsFailure: " << error.ToString(); |
- std::vector<std::pair<std::string, bool> > empty_accounts; |
- |
- // There must be at least one callback waiting for result. |
- DCHECK(!get_gaia_accounts_callbacks_.empty()); |
- |
- get_gaia_accounts_callbacks_.front().Run(error, empty_accounts); |
- get_gaia_accounts_callbacks_.pop_front(); |
- |
- MayBeDoNextListAccounts(); |
-} |
- |
-void AccountReconcilor::MayBeDoNextListAccounts() { |
- if (!get_gaia_accounts_callbacks_.empty()) { |
- gaia_fetcher_.reset(new GaiaAuthFetcher(this, GaiaConstants::kChromeSource, |
- profile_->GetRequestContext())); |
- gaia_fetcher_->StartListAccounts(); |
- } |
-} |
- |
-void AccountReconcilor::ContinueReconcileActionAfterGetGaiaAccounts( |
- const GoogleServiceAuthError& error, |
- const std::vector<std::pair<std::string, bool> >& accounts) { |
- if (error.state() == GoogleServiceAuthError::NONE) { |
- gaia_accounts_ = accounts; |
- are_gaia_accounts_set_ = true; |
- FinishReconcile(); |
- } else { |
- AbortReconcile(); |
- } |
-} |
- |
-void AccountReconcilor::ValidateAccountsFromTokenService() { |
- primary_account_ = |
- SigninManagerFactory::GetForProfile(profile_)->GetAuthenticatedUsername(); |
- DCHECK(!primary_account_.empty()); |
- |
- ProfileOAuth2TokenService* token_service = |
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile_); |
- chrome_accounts_ = token_service->GetAccounts(); |
- DCHECK_GT(chrome_accounts_.size(), 0u); |
- |
- VLOG(1) << "AccountReconcilor::ValidateAccountsFromTokenService: " |
- << "Chrome " << chrome_accounts_.size() << " accounts, " |
- << "Primary is '" << primary_account_ << "'"; |
- |
- DCHECK(!requests_); |
- requests_ = |
- new scoped_ptr<OAuth2TokenService::Request>[chrome_accounts_.size()]; |
- const OAuth2TokenService::ScopeSet scopes = |
- AccountReconcilor::UserIdFetcher::GetScopes(); |
- for (size_t i = 0; i < chrome_accounts_.size(); ++i) { |
- requests_[i] = token_service->StartRequest(chrome_accounts_[i], |
- scopes, |
- this); |
- } |
- |
- DCHECK_EQ(0u, user_id_fetchers_.size()); |
- user_id_fetchers_.resize(chrome_accounts_.size()); |
-} |
- |
-void AccountReconcilor::OnGetTokenSuccess( |
- const OAuth2TokenService::Request* request, |
- const std::string& access_token, |
- const base::Time& expiration_time) { |
- size_t index; |
- for (index = 0; index < chrome_accounts_.size(); ++index) { |
- if (request == requests_[index].get()) |
- break; |
- } |
- DCHECK(index < chrome_accounts_.size()); |
- |
- const std::string& account_id = chrome_accounts_[index]; |
- |
- VLOG(1) << "AccountReconcilor::OnGetTokenSuccess: valid " << account_id; |
- |
- DCHECK(!user_id_fetchers_[index]); |
- user_id_fetchers_[index] = |
- new UserIdFetcher(this, access_token, account_id); |
-} |
- |
-void AccountReconcilor::OnGetTokenFailure( |
- const OAuth2TokenService::Request* request, |
- const GoogleServiceAuthError& error) { |
- size_t index; |
- for (index = 0; index < chrome_accounts_.size(); ++index) { |
- if (request == requests_[index].get()) |
- break; |
- } |
- DCHECK(index < chrome_accounts_.size()); |
- |
- const std::string& account_id = chrome_accounts_[index]; |
- |
- VLOG(1) << "AccountReconcilor::OnGetTokenFailure: invalid " |
- << account_id; |
- HandleFailedAccountIdCheck(account_id); |
-} |
- |
-void AccountReconcilor::FinishReconcile() { |
- // Make sure that the process of validating the gaia cookie and the oauth2 |
- // tokens individually is done before proceeding with reconciliation. |
- if (!are_gaia_accounts_set_ || !AreAllRefreshTokensChecked()) |
- return; |
- |
- VLOG(1) << "AccountReconcilor::FinishReconcile"; |
- |
- DeleteFetchers(); |
- |
- DCHECK(add_to_cookie_.empty()); |
- DCHECK(add_to_chrome_.empty()); |
- bool are_primaries_equal = |
- gaia_accounts_.size() > 0 && |
- gaia::AreEmailsSame(primary_account_, gaia_accounts_[0].first); |
- |
- if (are_primaries_equal) { |
- // Determine if we need to merge accounts from gaia cookie to chrome. |
- for (size_t i = 0; i < gaia_accounts_.size(); ++i) { |
- const std::string& gaia_account = gaia_accounts_[i].first; |
- if (gaia_accounts_[i].second && |
- valid_chrome_accounts_.find(gaia_account) == |
- valid_chrome_accounts_.end()) { |
- add_to_chrome_.push_back(std::make_pair(gaia_account, i)); |
- } |
- } |
- |
- // Determine if we need to merge accounts from chrome into gaia cookie. |
- for (EmailSet::const_iterator i = valid_chrome_accounts_.begin(); |
- i != valid_chrome_accounts_.end(); ++i) { |
- bool add_to_cookie = true; |
- for (size_t j = 0; j < gaia_accounts_.size(); ++j) { |
- if (gaia::AreEmailsSame(gaia_accounts_[j].first, *i)) { |
- add_to_cookie = !gaia_accounts_[j].second; |
- break; |
- } |
- } |
- if (add_to_cookie) |
- add_to_cookie_.push_back(*i); |
- } |
- } else { |
- VLOG(1) << "AccountReconcilor::FinishReconcile: rebuild cookie"; |
- // Really messed up state. Blow away the gaia cookie completely and |
- // rebuild it, making sure the primary account as specified by the |
- // SigninManager is the first session in the gaia cookie. |
- PerformLogoutAllAccountsAction(); |
- add_to_cookie_.push_back(primary_account_); |
- for (EmailSet::const_iterator i = valid_chrome_accounts_.begin(); |
- i != valid_chrome_accounts_.end(); ++i) { |
- if (*i != primary_account_) |
- add_to_cookie_.push_back(*i); |
- } |
- } |
- |
- // For each account known to chrome but not in the gaia cookie, |
- // PerformMergeAction(). |
- for (size_t i = 0; i < add_to_cookie_.size(); ++i) |
- PerformMergeAction(add_to_cookie_[i]); |
- |
- // For each account in the gaia cookie not known to chrome, |
- // PerformAddToChromeAction. |
- for (std::vector<std::pair<std::string, int> >::const_iterator i = |
- add_to_chrome_.begin(); |
- i != add_to_chrome_.end(); ++i) { |
- PerformAddToChromeAction(i->first, i->second); |
- } |
- |
- CalculateIfReconcileIsDone(); |
- ScheduleStartReconcileIfChromeAccountsChanged(); |
-} |
- |
-void AccountReconcilor::AbortReconcile() { |
- VLOG(1) << "AccountReconcilor::AbortReconcile: we'll try again later"; |
- DeleteFetchers(); |
- add_to_cookie_.clear(); |
- add_to_chrome_.clear(); |
- CalculateIfReconcileIsDone(); |
-} |
- |
-void AccountReconcilor::CalculateIfReconcileIsDone() { |
- is_reconcile_started_ = !add_to_cookie_.empty() || !add_to_chrome_.empty(); |
- if (!is_reconcile_started_) |
- VLOG(1) << "AccountReconcilor::CalculateIfReconcileIsDone: done"; |
-} |
- |
-void AccountReconcilor::ScheduleStartReconcileIfChromeAccountsChanged() { |
- if (is_reconcile_started_) |
- return; |
- |
- // Start a reconcile as the token accounts have changed. |
- VLOG(1) << "AccountReconcilor::StartReconcileIfChromeAccountsChanged"; |
- std::vector<std::string> reconciled_accounts(chrome_accounts_); |
- std::vector<std::string> new_chrome_accounts( |
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile_)->GetAccounts()); |
- std::sort(reconciled_accounts.begin(), reconciled_accounts.end()); |
- std::sort(new_chrome_accounts.begin(), new_chrome_accounts.end()); |
- if (reconciled_accounts != new_chrome_accounts) { |
- base::MessageLoop::current()->PostTask( |
- FROM_HERE, |
- base::Bind(&AccountReconcilor::StartReconcile, base::Unretained(this))); |
- } |
-} |
- |
-void AccountReconcilor::MergeSessionCompleted( |
- const std::string& account_id, |
- const GoogleServiceAuthError& error) { |
- VLOG(1) << "AccountReconcilor::MergeSessionCompleted: account_id=" |
- << account_id; |
- |
- // Remove the account from the list that is being merged. |
- for (std::vector<std::string>::iterator i = add_to_cookie_.begin(); |
- i != add_to_cookie_.end(); ++i) { |
- if (account_id == *i) { |
- add_to_cookie_.erase(i); |
- break; |
- } |
- } |
- |
- CalculateIfReconcileIsDone(); |
- ScheduleStartReconcileIfChromeAccountsChanged(); |
-} |
- |
-void AccountReconcilor::HandleSuccessfulAccountIdCheck( |
- const std::string& account_id) { |
- valid_chrome_accounts_.insert(account_id); |
- FinishReconcile(); |
-} |
- |
-void AccountReconcilor::HandleFailedAccountIdCheck( |
- const std::string& account_id) { |
- invalid_chrome_accounts_.insert(account_id); |
- FinishReconcile(); |
-} |
- |
-void AccountReconcilor::HandleRefreshTokenFetched( |
- const std::string& account_id, |
- const std::string& refresh_token) { |
- if (!refresh_token.empty()) { |
- ProfileOAuth2TokenService* token_service = |
- ProfileOAuth2TokenServiceFactory::GetForProfile(profile()); |
- token_service->UpdateCredentials(account_id, refresh_token); |
- } |
- |
- // Remove the account from the list that is being updated. |
- for (std::vector<std::pair<std::string, int> >::iterator i = |
- add_to_chrome_.begin(); |
- i != add_to_chrome_.end(); ++i) { |
- if (gaia::AreEmailsSame(account_id, i->first)) { |
- add_to_chrome_.erase(i); |
- break; |
- } |
- } |
- |
- CalculateIfReconcileIsDone(); |
-} |