oauth2_token_fetcher.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
1// Copyright (c) 2013 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 "chrome/browser/chromeos/login/oauth2_token_fetcher.h" 6 7#include "base/logging.h" 8#include "base/strings/string_util.h" 9#include "chrome/browser/chromeos/net/connectivity_state_helper.h" 10#include "content/public/browser/browser_thread.h" 11#include "google_apis/gaia/gaia_constants.h" 12#include "google_apis/gaia/google_service_auth_error.h" 13 14using content::BrowserThread; 15 16namespace { 17 18// OAuth token request max retry count. 19const int kMaxRequestAttemptCount = 5; 20// OAuth token request retry delay in milliseconds. 21const int kRequestRestartDelay = 3000; 22 23} // namespace 24 25namespace chromeos { 26 27OAuth2TokenFetcher::OAuth2TokenFetcher( 28 OAuth2TokenFetcher::Delegate* delegate, 29 net::URLRequestContextGetter* context_getter) 30 : delegate_(delegate), 31 auth_fetcher_(this, GaiaConstants::kChromeSource, context_getter), 32 retry_count_(0) { 33 DCHECK(delegate); 34} 35 36OAuth2TokenFetcher::~OAuth2TokenFetcher() { 37} 38 39void OAuth2TokenFetcher::StartExchangeFromCookies() { 40 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 41 42 // Delay the verification if the network is not connected or on a captive 43 // portal. 44 ConnectivityStateHelper* csh = ConnectivityStateHelper::Get(); 45 if (!csh->DefaultNetworkOnline()) { 46 // If network is offline, defer the token fetching until online. 47 VLOG(1) << "Network is offline. Deferring OAuth2 token fetch."; 48 BrowserThread::PostDelayedTask( 49 BrowserThread::UI, FROM_HERE, 50 base::Bind(&OAuth2TokenFetcher::StartExchangeFromCookies, 51 AsWeakPtr()), 52 base::TimeDelta::FromMilliseconds(kRequestRestartDelay)); 53 return; 54 } 55 auth_fetcher_.StartCookieForOAuthLoginTokenExchange(EmptyString()); 56} 57 58void OAuth2TokenFetcher::StartExchangeFromAuthCode( 59 const std::string& auth_code) { 60 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 61 auth_code_ = auth_code; 62 // Delay the verification if the network is not connected or on a captive 63 // portal. 64 ConnectivityStateHelper* csh = ConnectivityStateHelper::Get(); 65 if (!csh->DefaultNetworkOnline()) { 66 // If network is offline, defer the token fetching until online. 67 VLOG(1) << "Network is offline. Deferring OAuth2 token fetch."; 68 BrowserThread::PostDelayedTask( 69 BrowserThread::UI, FROM_HERE, 70 base::Bind(&OAuth2TokenFetcher::StartExchangeFromAuthCode, 71 AsWeakPtr(), 72 auth_code), 73 base::TimeDelta::FromMilliseconds(kRequestRestartDelay)); 74 return; 75 } 76 auth_fetcher_.StartAuthCodeForOAuth2TokenExchange(auth_code); 77} 78 79void OAuth2TokenFetcher::OnClientOAuthSuccess( 80 const GaiaAuthConsumer::ClientOAuthResult& oauth_tokens) { 81 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 82 LOG(INFO) << "Got OAuth2 tokens!"; 83 retry_count_ = 0; 84 oauth_tokens_ = oauth_tokens; 85 delegate_->OnOAuth2TokensAvailable(oauth_tokens_); 86} 87 88void OAuth2TokenFetcher::OnClientOAuthFailure( 89 const GoogleServiceAuthError& error) { 90 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 91 RetryOnError( 92 error, 93 auth_code_.empty() ? 94 base::Bind(&OAuth2TokenFetcher::StartExchangeFromCookies, 95 AsWeakPtr()) : 96 base::Bind(&OAuth2TokenFetcher::StartExchangeFromAuthCode, 97 AsWeakPtr(), auth_code_), 98 base::Bind(&Delegate::OnOAuth2TokensFetchFailed, 99 base::Unretained(delegate_))); 100} 101 102void OAuth2TokenFetcher::RetryOnError(const GoogleServiceAuthError& error, 103 const base::Closure& task, 104 const base::Closure& error_handler) { 105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 106 if ((error.state() == GoogleServiceAuthError::CONNECTION_FAILED || 107 error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE || 108 error.state() == GoogleServiceAuthError::REQUEST_CANCELED) && 109 retry_count_ < kMaxRequestAttemptCount) { 110 retry_count_++; 111 BrowserThread::PostDelayedTask( 112 BrowserThread::UI, FROM_HERE, task, 113 base::TimeDelta::FromMilliseconds(kRequestRestartDelay)); 114 return; 115 } 116 LOG(ERROR) << "Unrecoverable error or retry count max reached. State: " 117 << error.state() << ", network error: " << error.network_error() 118 << ", message: " << error.error_message(); 119 error_handler.Run(); 120} 121 122} // namespace chromeos 123