Index: chrome/browser/signin/dice_response_handler.cc |
diff --git a/chrome/browser/signin/dice_response_handler.cc b/chrome/browser/signin/dice_response_handler.cc |
index dd202daca9ccd1cd7af8daa911e4aa6696ddb981..a538af04a42b4aba9abe81b4868864da476c17c1 100644 |
--- a/chrome/browser/signin/dice_response_handler.cc |
+++ b/chrome/browser/signin/dice_response_handler.cc |
@@ -4,8 +4,13 @@ |
#include "chrome/browser/signin/dice_response_handler.h" |
+#include "base/bind.h" |
+#include "base/bind_helpers.h" |
+#include "base/location.h" |
#include "base/logging.h" |
#include "base/memory/singleton.h" |
+#include "base/threading/thread_task_runner_handle.h" |
+#include "base/time/time.h" |
#include "chrome/browser/profiles/profile.h" |
#include "chrome/browser/signin/account_tracker_service_factory.h" |
#include "chrome/browser/signin/chrome_signin_client_factory.h" |
@@ -21,6 +26,8 @@ |
#include "google_apis/gaia/gaia_constants.h" |
#include "google_apis/gaia/google_service_auth_error.h" |
+const int kDiceTokenFetchTimeoutSeconds = 10; |
+ |
namespace { |
class DiceResponseHandlerFactory : public BrowserContextKeyedServiceFactory { |
@@ -78,27 +85,45 @@ DiceResponseHandler::DiceTokenFetcher::DiceTokenFetcher( |
: gaia_id_(gaia_id), |
email_(email), |
authorization_code_(authorization_code), |
- dice_response_handler_(dice_response_handler) { |
+ dice_response_handler_(dice_response_handler), |
+ timeout_closure_( |
+ base::Bind(&DiceResponseHandler::DiceTokenFetcher::OnTimeout, |
+ base::Unretained(this))) { |
+ DCHECK(dice_response_handler_); |
gaia_auth_fetcher_ = signin_client->CreateGaiaAuthFetcher( |
this, GaiaConstants::kChromeSource, |
signin_client->GetURLRequestContext()); |
gaia_auth_fetcher_->StartAuthCodeForOAuth2TokenExchange(authorization_code_); |
- |
- // TODO(droger): The token exchange must complete quickly or be cancelled. Add |
- // a timeout logic. |
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
+ FROM_HERE, timeout_closure_.callback(), |
+ base::TimeDelta::FromSeconds(kDiceTokenFetchTimeoutSeconds)); |
} |
DiceResponseHandler::DiceTokenFetcher::~DiceTokenFetcher() {} |
+void DiceResponseHandler::DiceTokenFetcher::OnTimeout() { |
+ gaia_auth_fetcher_.reset(); |
+ timeout_closure_.Cancel(); |
+ dice_response_handler_->OnTokenExchangeFailure( |
+ this, GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED)); |
+ // |this| may be deleted at this point. |
+} |
+ |
void DiceResponseHandler::DiceTokenFetcher::OnClientOAuthSuccess( |
const GaiaAuthConsumer::ClientOAuthResult& result) { |
+ gaia_auth_fetcher_.reset(); |
+ timeout_closure_.Cancel(); |
dice_response_handler_->OnTokenExchangeSuccess(this, gaia_id_, email_, |
result); |
+ // |this| may be deleted at this point. |
} |
void DiceResponseHandler::DiceTokenFetcher::OnClientOAuthFailure( |
const GoogleServiceAuthError& error) { |
+ gaia_auth_fetcher_.reset(); |
+ timeout_closure_.Cancel(); |
dice_response_handler_->OnTokenExchangeFailure(this, error); |
+ // |this| may be deleted at this point. |
} |
//////////////////////////////////////////////////////////////////////////////// |
@@ -147,6 +172,10 @@ void DiceResponseHandler::ProcessDiceHeader( |
return; |
} |
+size_t DiceResponseHandler::GetPendingDiceTokenFetchersCountForTesting() const { |
+ return token_fetchers_.size(); |
+} |
+ |
void DiceResponseHandler::ProcessDiceSigninHeader( |
const std::string& gaia_id, |
const std::string& email, |