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..8e97b7670b994ada16462a2bc84568a55fbdac39 100644 |
--- a/chrome/browser/signin/oauth2_token_service.cc |
+++ b/chrome/browser/signin/oauth2_token_service.cc |
@@ -84,7 +84,8 @@ void OAuth2TokenService::RequestImpl::InformConsumer( |
// - when the Fetcher is destructed if the Fetcher is destructed before it |
// completes fetching (in this case, the waiting requests will be called back |
// with error). |
-class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { |
+class OAuth2TokenService::Fetcher : public RefreshTokenValidationConsumer, |
+ public OAuth2AccessTokenConsumer { |
public: |
// Creates a Fetcher and starts fetching an OAuth2 access token for |
// |refresh_token| and |scopes| in the request context obtained by |getter|. |
@@ -111,6 +112,11 @@ class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { |
const base::Time& expiration_date) OVERRIDE; |
virtual void OnGetTokenFailure(const GoogleServiceAuthError& error) OVERRIDE; |
+ // RefreshTokenValidationConsumer |
+ virtual void OnRefreshTokenValidationComplete( |
+ const std::string& refresh_token, |
+ bool is_valid) OVERRIDE; |
+ |
private: |
Fetcher(OAuth2TokenService* oauth2_token_service, |
net::URLRequestContextGetter* getter, |
@@ -118,7 +124,9 @@ class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { |
const OAuth2TokenService::ScopeSet& scopes, |
base::WeakPtr<RequestImpl> waiting_request); |
void Start(); |
+ void StartAccessTokenFetch(); |
void InformWaitingRequests(); |
+ void InformWaitingRequestsAndQuit(); |
static bool ShouldRetry(const GoogleServiceAuthError& error); |
// |oauth2_token_service_| remains valid for the life of this Fetcher, since |
@@ -183,6 +191,26 @@ OAuth2TokenService::Fetcher::~Fetcher() { |
} |
void OAuth2TokenService::Fetcher::Start() { |
+ if (!oauth2_token_service_->StartRefreshTokenValidation(refresh_token_, |
+ this)) { |
+ StartAccessTokenFetch(); |
+ } |
+} |
+ |
+void OAuth2TokenService::Fetcher::OnRefreshTokenValidationComplete( |
+ const std::string& refresh_token, |
+ bool is_valid) { |
+ DCHECK(refresh_token_ == refresh_token); |
+ if (is_valid) { |
+ StartAccessTokenFetch(); |
+ } else { |
+ error_ = GoogleServiceAuthError( |
+ GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS); |
+ InformWaitingRequestsAndQuit(); |
+ } |
+} |
+ |
+void OAuth2TokenService::Fetcher::StartAccessTokenFetch() { |
fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_.get())); |
fetcher_->Start(GaiaUrls::GetInstance()->oauth2_chrome_client_id(), |
GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), |
@@ -209,11 +237,7 @@ 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); |
+ InformWaitingRequestsAndQuit(); |
} |
void OAuth2TokenService::Fetcher::OnGetTokenFailure( |
@@ -231,14 +255,8 @@ void OAuth2TokenService::Fetcher::OnGetTokenFailure( |
return; |
} |
- // Fetch completes. |
error_ = error; |
- |
- // 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); |
+ InformWaitingRequestsAndQuit(); |
} |
// static |
@@ -261,6 +279,14 @@ void OAuth2TokenService::Fetcher::InformWaitingRequests() { |
waiting_requests_.clear(); |
} |
+void OAuth2TokenService::Fetcher::InformWaitingRequestsAndQuit() { |
+ // 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); |
@@ -298,11 +324,6 @@ OAuth2TokenService::~OAuth2TokenService() { |
pending_fetchers_.begin(), pending_fetchers_.end()); |
} |
-bool OAuth2TokenService::RefreshTokenIsAvailable() { |
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
- return !GetRefreshToken().empty(); |
-} |
- |
scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( |
const OAuth2TokenService::ScopeSet& scopes, |
OAuth2TokenService::Consumer* consumer) { |
@@ -323,11 +344,11 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( |
} |
if (HasCacheEntry(scopes)) |
- return StartCacheLookupRequest(scopes, consumer); |
+ return StartCacheLookupRequest(scopes, request.Pass()); |
- // 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 +356,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(), |
@@ -347,10 +369,9 @@ scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( |
scoped_ptr<OAuth2TokenService::Request> |
OAuth2TokenService::StartCacheLookupRequest( |
const OAuth2TokenService::ScopeSet& scopes, |
- OAuth2TokenService::Consumer* consumer) { |
+ scoped_ptr<RequestImpl> request) { |
CHECK(HasCacheEntry(scopes)); |
const CacheEntry* cache_entry = GetCacheEntry(scopes); |
- scoped_ptr<RequestImpl> request(new RequestImpl(consumer)); |
base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
&RequestImpl::InformConsumer, |
request->AsWeakPtr(), |
@@ -451,6 +472,12 @@ void OAuth2TokenService::RegisterCacheEntry( |
token.expiration_date = expiration_date; |
} |
+bool OAuth2TokenService::StartRefreshTokenValidation( |
+ const std::string refresh_token, |
+ RefreshTokenValidationConsumer* consumer) { |
+ return false; // No validation needed; use token directly. |
+} |
+ |
void OAuth2TokenService::UpdateAuthError(const GoogleServiceAuthError& error) { |
// Default implementation does nothing. |
} |