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.
5 #ifndef GOOGLE_APIS_GAIA_MERGE_SESSION_HELPER_H_
6 #define GOOGLE_APIS_GAIA_MERGE_SESSION_HELPER_H_
10 #include "base/observer_list.h"
11 #include "base/timer/timer.h"
12 #include "google_apis/gaia/gaia_auth_consumer.h"
13 #include "google_apis/gaia/ubertoken_fetcher.h"
14 #include "net/url_request/url_fetcher_delegate.h"
16 class GaiaAuthFetcher
;
17 class GoogleServiceAuthError
;
18 class OAuth2TokenService
;
22 class URLRequestContextGetter
;
25 // Merges a Google account known to Chrome into the cookie jar. When merging
26 // multiple accounts, one instance of the helper is better than multiple
27 // instances if there is the possibility that they run concurrently, since
28 // changes to the cookie must be serialized.
30 // By default instances of MergeSessionHelper delete themselves when done.
31 class MergeSessionHelper
: public GaiaAuthConsumer
,
32 public UbertokenConsumer
,
33 public net::URLFetcherDelegate
{
37 // Called whenever a merge session is completed. The account that was
38 // merged is given by |account_id|. If |error| is equal to
39 // GoogleServiceAuthError::AuthErrorNone() then the merge succeeeded.
40 virtual void MergeSessionCompleted(const std::string
& account_id
,
41 const GoogleServiceAuthError
& error
) = 0;
43 // Called when StartFetchingExternalCcResult() completes. From this moment
44 // forward calls to LogIn() will use the result in merge session calls.
45 // If |succeeded| is false, not all connections were checked, but some
46 // may have been. LogIn() will proceed with whatever partial results were
48 virtual void GetCheckConnectionInfoCompleted(bool succeeded
) {}
50 virtual ~Observer() {}
53 // Class to retrieve the external connection check results from gaia.
54 // Declared publicly for unit tests.
55 class ExternalCcResultFetcher
: public GaiaAuthConsumer
,
56 public net::URLFetcherDelegate
{
58 // Maps connection URLs, as returned by StartGetCheckConnectionInfo() to
59 // token and URLFetcher used to fetch the URL.
60 typedef std::map
<GURL
, std::pair
<std::string
, net::URLFetcher
*> >
63 // Maps tokens to the fetched result for that token.
64 typedef std::map
<std::string
, std::string
> ResultMap
;
66 ExternalCcResultFetcher(MergeSessionHelper
* helper
);
67 ~ExternalCcResultFetcher() override
;
69 // Gets the current value of the external connection check result string.
70 std::string
GetExternalCcResult();
72 // Start fetching the external CC result. If a fetch is already in progress
76 // Are external URLs still being checked?
79 // Returns a copy of the internal token to fetcher map.
80 URLToTokenAndFetcher
get_fetcher_map_for_testing() {
84 // Simulate a timeout for tests.
85 void TimeoutForTests();
88 // Overridden from GaiaAuthConsumer.
89 void OnGetCheckConnectionInfoSuccess(const std::string
& data
) override
;
90 void OnGetCheckConnectionInfoError(
91 const GoogleServiceAuthError
& error
) override
;
93 // Creates and initializes a URL fetcher for doing a connection check.
94 net::URLFetcher
* CreateFetcher(const GURL
& url
);
96 // Overridden from URLFetcherDelgate.
97 void OnURLFetchComplete(const net::URLFetcher
* source
) override
;
99 // Any fetches still ongoing after this call are considered timed out.
102 void CleanupTransientState();
104 void FireGetCheckConnectionInfoCompleted(bool succeeded
);
106 MergeSessionHelper
* helper_
;
107 base::OneShotTimer
<ExternalCcResultFetcher
> timer_
;
108 scoped_ptr
<GaiaAuthFetcher
> gaia_auth_fetcher_
;
109 URLToTokenAndFetcher fetchers_
;
112 DISALLOW_COPY_AND_ASSIGN(ExternalCcResultFetcher
);
115 MergeSessionHelper(OAuth2TokenService
* token_service
,
116 const std::string
& source
,
117 net::URLRequestContextGetter
* request_context
,
119 ~MergeSessionHelper() override
;
121 void LogIn(const std::string
& account_id
);
123 // Add or remove observers of this helper.
124 void AddObserver(Observer
* observer
);
125 void RemoveObserver(Observer
* observer
);
127 // Cancel all login requests.
130 // Signout of |account_id| given a list of accounts already signed in.
131 // Since this involves signing out of all accounts and resigning back in,
132 // the order which |accounts| are given is important as it will dictate
133 // the sign in order. |account_id| does not have to be in |accounts|.
134 void LogOut(const std::string
& account_id
,
135 const std::vector
<std::string
>& accounts
);
137 // Signout all accounts.
138 void LogOutAllAccounts();
140 // Call observers when merge session completes. This public so that callers
141 // that know that a given account is already in the cookie jar can simply
142 // inform the observers.
143 void SignalComplete(const std::string
& account_id
,
144 const GoogleServiceAuthError
& error
);
146 // Returns true of there are pending log ins or outs.
147 bool is_running() const { return accounts_
.size() > 0; }
149 // Start the process of fetching the external check connection result so that
150 // its ready when we try to perform a merge session.
151 void StartFetchingExternalCcResult();
153 // Returns true if the helper is still fetching external check connection
155 bool StillFetchingExternalCcResult();
158 net::URLRequestContextGetter
* request_context() { return request_context_
; }
160 // Overridden from UbertokenConsumer.
161 void OnUbertokenSuccess(const std::string
& token
) override
;
162 void OnUbertokenFailure(const GoogleServiceAuthError
& error
) override
;
164 // Overridden from GaiaAuthConsumer.
165 void OnMergeSessionSuccess(const std::string
& data
) override
;
166 void OnMergeSessionFailure(const GoogleServiceAuthError
& error
) override
;
168 void LogOutInternal(const std::string
& account_id
,
169 const std::vector
<std::string
>& accounts
);
171 // Starts the proess of fetching the uber token and performing a merge session
172 // for the next account. Virtual so that it can be overriden in tests.
173 virtual void StartFetching();
175 // Virtual for testing purpose.
176 virtual void StartLogOutUrlFetch();
178 // Start the next merge session, if needed.
179 void HandleNextAccount();
181 // Overridden from URLFetcherDelgate.
182 void OnURLFetchComplete(const net::URLFetcher
* source
) override
;
184 OAuth2TokenService
* token_service_
;
185 net::URLRequestContextGetter
* request_context_
;
186 scoped_ptr
<GaiaAuthFetcher
> gaia_auth_fetcher_
;
187 scoped_ptr
<UbertokenFetcher
> uber_token_fetcher_
;
188 ExternalCcResultFetcher result_fetcher_
;
190 // A worklist for this class. Accounts names are stored here if
191 // we are pending a signin action for that account. Empty strings
192 // represent a signout request.
193 std::deque
<std::string
> accounts_
;
195 // List of observers to notify when merge session completes.
196 // Makes sure list is empty on destruction.
197 ObserverList
<Observer
, true> observer_list_
;
199 // Source to use with GAIA endpoints for accounting.
202 DISALLOW_COPY_AND_ASSIGN(MergeSessionHelper
);
205 #endif // GOOGLE_APIS_GAIA_MERGE_SESSION_HELPER_H_