1 // Copyright 2014 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 COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_
5 #define COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_
14 #include "base/basictypes.h"
15 #include "base/callback_forward.h"
16 #include "base/compiler_specific.h"
17 #include "base/memory/scoped_ptr.h"
18 #include "base/memory/scoped_vector.h"
19 #include "components/keyed_service/core/keyed_service.h"
20 #include "components/signin/core/browser/signin_client.h"
21 #include "components/signin/core/browser/signin_manager.h"
22 #include "google_apis/gaia/gaia_auth_consumer.h"
23 #include "google_apis/gaia/google_service_auth_error.h"
24 #include "google_apis/gaia/merge_session_helper.h"
25 #include "google_apis/gaia/oauth2_token_service.h"
27 class GaiaAuthFetcher;
28 class ProfileOAuth2TokenService;
32 class CanonicalCookie;
35 class AccountReconcilor : public KeyedService,
36 public GaiaAuthConsumer,
37 public MergeSessionHelper::Observer,
38 public OAuth2TokenService::Observer,
39 public SigninManagerBase::Observer {
41 AccountReconcilor(ProfileOAuth2TokenService* token_service,
42 SigninManagerBase* signin_manager,
43 SigninClient* client);
44 virtual ~AccountReconcilor();
46 void Initialize(bool start_reconcile_if_tokens_available);
48 // Signal that the status of the new_profile_management flag has changed.
49 // Pass the new status as an explicit parameter since disabling the flag
50 // doesn't remove it from the CommandLine::ForCurrentProcess().
51 void OnNewProfileManagementFlagChanged(bool new_flag_status);
53 // KeyedService implementation.
54 virtual void Shutdown() OVERRIDE;
56 // Add or remove observers for the merge session notification.
57 void AddMergeSessionObserver(MergeSessionHelper::Observer* observer);
58 void RemoveMergeSessionObserver(MergeSessionHelper::Observer* observer);
60 ProfileOAuth2TokenService* token_service() { return token_service_; }
61 SigninClient* client() { return client_; }
64 // Used during GetAccountsFromCookie.
65 // Stores a callback for the next action to perform.
66 typedef base::Callback<
67 void(const GoogleServiceAuthError& error,
68 const std::vector<std::pair<std::string, bool> >&)>
69 GetAccountsFromCookieCallback;
71 virtual void GetAccountsFromCookie(GetAccountsFromCookieCallback callback);
74 bool IsRegisteredWithTokenService() const {
75 return registered_with_token_service_;
78 bool AreGaiaAccountsSet() const { return are_gaia_accounts_set_; }
80 const std::vector<std::pair<std::string, bool> >& GetGaiaAccountsForTesting()
82 return gaia_accounts_;
85 // Virtual so that it can be overridden in tests.
86 virtual void StartFetchingExternalCcResult();
88 friend class AccountReconcilorTest;
89 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, SigninManagerRegistration);
90 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, Reauth);
91 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, ProfileAlreadyConnected);
92 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, GetAccountsFromCookieSuccess);
93 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, GetAccountsFromCookieFailure);
94 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoop);
95 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoopWithDots);
96 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileNoopMultiple);
97 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileAddToCookie);
98 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
99 StartReconcileRemoveFromCookie);
100 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
101 StartReconcileAddToCookieTwice);
102 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileBadPrimary);
103 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest, StartReconcileOnlyOnce);
104 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
105 StartReconcileWithSessionInfoExpiredDefault);
106 FRIEND_TEST_ALL_PREFIXES(AccountReconcilorTest,
107 MergeSessionCompletedWithBogusAccount);
109 // Register and unregister with dependent services.
110 void RegisterForCookieChanges();
111 void UnregisterForCookieChanges();
112 void RegisterWithSigninManager();
113 void UnregisterWithSigninManager();
114 void RegisterWithTokenService();
115 void UnregisterWithTokenService();
117 bool IsProfileConnected();
119 // All actions with side effects. Virtual so that they can be overridden
121 virtual void PerformMergeAction(const std::string& account_id);
122 virtual void PerformLogoutAllAccountsAction();
124 // Used during periodic reconciliation.
125 void StartReconcile();
126 void FinishReconcile();
127 void AbortReconcile();
128 void CalculateIfReconcileIsDone();
129 void ScheduleStartReconcileIfChromeAccountsChanged();
131 void ContinueReconcileActionAfterGetGaiaAccounts(
132 const GoogleServiceAuthError& error,
133 const std::vector<std::pair<std::string, bool> >& accounts);
134 void ValidateAccountsFromTokenService();
135 // Note internally that this |account_id| is added to the cookie jar.
136 bool MarkAccountAsAddedToCookie(const std::string& account_id);
138 void OnCookieChanged(const net::CanonicalCookie* cookie);
140 // Overriden from GaiaAuthConsumer.
141 virtual void OnListAccountsSuccess(const std::string& data) OVERRIDE;
142 virtual void OnListAccountsFailure(const GoogleServiceAuthError& error)
145 // Overriden from MergeSessionHelper::Observer.
146 virtual void MergeSessionCompleted(const std::string& account_id,
147 const GoogleServiceAuthError& error)
150 // Overriden from OAuth2TokenService::Observer.
151 virtual void OnEndBatchChanges() OVERRIDE;
153 // Overriden from SigninManagerBase::Observer.
154 virtual void GoogleSigninSucceeded(const std::string& account_id,
155 const std::string& username,
156 const std::string& password) OVERRIDE;
157 virtual void GoogleSignedOut(const std::string& account_id,
158 const std::string& username) OVERRIDE;
160 void MayBeDoNextListAccounts();
162 // The ProfileOAuth2TokenService associated with this reconcilor.
163 ProfileOAuth2TokenService* token_service_;
165 // The SigninManager associated with this reconcilor.
166 SigninManagerBase* signin_manager_;
168 // The SigninClient associated with this reconcilor.
169 SigninClient* client_;
171 MergeSessionHelper merge_session_helper_;
172 scoped_ptr<GaiaAuthFetcher> gaia_fetcher_;
173 bool registered_with_token_service_;
175 // True while the reconcilor is busy checking or managing the accounts in
177 bool is_reconcile_started_;
179 // True iff this is the first time the reconcilor is executing.
180 bool first_execution_;
182 // Used during reconcile action.
183 // These members are used to validate the gaia cookie. |gaia_accounts_|
184 // holds the state of google accounts in the gaia cookie. Each element is
185 // a pair that holds the email address of the account and a boolean that
186 // indicates whether the account is valid or not. The accounts in the vector
187 // are ordered the in same way as the gaia cookie.
188 bool are_gaia_accounts_set_;
189 std::vector<std::pair<std::string, bool> > gaia_accounts_;
191 // Used during reconcile action.
192 // These members are used to validate the tokens in OAuth2TokenService.
193 std::string primary_account_;
194 std::vector<std::string> chrome_accounts_;
195 std::vector<std::string> add_to_cookie_;
197 std::deque<GetAccountsFromCookieCallback> get_gaia_accounts_callbacks_;
199 scoped_ptr<SigninClient::CookieChangedCallbackList::Subscription>
200 cookie_changed_subscription_;
202 DISALLOW_COPY_AND_ASSIGN(AccountReconcilor);
205 #endif // COMPONENTS_SIGNIN_CORE_BROWSER_ACCOUNT_RECONCILOR_H_