Index: chrome/browser/signin/oauth2_token_service.cc |
diff --git a/chrome/browser/signin/oauth2_token_service.cc b/chrome/browser/signin/oauth2_token_service.cc |
index e21911d00ffee39bea0bd97305fe4fb9eb5c1837..7dfcc38dec56560acb8f422ebed0905b7267f663 100644 |
--- a/chrome/browser/signin/oauth2_token_service.cc |
+++ b/chrome/browser/signin/oauth2_token_service.cc |
@@ -20,21 +20,7 @@ |
#include "google_apis/gaia/oauth2_access_token_fetcher.h" |
#include "net/url_request/url_request_context_getter.h" |
-namespace { |
- |
-// Maximum number of retries in fetching an OAuth2 access token. |
-const int kMaxFetchRetryNum = 5; |
- |
-// Returns an exponential backoff in milliseconds including randomness less than |
-// 1000 ms when retrying fetching an OAuth2 access token. |
-int64 ComputeExponentialBackOffMilliseconds(int retry_num) { |
- DCHECK(retry_num < kMaxFetchRetryNum); |
- int64 exponential_backoff_in_seconds = 1 << retry_num; |
- // Returns a backoff with randomness < 1000ms |
- return (exponential_backoff_in_seconds + base::RandDouble()) * 1000; |
-} |
- |
-} // namespace |
+int OAuth2TokenService::max_fetch_retry_num_ = 5; |
OAuth2TokenService::RequestImpl::RequestImpl( |
OAuth2TokenService::Consumer* consumer) |
@@ -119,7 +105,9 @@ class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { |
base::WeakPtr<RequestImpl> waiting_request); |
void Start(); |
void InformWaitingRequests(); |
+ void InformWaitingRequestsAndDelete(); |
static bool ShouldRetry(const GoogleServiceAuthError& error); |
+ int64 ComputeExponentialBackOffMilliseconds(int retry_num); |
// |oauth2_token_service_| remains valid for the life of this Fetcher, since |
// this Fetcher is destructed in the dtor of the OAuth2TokenService or is |
@@ -209,18 +197,14 @@ void OAuth2TokenService::Fetcher::OnGetTokenSuccess( |
scopes_, |
access_token_, |
expiration_date_); |
- // Deregisters itself from the service to prevent more waiting requests to |
- // be added when it calls back the waiting requests. |
- oauth2_token_service_->OnFetchComplete(this); |
- InformWaitingRequests(); |
- base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
+ InformWaitingRequestsAndDelete(); |
} |
void OAuth2TokenService::Fetcher::OnGetTokenFailure( |
const GoogleServiceAuthError& error) { |
fetcher_.reset(); |
- if (ShouldRetry(error) && retry_number_ < kMaxFetchRetryNum) { |
+ if (ShouldRetry(error) && retry_number_ < max_fetch_retry_num_) { |
int64 backoff = ComputeExponentialBackOffMilliseconds(retry_number_); |
++retry_number_; |
retry_timer_.Stop(); |
@@ -231,14 +215,18 @@ void OAuth2TokenService::Fetcher::OnGetTokenFailure( |
return; |
} |
- // Fetch completes. |
error_ = error; |
+ InformWaitingRequestsAndDelete(); |
+} |
- // Deregisters itself from the service to prevent more waiting requests to be |
- // added when it calls back the waiting requests. |
- oauth2_token_service_->OnFetchComplete(this); |
- InformWaitingRequests(); |
- base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
+// Returns an exponential backoff in milliseconds including randomness less than |
+// 1000 ms when retrying fetching an OAuth2 access token. |
+int64 OAuth2TokenService::Fetcher::ComputeExponentialBackOffMilliseconds( |
+ int retry_num) { |
+ DCHECK(retry_num < max_fetch_retry_num_); |
+ int64 exponential_backoff_in_seconds = 1 << retry_num; |
+ // Returns a backoff with randomness < 1000ms |
+ return (exponential_backoff_in_seconds + base::RandDouble()) * 1000; |
} |
// static |
@@ -261,6 +249,14 @@ void OAuth2TokenService::Fetcher::InformWaitingRequests() { |
waiting_requests_.clear(); |
} |
+void OAuth2TokenService::Fetcher::InformWaitingRequestsAndDelete() { |
+ // Deregisters itself from the service to prevent more waiting requests to |
+ // be added when it calls back the waiting requests. |
+ oauth2_token_service_->OnFetchComplete(this); |
+ InformWaitingRequests(); |
+ base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); |
+} |
+ |
void OAuth2TokenService::Fetcher::AddWaitingRequest( |
base::WeakPtr<OAuth2TokenService::RequestImpl> waiting_request) { |
waiting_requests_.push_back(waiting_request); |
@@ -325,9 +321,9 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( |
if (HasCacheEntry(scopes)) |
return StartCacheLookupRequest(scopes, consumer); |
- // Makes sure there is a pending fetcher for |scopes| and |refresh_token|. |
- // Adds |request| to the waiting request list of this fetcher so |request| |
- // will be called back when this fetcher finishes fetching. |
+ // If there is already a pending fetcher for |scopes| and |refresh_token|, |
+ // simply register this |request| for those results rather than starting |
+ // a new fetcher. |
FetchParameters fetch_parameters = std::make_pair(refresh_token, scopes); |
std::map<FetchParameters, Fetcher*>::iterator iter = |
pending_fetchers_.find(fetch_parameters); |
@@ -335,6 +331,7 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( |
iter->second->AddWaitingRequest(request->AsWeakPtr()); |
return request.PassAs<Request>(); |
} |
+ |
pending_fetchers_[fetch_parameters] = |
Fetcher::CreateAndStart(this, |
request_context_getter_.get(), |
@@ -463,3 +460,9 @@ void OAuth2TokenService::ClearCache() { |
int OAuth2TokenService::cache_size_for_testing() const { |
return token_cache_.size(); |
} |
+ |
+void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( |
+ int max_retries) { |
+ DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
+ max_fetch_retry_num_ = max_retries; |
+} |