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 #include "google_apis/gaia/merge_session_helper.h"
7 #include "google_apis/gaia/gaia_auth_fetcher.h"
8 #include "google_apis/gaia/gaia_constants.h"
9 #include "google_apis/gaia/gaia_urls.h"
10 #include "google_apis/gaia/oauth2_token_service.h"
11 #include "net/url_request/url_fetcher.h"
12 #include "net/url_request/url_fetcher_delegate.h"
14 MergeSessionHelper::MergeSessionHelper(
15 OAuth2TokenService
* token_service
,
16 net::URLRequestContextGetter
* request_context
,
18 : token_service_(token_service
),
19 request_context_(request_context
) {
21 AddObserver(observer
);
24 MergeSessionHelper::~MergeSessionHelper() {
25 DCHECK(accounts_
.empty());
28 void MergeSessionHelper::LogIn(const std::string
& account_id
) {
29 DCHECK(!account_id
.empty());
30 VLOG(1) << "MergeSessionHelper::LogIn: " << account_id
;
31 accounts_
.push_back(account_id
);
32 if (accounts_
.size() == 1)
36 void MergeSessionHelper::AddObserver(Observer
* observer
) {
37 observer_list_
.AddObserver(observer
);
40 void MergeSessionHelper::RemoveObserver(Observer
* observer
) {
41 observer_list_
.RemoveObserver(observer
);
44 void MergeSessionHelper::CancelAll() {
45 VLOG(1) << "MergeSessionHelper::CancelAll";
46 gaia_auth_fetcher_
.reset();
47 uber_token_fetcher_
.reset();
51 void MergeSessionHelper::LogOut(
52 const std::string
& account_id
,
53 const std::vector
<std::string
>& accounts
) {
54 DCHECK(!account_id
.empty());
55 VLOG(1) << "MergeSessionHelper::LogOut: " << account_id
56 << " accounts=" << accounts
.size();
57 LogOutInternal(account_id
, accounts
);
60 void MergeSessionHelper::LogOutInternal(
61 const std::string
& account_id
,
62 const std::vector
<std::string
>& accounts
) {
63 bool pending
= !accounts_
.empty();
66 for (std::deque
<std::string
>::const_iterator it
= accounts_
.begin() + 1;
67 it
!= accounts_
.end(); it
++) {
69 (std::find(accounts
.begin(), accounts
.end(), *it
) == accounts
.end() ||
71 // We have a pending log in request for an account followed by
73 GoogleServiceAuthError
error(GoogleServiceAuthError::REQUEST_CANCELED
);
74 SignalComplete(*it
, error
);
78 // Remove every thing in the work list besides the one that is running.
82 // Signal a logout to be the next thing to do unless the pending
83 // action is already a logout.
84 if (!pending
|| !accounts_
.front().empty())
85 accounts_
.push_back("");
87 for (std::vector
<std::string
>::const_iterator it
= accounts
.begin();
88 it
!= accounts
.end(); it
++) {
89 if (*it
!= account_id
) {
91 accounts_
.push_back(*it
);
96 StartLogOutUrlFetch();
99 void MergeSessionHelper::LogOutAllAccounts() {
100 VLOG(1) << "MergeSessionHelper::LogOutAllAccounts";
101 LogOutInternal("", std::vector
<std::string
>());
104 void MergeSessionHelper::SignalComplete(
105 const std::string
& account_id
,
106 const GoogleServiceAuthError
& error
) {
107 // Its possible for the observer to delete |this| object. Don't access
108 // access any members after this calling the observer. This method should
109 // be the last call in any other method.
110 FOR_EACH_OBSERVER(Observer
, observer_list_
,
111 MergeSessionCompleted(account_id
, error
));
114 void MergeSessionHelper::StartLogOutUrlFetch() {
115 DCHECK(accounts_
.front().empty());
116 VLOG(1) << "MergeSessionHelper::StartLogOutUrlFetch";
117 GURL
logout_url(GaiaUrls::GetInstance()->service_logout_url());
118 net::URLFetcher
* fetcher
=
119 net::URLFetcher::Create(logout_url
, net::URLFetcher::GET
, this);
120 fetcher
->SetRequestContext(request_context_
);
124 void MergeSessionHelper::OnUbertokenSuccess(const std::string
& uber_token
) {
125 VLOG(1) << "MergeSessionHelper::OnUbertokenSuccess"
126 << " account=" << accounts_
.front();
127 gaia_auth_fetcher_
.reset(new GaiaAuthFetcher(this,
128 GaiaConstants::kChromeSource
,
130 gaia_auth_fetcher_
->StartMergeSession(uber_token
);
133 void MergeSessionHelper::OnUbertokenFailure(
134 const GoogleServiceAuthError
& error
) {
135 VLOG(1) << "Failed to retrieve ubertoken"
136 << " account=" << accounts_
.front()
137 << " error=" << error
.ToString();
138 const std::string account_id
= accounts_
.front();
140 SignalComplete(account_id
, error
);
143 void MergeSessionHelper::OnMergeSessionSuccess(const std::string
& data
) {
144 VLOG(1) << "MergeSession successful account=" << accounts_
.front();
145 const std::string account_id
= accounts_
.front();
147 SignalComplete(account_id
, GoogleServiceAuthError::AuthErrorNone());
150 void MergeSessionHelper::OnMergeSessionFailure(
151 const GoogleServiceAuthError
& error
) {
152 VLOG(1) << "Failed MergeSession"
153 << " account=" << accounts_
.front()
154 << " error=" << error
.ToString();
155 const std::string account_id
= accounts_
.front();
157 SignalComplete(account_id
, error
);
160 void MergeSessionHelper::StartFetching() {
161 VLOG(1) << "MergeSessionHelper::StartFetching account_id="
162 << accounts_
.front();
163 uber_token_fetcher_
.reset(new UbertokenFetcher(token_service_
,
166 uber_token_fetcher_
->StartFetchingToken(accounts_
.front());
169 void MergeSessionHelper::OnURLFetchComplete(const net::URLFetcher
* source
) {
170 DCHECK(accounts_
.front().empty());
171 VLOG(1) << "MergeSessionHelper::OnURLFetchComplete";
175 void MergeSessionHelper::HandleNextAccount() {
176 VLOG(1) << "MergeSessionHelper::HandleNextAccount";
177 accounts_
.pop_front();
178 gaia_auth_fetcher_
.reset();
179 if (accounts_
.empty()) {
180 VLOG(1) << "MergeSessionHelper::HandleNextAccount: no more";
181 uber_token_fetcher_
.reset();
183 if (accounts_
.front().empty()) {
184 StartLogOutUrlFetch();