Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / google_apis / gaia / merge_session_helper.cc
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
5 #include "google_apis/gaia/merge_session_helper.h"
6
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"
13
14 MergeSessionHelper::MergeSessionHelper(
15     OAuth2TokenService* token_service,
16     net::URLRequestContextGetter* request_context,
17     Observer* observer)
18     : token_service_(token_service),
19       request_context_(request_context) {
20   if (observer)
21     AddObserver(observer);
22 }
23
24 MergeSessionHelper::~MergeSessionHelper() {
25   DCHECK(accounts_.empty());
26 }
27
28 void MergeSessionHelper::LogIn(const std::string& account_id) {
29   DCHECK(!account_id.empty());
30   accounts_.push_back(account_id);
31   if (accounts_.size() == 1)
32     StartFetching();
33 }
34
35 void MergeSessionHelper::AddObserver(Observer* observer) {
36   observer_list_.AddObserver(observer);
37 }
38
39 void MergeSessionHelper::RemoveObserver(Observer* observer) {
40   observer_list_.RemoveObserver(observer);
41 }
42
43 void MergeSessionHelper::CancelAll() {
44   gaia_auth_fetcher_.reset();
45   uber_token_fetcher_.reset();
46   accounts_.clear();
47 }
48
49 void MergeSessionHelper::LogOut(
50     const std::string& account_id,
51     const std::vector<std::string>& accounts) {
52   DCHECK(!account_id.empty());
53   LogOutInternal(account_id, accounts);
54 }
55
56 void MergeSessionHelper::LogOutInternal(
57     const std::string& account_id,
58     const std::vector<std::string>& accounts) {
59   bool pending = !accounts_.empty();
60
61   if (pending) {
62     for (std::deque<std::string>::const_iterator it = accounts_.begin() + 1;
63         it != accounts_.end(); it++) {
64       if (!it->empty() &&
65           (std::find(accounts.begin(), accounts.end(), *it) == accounts.end() ||
66            *it == account_id)) {
67         // We have a pending log in request for an account followed by
68         // a signout.
69         GoogleServiceAuthError error(GoogleServiceAuthError::REQUEST_CANCELED);
70         SignalComplete(*it, error);
71       }
72     }
73
74     // Remove every thing in the work list besides the one that is running.
75     accounts_.resize(1);
76   }
77
78   // Signal a logout to be the next thing to do unless the pending
79   // action is already a logout.
80   if (!pending || !accounts_.front().empty())
81     accounts_.push_back("");
82
83   for (std::vector<std::string>::const_iterator it = accounts.begin();
84       it != accounts.end(); it++) {
85     if (*it != account_id) {
86       DCHECK(!it->empty());
87       accounts_.push_back(*it);
88     }
89   }
90
91   if (!pending)
92     StartLogOutUrlFetch();
93 }
94
95 void MergeSessionHelper::LogOutAllAccounts() {
96   LogOutInternal("", std::vector<std::string>());
97 }
98
99 void MergeSessionHelper::StartLogOutUrlFetch() {
100   DCHECK(accounts_.front().empty());
101   GURL logout_url(GaiaUrls::GetInstance()->service_logout_url());
102   net::URLFetcher* fetcher =
103       net::URLFetcher::Create(logout_url, net::URLFetcher::GET, this);
104   fetcher->SetRequestContext(request_context_);
105   fetcher->Start();
106 }
107
108 void MergeSessionHelper::OnUbertokenSuccess(const std::string& uber_token) {
109   VLOG(1) << "MergeSessionHelper::OnUbertokenSuccess"
110           << " account=" << accounts_.front();
111   gaia_auth_fetcher_.reset(new GaiaAuthFetcher(this,
112                                                GaiaConstants::kChromeSource,
113                                                request_context_));
114   gaia_auth_fetcher_->StartMergeSession(uber_token);
115 }
116
117 void MergeSessionHelper::OnUbertokenFailure(
118     const GoogleServiceAuthError& error) {
119   VLOG(1) << "Failed to retrieve ubertoken"
120           << " account=" << accounts_.front()
121           << " error=" << error.ToString();
122   const std::string account_id = accounts_.front();
123   HandleNextAccount();
124   SignalComplete(account_id, error);
125 }
126
127 void MergeSessionHelper::OnMergeSessionSuccess(const std::string& data) {
128   DVLOG(1) << "MergeSession successful account=" << accounts_.front();
129   const std::string account_id = accounts_.front();
130   HandleNextAccount();
131   SignalComplete(account_id, GoogleServiceAuthError::AuthErrorNone());
132 }
133
134 void MergeSessionHelper::OnMergeSessionFailure(
135     const GoogleServiceAuthError& error) {
136   VLOG(1) << "Failed MergeSession"
137           << " account=" << accounts_.front()
138           << " error=" << error.ToString();
139   const std::string account_id = accounts_.front();
140   HandleNextAccount();
141   SignalComplete(account_id, error);
142 }
143
144 void MergeSessionHelper::StartFetching() {
145   uber_token_fetcher_.reset(new UbertokenFetcher(token_service_,
146                                                  this,
147                                                  request_context_));
148   uber_token_fetcher_->StartFetchingToken(accounts_.front());
149 }
150
151 void MergeSessionHelper::OnURLFetchComplete(const net::URLFetcher* source) {
152   DCHECK(accounts_.front().empty());
153   HandleNextAccount();
154 }
155
156 void MergeSessionHelper::SignalComplete(
157     const std::string& account_id,
158     const GoogleServiceAuthError& error) {
159   // Its possible for the observer to delete |this| object.  Don't access
160   // access any members after this calling the observer.  This method should
161   // be the last call in any other method.
162   FOR_EACH_OBSERVER(Observer, observer_list_,
163                     MergeSessionCompleted(account_id, error));
164 }
165
166 void MergeSessionHelper::HandleNextAccount() {
167   accounts_.pop_front();
168   gaia_auth_fetcher_.reset();
169   if (accounts_.empty()) {
170     uber_token_fetcher_.reset();
171   } else {
172     if (accounts_.front().empty()) {
173       StartLogOutUrlFetch();
174     } else {
175       StartFetching();
176     }
177   }
178 }