#ifndef COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_
#define COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_
#include <deque>
#include <functional>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/basictypes.h"
#include "base/callback_forward.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "components/keyed_service/core/keyed_service.h"
#include "components/signin/core/browser/signin_manager.h"
#include "google_apis/gaia/gaia_auth_consumer.h"
#include "google_apis/gaia/google_service_auth_error.h"
#include "google_apis/gaia/merge_session_helper.h"
#include "google_apis/gaia/oauth2_token_service.h"
class GaiaAuthFetcher;
class ProfileOAuth2TokenService;
class SigninClient;
class SigninOAuthHelper;
namespace net {
class CanonicalCookie;
}
class AccountReconcilor : public KeyedService,
public GaiaAuthConsumer,
public MergeSessionHelper::Observer,
public OAuth2TokenService::Consumer,
public OAuth2TokenService::Observer,
public SigninManagerBase::Observer {
public:
AccountReconcilor(ProfileOAuth2TokenService* token_service,
SigninManagerBase* signin_manager,
SigninClient* client);
virtual ~AccountReconcilor();
void Initialize(bool start_reconcile_if_tokens_available);
virtual void Shutdown() OVERRIDE;
void AddMergeSessionObserver(MergeSessionHelper::Observer* observer);
void RemoveMergeSessionObserver(MergeSessionHelper::Observer* observer);
ProfileOAuth2TokenService* token_service() { return token_service_; }
SigninClient* client() { return client_; }
private:
class EmailLessFunc : public std::less<std::string> {
public:
bool operator()(const std::string& s1, const std::string& s2) const;
};
typedef std::set<std::string, EmailLessFunc> EmailSet;
class RefreshTokenFetcher;
class UserIdFetcher;
bool IsPeriodicReconciliationRunning() const {
return reconciliation_timer_.IsRunning();
}
bool IsRegisteredWithTokenService() const {
return registered_with_token_service_;
}
bool AreGaiaAccountsSet() const { return are_gaia_accounts_set_; }
bool AreAllRefreshTokensChecked() const;
const std::vector<std::pair<std::string, bool> >& GetGaiaAccountsForTesting()
const {
return gaia_accounts_;
}
const EmailSet& GetValidChromeAccountsForTesting() const {
return valid_chrome_accounts_;
}
const EmailSet& GetInvalidChromeAccountsForTesting() const {
return invalid_chrome_accounts_;
}
typedef base::Callback<
void(const GoogleServiceAuthError& error,
const std::vector<std::pair<std::string, bool> >&)>
GetAccountsFromCookieCallback;
friend class AccountReconcilorTest;
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, SigninManagerRegistration);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, Reauth);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, ProfileAlreadyConnected);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, GetAccountsFromCookieSuccess);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, GetAccountsFromCookieFailure);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, ValidateAccountsFromTokens);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
ValidateAccountsFromTokensFailedUserInfo);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
ValidateAccountsFromTokensFailedTokenRequest);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoop);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoopWithDots);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoopMultiple);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileAddToCookie);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileAddToChrome);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileBadPrimary);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileOnlyOnce);
FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
StartReconcileWithSessionInfoExpiredDefault);
void RegisterForCookieChanges();
void UnregisterForCookieChanges();
void RegisterWithSigninManager();
void UnregisterWithSigninManager();
void RegisterWithTokenService();
void UnregisterWithTokenService();
bool IsProfileConnected();
void DeleteFetchers();
void StartPeriodicReconciliation();
void StopPeriodicReconciliation();
void PeriodicReconciliation();
virtual void PerformMergeAction(const std::string& account_id);
virtual void PerformAddToChromeAction(const std::string& account_id,
int session_index);
virtual void PerformLogoutAllAccountsAction();
virtual void StartRemoveAction(const std::string& account_id);
virtual void FinishRemoveAction(
const std::string& account_id,
const GoogleServiceAuthError& error,
const std::vector<std::pair<std::string, bool> >& accounts);
void StartReconcile();
void FinishReconcile();
void AbortReconcile();
void CalculateIfReconcileIsDone();
void ScheduleStartReconcileIfChromeAccountsChanged();
void HandleSuccessfulAccountIdCheck(const std::string& account_id);
void HandleFailedAccountIdCheck(const std::string& account_id);
void HandleRefreshTokenFetched(const std::string& account_id,
const std::string& refresh_token);
void GetAccountsFromCookie(GetAccountsFromCookieCallback callback);
void ContinueReconcileActionAfterGetGaiaAccounts(
const GoogleServiceAuthError& error,
const std::vector<std::pair<std::string, bool> >& accounts);
void ValidateAccountsFromTokenService();
void OnCookieChanged(const net::CanonicalCookie* cookie);
virtual void OnListAccountsSuccess(const std::string& data) OVERRIDE;
virtual void OnListAccountsFailure(const GoogleServiceAuthError& error)
OVERRIDE;
virtual void MergeSessionCompleted(const std::string& account_id,
const GoogleServiceAuthError& error)
OVERRIDE;
virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
const std::string& access_token,
const base::Time& expiration_time) OVERRIDE;
virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
const GoogleServiceAuthError& error) OVERRIDE;
virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE;
virtual void OnRefreshTokenRevoked(const std::string& account_id) OVERRIDE;
virtual void OnRefreshTokensLoaded() OVERRIDE;
virtual void GoogleSigninSucceeded(const std::string& username,
const std::string& password) OVERRIDE;
virtual void GoogleSignedOut(const std::string& username) OVERRIDE;
void MayBeDoNextListAccounts();
ProfileOAuth2TokenService* token_service_;
SigninManagerBase* signin_manager_;
SigninClient* client_;
base::RepeatingTimer<AccountReconcilor> reconciliation_timer_;
MergeSessionHelper merge_session_helper_;
scoped_ptr<GaiaAuthFetcher> gaia_fetcher_;
bool registered_with_token_service_;
bool is_reconcile_started_;
bool are_gaia_accounts_set_;
std::vector<std::pair<std::string, bool> > gaia_accounts_;
std::string primary_account_;
std::vector<std::string> chrome_accounts_;
scoped_ptr<OAuth2TokenService::Request>* requests_;
ScopedVector<UserIdFetcher> user_id_fetchers_;
ScopedVector<SigninOAuthHelper> refresh_token_fetchers_;
EmailSet valid_chrome_accounts_;
EmailSet invalid_chrome_accounts_;
std::vector<std::string> add_to_cookie_;
std::vector<std::pair<std::string, int> > add_to_chrome_;
std::deque<GetAccountsFromCookieCallback> get_gaia_accounts_callbacks_;
DISALLOW_COPY_AND_ASSIGN(AccountReconcilor);
};
#endif