account_tracker.cc revision 5f1c94371a64b3196d4be9466099bb892df9b88e
12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file.
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "google_apis/gaia/account_tracker.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/debug/trace_event.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace gaia {
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
147dbb3d5cf0c15f500944d211057644d6a2f37371Ben MurdochAccountTracker::AccountTracker(
152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    IdentityProvider* identity_provider,
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    net::URLRequestContextGetter* request_context_getter)
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : identity_provider_(identity_provider),
182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_context_getter_(request_context_getter),
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      shutdown_called_(false) {
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  identity_provider_->AddObserver(this);
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  identity_provider_->GetTokenService()->AddObserver(this);
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AccountTracker::~AccountTracker() {
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(shutdown_called_);
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccountTracker::Shutdown() {
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  shutdown_called_ = true;
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  STLDeleteValues(&user_info_requests_);
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  identity_provider_->GetTokenService()->RemoveObserver(this);
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  identity_provider_->RemoveObserver(this);
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)bool AccountTracker::IsAllUserInfoFetched() const {
36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return user_info_requests_.empty();
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccountTracker::AddObserver(Observer* observer) {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_list_.AddObserver(observer);
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccountTracker::RemoveObserver(Observer* observer) {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  observer_list_.RemoveObserver(observer);
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::vector<AccountIds> AccountTracker::GetAccounts() const {
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  const std::string active_account_id =
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      identity_provider_->GetActiveAccountId();
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<AccountIds> accounts;
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::map<std::string, AccountState>::const_iterator it =
532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           accounts_.begin();
542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != accounts_.end();
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const AccountState& state = it->second;
572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool is_visible = state.is_signed_in && !state.ids.gaia.empty();
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (it->first == active_account_id) {
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if (is_visible)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        accounts.insert(accounts.begin(), state.ids);
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      else
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        return std::vector<AccountIds>();
642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } else if (is_visible) {
662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      accounts.push_back(state.ids);
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return accounts;
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AccountIds AccountTracker::FindAccountIdsByGaiaId(const std::string& gaia_id) {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::map<std::string, AccountState>::const_iterator it =
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           accounts_.begin();
75424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)       it != accounts_.end();
76868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)       ++it) {
77868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    const AccountState& state = it->second;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if (state.ids.gaia == gaia_id) {
79868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)      return state.ids;
80424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)    }
81868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  }
82424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
83868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  return AccountIds();
84424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)}
85424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)
86868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void AccountTracker::OnRefreshTokenAvailable(const std::string& account_id) {
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT1("identity",
88868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)               "AccountTracker::OnRefreshTokenAvailable",
892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "account_key",
902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               account_id);
91868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Ignore refresh tokens if there is no active account ID at all.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (identity_provider_->GetActiveAccountId().empty())
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return;
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "AVAILABLE " << account_id;
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateSignInState(account_id, true);
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccountTracker::OnRefreshTokenRevoked(const std::string& account_id) {
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT1("identity",
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "AccountTracker::OnRefreshTokenRevoked",
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               "account_key",
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)               account_id);
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "REVOKED " << account_id;
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  UpdateSignInState(account_id, false);
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccountTracker::OnActiveAccountLogin() {
1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("identity", "AccountTracker::OnActiveAccountLogin");
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::vector<std::string> accounts =
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      identity_provider_->GetTokenService()->GetAccounts();
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "LOGIN " << accounts.size() << " accounts available.";
1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  for (std::vector<std::string>::const_iterator it = accounts.begin();
1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       it != accounts.end();
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)       ++it) {
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    OnRefreshTokenAvailable(*it);
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccountTracker::OnActiveAccountLogout() {
1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TRACE_EVENT0("identity", "AccountTracker::OnActiveAccountLogout");
1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "LOGOUT";
1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  StopTrackingAllAccounts();
1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccountTracker::SetAccountStateForTest(AccountIds ids, bool is_signed_in) {
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  accounts_[ids.account_key].ids = ids;
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  accounts_[ids.account_key].is_signed_in = is_signed_in;
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DVLOG(1) << "SetAccountStateForTest " << ids.account_key << ":"
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)           << is_signed_in;
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (VLOG_IS_ON(1)) {
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    for (std::map<std::string, AccountState>::const_iterator it =
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             accounts_.begin();
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         it != accounts_.end();
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)         ++it) {
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      DVLOG(1) << it->first << ":" << it->second.is_signed_in;
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    }
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccountTracker::NotifyAccountAdded(const AccountState& account) {
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(!account.ids.gaia.empty());
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FOR_EACH_OBSERVER(
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Observer, observer_list_, OnAccountAdded(account.ids));
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccountTracker::NotifyAccountRemoved(const AccountState& account) {
155  DCHECK(!account.ids.gaia.empty());
156  FOR_EACH_OBSERVER(
157      Observer, observer_list_, OnAccountRemoved(account.ids));
158}
159
160void AccountTracker::NotifySignInChanged(const AccountState& account) {
161  DCHECK(!account.ids.gaia.empty());
162  FOR_EACH_OBSERVER(Observer,
163                    observer_list_,
164                    OnAccountSignInChanged(account.ids, account.is_signed_in));
165}
166
167void AccountTracker::UpdateSignInState(const std::string account_key,
168                                       bool is_signed_in) {
169  StartTrackingAccount(account_key);
170  AccountState& account = accounts_[account_key];
171  bool needs_gaia_id = account.ids.gaia.empty();
172  bool was_signed_in = account.is_signed_in;
173  account.is_signed_in = is_signed_in;
174
175  if (needs_gaia_id && is_signed_in)
176    StartFetchingUserInfo(account_key);
177
178  if (!needs_gaia_id && (was_signed_in != is_signed_in))
179    NotifySignInChanged(account);
180}
181
182void AccountTracker::StartTrackingAccount(const std::string account_key) {
183  if (!ContainsKey(accounts_, account_key)) {
184    DVLOG(1) << "StartTracking " << account_key;
185    AccountState account_state;
186    account_state.ids.account_key = account_key;
187    account_state.ids.email = account_key;
188    account_state.is_signed_in = false;
189    accounts_.insert(make_pair(account_key, account_state));
190  }
191}
192
193void AccountTracker::StopTrackingAccount(const std::string account_key) {
194  DVLOG(1) << "StopTracking " << account_key;
195  if (ContainsKey(accounts_, account_key)) {
196    AccountState& account = accounts_[account_key];
197    if (!account.ids.gaia.empty()) {
198      UpdateSignInState(account_key, false);
199      NotifyAccountRemoved(account);
200    }
201    accounts_.erase(account_key);
202  }
203
204  if (ContainsKey(user_info_requests_, account_key))
205    DeleteFetcher(user_info_requests_[account_key]);
206}
207
208void AccountTracker::StopTrackingAllAccounts() {
209  while (!accounts_.empty())
210    StopTrackingAccount(accounts_.begin()->first);
211}
212
213void AccountTracker::StartFetchingUserInfo(const std::string account_key) {
214  if (ContainsKey(user_info_requests_, account_key))
215    DeleteFetcher(user_info_requests_[account_key]);
216
217  DVLOG(1) << "StartFetching " << account_key;
218  AccountIdFetcher* fetcher =
219      new AccountIdFetcher(identity_provider_->GetTokenService(),
220                           request_context_getter_.get(),
221                           this,
222                           account_key);
223  user_info_requests_[account_key] = fetcher;
224  fetcher->Start();
225}
226
227void AccountTracker::OnUserInfoFetchSuccess(AccountIdFetcher* fetcher,
228                                            const std::string& gaia_id) {
229  const std::string& account_key = fetcher->account_key();
230  DCHECK(ContainsKey(accounts_, account_key));
231  AccountState& account = accounts_[account_key];
232
233  account.ids.gaia = gaia_id;
234  NotifyAccountAdded(account);
235
236  if (account.is_signed_in)
237    NotifySignInChanged(account);
238
239  DeleteFetcher(fetcher);
240}
241
242void AccountTracker::OnUserInfoFetchFailure(AccountIdFetcher* fetcher) {
243  LOG(WARNING) << "Failed to get UserInfo for " << fetcher->account_key();
244  std::string key = fetcher->account_key();
245  DeleteFetcher(fetcher);
246  StopTrackingAccount(key);
247}
248
249void AccountTracker::DeleteFetcher(AccountIdFetcher* fetcher) {
250  DVLOG(1) << "DeleteFetcher " << fetcher->account_key();
251  const std::string& account_key = fetcher->account_key();
252  DCHECK(ContainsKey(user_info_requests_, account_key));
253  DCHECK_EQ(fetcher, user_info_requests_[account_key]);
254  user_info_requests_.erase(account_key);
255  delete fetcher;
256}
257
258AccountIdFetcher::AccountIdFetcher(
259    OAuth2TokenService* token_service,
260    net::URLRequestContextGetter* request_context_getter,
261    AccountTracker* tracker,
262    const std::string& account_key)
263    : OAuth2TokenService::Consumer("gaia_account_tracker"),
264      token_service_(token_service),
265      request_context_getter_(request_context_getter),
266      tracker_(tracker),
267      account_key_(account_key) {
268  TRACE_EVENT_ASYNC_BEGIN1(
269      "identity", "AccountIdFetcher", this, "account_key", account_key);
270}
271
272AccountIdFetcher::~AccountIdFetcher() {
273  TRACE_EVENT_ASYNC_END0("identity", "AccountIdFetcher", this);
274}
275
276void AccountIdFetcher::Start() {
277  login_token_request_ = token_service_->StartRequest(
278      account_key_, OAuth2TokenService::ScopeSet(), this);
279}
280
281void AccountIdFetcher::OnGetTokenSuccess(
282    const OAuth2TokenService::Request* request,
283    const std::string& access_token,
284    const base::Time& expiration_time) {
285  TRACE_EVENT_ASYNC_STEP_PAST0(
286      "identity", "AccountIdFetcher", this, "OnGetTokenSuccess");
287  DCHECK_EQ(request, login_token_request_.get());
288
289  gaia_oauth_client_.reset(new gaia::GaiaOAuthClient(request_context_getter_));
290
291  const int kMaxGetUserIdRetries = 3;
292  gaia_oauth_client_->GetUserId(access_token, kMaxGetUserIdRetries, this);
293}
294
295void AccountIdFetcher::OnGetTokenFailure(
296    const OAuth2TokenService::Request* request,
297    const GoogleServiceAuthError& error) {
298  TRACE_EVENT_ASYNC_STEP_PAST1("identity",
299                               "AccountIdFetcher",
300                               this,
301                               "OnGetTokenFailure",
302                               "google_service_auth_error",
303                               error.ToString());
304  LOG(ERROR) << "OnGetTokenFailure: " << error.ToString();
305  DCHECK_EQ(request, login_token_request_.get());
306  tracker_->OnUserInfoFetchFailure(this);
307}
308
309void AccountIdFetcher::OnGetUserIdResponse(const std::string& gaia_id) {
310  TRACE_EVENT_ASYNC_STEP_PAST1("identity",
311                               "AccountIdFetcher",
312                               this,
313                               "OnGetUserIdResponse",
314                               "gaia_id",
315                               gaia_id);
316  tracker_->OnUserInfoFetchSuccess(this, gaia_id);
317}
318
319void AccountIdFetcher::OnOAuthError() {
320  TRACE_EVENT_ASYNC_STEP_PAST0(
321      "identity", "AccountIdFetcher", this, "OnOAuthError");
322  LOG(ERROR) << "OnOAuthError";
323  tracker_->OnUserInfoFetchFailure(this);
324}
325
326void AccountIdFetcher::OnNetworkError(int response_code) {
327  TRACE_EVENT_ASYNC_STEP_PAST1("identity",
328                               "AccountIdFetcher",
329                               this,
330                               "OnNetworkError",
331                               "response_code",
332                               response_code);
333  LOG(ERROR) << "OnNetworkError " << response_code;
334  tracker_->OnUserInfoFetchFailure(this);
335}
336
337}  // namespace gaia
338