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
3 // found in the LICENSE file.
4 #ifndef CHROME_BROWSER_SIGNIN_ACCOUNT_RECONCILOR_H_
5 #define CHROME_BROWSER_SIGNIN_ACCOUNT_RECONCILOR_H_
12 #include "base/basictypes.h"
13 #include "base/callback_forward.h"
14 #include "base/compiler_specific.h"
15 #include "base/memory/scoped_ptr.h"
16 #include "base/memory/scoped_vector.h"
17 #include "chrome/browser/signin/signin_manager.h"
18 #include "components/browser_context_keyed_service/browser_context_keyed_service.h"
19 #include "content/public/browser/notification_observer.h"
20 #include "content/public/browser/notification_registrar.h"
21 #include "google_apis/gaia/gaia_auth_consumer.h"
22 #include "google_apis/gaia/google_service_auth_error.h"
23 #include "google_apis/gaia/merge_session_helper.h"
24 #include "google_apis/gaia/oauth2_token_service.h"
26 class GaiaAuthFetcher;
28 struct ChromeCookieDetails;
30 class AccountReconcilor : public BrowserContextKeyedService,
31 public content::NotificationObserver,
32 public GaiaAuthConsumer,
33 public MergeSessionHelper::Observer,
34 public OAuth2TokenService::Consumer,
35 public OAuth2TokenService::Observer,
36 public SigninManagerBase::Observer {
38 explicit AccountReconcilor(Profile* profile);
39 virtual ~AccountReconcilor();
41 // BrowserContextKeyedService implementation.
42 virtual void Shutdown() OVERRIDE;
44 // Add or remove observers for the merge session notification.
45 void AddMergeSessionObserver(MergeSessionHelper::Observer* observer);
46 void RemoveMergeSessionObserver(MergeSessionHelper::Observer* observer);
48 Profile* profile() { return profile_; }
50 bool IsPeriodicReconciliationRunning() const {
51 return reconciliation_timer_.IsRunning();
54 bool IsRegisteredWithTokenService() const {
55 return registered_with_token_service_;
58 bool AreGaiaAccountsSet() const { return are_gaia_accounts_set_; }
60 bool AreAllRefreshTokensChecked() const;
62 const std::vector<std::pair<std::string, bool> >&
63 GetGaiaAccountsForTesting() const {
64 return gaia_accounts_;
68 const std::set<std::string>& GetValidChromeAccountsForTesting() const {
69 return valid_chrome_accounts_;
72 const std::set<std::string>& GetInvalidChromeAccountsForTesting() const {
73 return invalid_chrome_accounts_;
76 // Used during GetAccountsFromCookie.
77 // Stores a callback for the next action to perform.
78 typedef base::Callback<void(
79 const GoogleServiceAuthError& error,
80 const std::vector<std::pair<std::string, bool> >&)>
81 GetAccountsFromCookieCallback;
83 friend class AccountReconcilorTest;
84 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, GetAccountsFromCookieSuccess);
85 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, GetAccountsFromCookieFailure);
86 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, ValidateAccountsFromTokens);
87 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
88 ValidateAccountsFromTokensFailedUserInfo);
89 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
90 ValidateAccountsFromTokensFailedTokenRequest);
91 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoop);
92 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoopMultiple);
93 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileAddToCookie);
94 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileAddToChrome);
95 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileBadPrimary);
96 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileOnlyOnce);
97 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
98 StartReconcileWithSessionInfoExpiredDefault);
100 class RefreshTokenFetcher;
103 // Register and unregister with dependent services.
104 void RegisterWithCookieMonster();
105 void UnregisterWithCookieMonster();
106 void RegisterWithSigninManager();
107 void UnregisterWithSigninManager();
108 void RegisterWithTokenService();
109 void UnregisterWithTokenService();
111 bool IsProfileConnected();
113 void DeleteFetchers();
115 // Start and stop the periodic reconciliation.
116 void StartPeriodicReconciliation();
117 void StopPeriodicReconciliation();
118 void PeriodicReconciliation();
120 // All actions with side effects. Virtual so that they can be overridden
122 virtual void PerformMergeAction(const std::string& account_id);
123 virtual void PerformAddToChromeAction(const std::string& account_id,
125 virtual void PerformLogoutAllAccountsAction();
127 // Used to remove an account from chrome and the cookie jar.
128 virtual void StartRemoveAction(const std::string& account_id);
129 virtual void FinishRemoveAction(
130 const std::string& account_id,
131 const GoogleServiceAuthError& error,
132 const std::vector<std::pair<std::string, bool> >& accounts);
134 // Used during periodic reconciliation.
135 void StartReconcile();
136 void FinishReconcile();
137 void AbortReconcile();
138 void CalculateIfReconcileIsDone();
139 void HandleSuccessfulAccountIdCheck(const std::string& account_id);
140 void HandleFailedAccountIdCheck(const std::string& account_id);
141 void HandleRefreshTokenFetched(const std::string& account_id,
142 const std::string& refresh_token);
144 void GetAccountsFromCookie(GetAccountsFromCookieCallback callback);
145 void ContinueReconcileActionAfterGetGaiaAccounts(
146 const GoogleServiceAuthError& error,
147 const std::vector<std::pair<std::string, bool> >& accounts);
148 void ValidateAccountsFromTokenService();
150 void OnCookieChanged(ChromeCookieDetails* details);
152 // Overriden from content::NotificationObserver.
153 virtual void Observe(int type,
154 const content::NotificationSource& source,
155 const content::NotificationDetails& details) OVERRIDE;
157 // Overriden from GaiaAuthConsumer.
158 virtual void OnListAccountsSuccess(const std::string& data) OVERRIDE;
159 virtual void OnListAccountsFailure(
160 const GoogleServiceAuthError& error) OVERRIDE;
162 // Overriden from MergeSessionHelper::Observer.
163 virtual void MergeSessionCompleted(
164 const std::string& account_id,
165 const GoogleServiceAuthError& error) OVERRIDE;
167 // Overriden from OAuth2TokenService::Consumer.
168 virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request,
169 const std::string& access_token,
170 const base::Time& expiration_time) OVERRIDE;
171 virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request,
172 const GoogleServiceAuthError& error) OVERRIDE;
174 // Overriden from OAuth2TokenService::Observer.
175 virtual void OnRefreshTokenAvailable(const std::string& account_id) OVERRIDE;
176 virtual void OnRefreshTokenRevoked(const std::string& account_id) OVERRIDE;
177 virtual void OnRefreshTokensLoaded() OVERRIDE;
179 // Overriden from SigninManagerBase::Observer.
180 virtual void GoogleSigninSucceeded(const std::string& username,
181 const std::string& password) OVERRIDE;
182 virtual void GoogleSignedOut(const std::string& username) OVERRIDE;
184 void MayBeDoNextListAccounts();
186 // The profile that this reconcilor belongs to.
188 content::NotificationRegistrar registrar_;
189 base::RepeatingTimer<AccountReconcilor> reconciliation_timer_;
190 MergeSessionHelper merge_session_helper_;
191 scoped_ptr<GaiaAuthFetcher> gaia_fetcher_;
192 bool registered_with_token_service_;
194 // True while the reconcilor is busy checking or managing the accounts in
196 bool is_reconcile_started_;
198 // Used during reconcile action.
199 // These members are used used to validate the gaia cookie. |gaia_accounts_|
200 // holds the state of google accounts in the gaia cookie. Each element is
201 // a pair that holds the email address of the account and a boolean that
202 // indicates whether the account is valid or not. The accounts in the vector
203 // are ordered the in same way as the gaia cookie.
204 bool are_gaia_accounts_set_;
205 std::vector<std::pair<std::string, bool> > gaia_accounts_;
207 // Used during reconcile action.
208 // These members are used to validate the tokens in OAuth2TokenService.
209 std::string primary_account_;
210 std::vector<std::string> chrome_accounts_;
211 scoped_ptr<OAuth2TokenService::Request>* requests_;
212 ScopedVector<UserIdFetcher> user_id_fetchers_;
213 ScopedVector<RefreshTokenFetcher> refresh_token_fetchers_;
214 std::set<std::string> valid_chrome_accounts_;
215 std::set<std::string> invalid_chrome_accounts_;
216 std::vector<std::string> add_to_cookie_;
217 std::vector<std::pair<std::string, int> > add_to_chrome_;
219 std::deque<GetAccountsFromCookieCallback> get_gaia_accounts_callbacks_;
221 DISALLOW_COPY_AND_ASSIGN(AccountReconcilor);
224 #endif // CHROME_BROWSER_SIGNIN_ACCOUNT_RECONCILOR_H_