oauth2_token_service.cc revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
1424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// Copyright 2013 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) 5424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "google_apis/gaia/oauth2_token_service.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <vector> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/bind.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h" 119ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/rand_util.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/stl_util.h" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/timer/timer.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "google_apis/gaia/gaia_urls.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h" 18c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint OAuth2TokenService::max_fetch_retry_num_ = 5; 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)OAuth2TokenService::RequestParameters::RequestParameters( 2358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 2558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet& scopes) 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : client_id(client_id), 2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id(account_id), 2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scopes(scopes) { 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)OAuth2TokenService::RequestParameters::~RequestParameters() { 3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool OAuth2TokenService::RequestParameters::operator<( 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& p) const { 3658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (client_id < p.client_id) 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) else if (p.client_id < client_id) 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (account_id < p.account_id) 4258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else if (p.account_id < account_id) 4458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return scopes < p.scopes; 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::RequestImpl::RequestImpl( 50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& account_id, 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuth2TokenService::Consumer* consumer) 52f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : account_id_(account_id), 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) consumer_(consumer) { 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::RequestImpl::~RequestImpl() { 57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 60f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string OAuth2TokenService::RequestImpl::GetAccountId() const { 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return account_id_; 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string OAuth2TokenService::RequestImpl::GetConsumerId() const { 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return consumer_->id(); 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::RequestImpl::InformConsumer( 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GoogleServiceAuthError& error, 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& access_token, 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& expiration_date) { 72424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error.state() == GoogleServiceAuthError::NONE) 74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) consumer_->OnGetTokenSuccess(this, access_token, expiration_date); 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 76c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) consumer_->OnGetTokenFailure(this, error); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// Class that fetches an OAuth2 access token for a given set of scopes and 8058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// OAuth2 refresh token. 8158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Class that fetches OAuth2 access tokens for given scopes and refresh token. 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// It aims to meet OAuth2TokenService's requirements on token fetching. Retry 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// mechanism is used to handle failures. 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To use this class, call CreateAndStart() to create and start a Fetcher. 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The Fetcher will call back the service by calling 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// not destructed before it completes fetching; if the Fetcher is destructed 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// before it completes fetching, the service will never be called back. The 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Fetcher destructs itself after calling back the service when finishes 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// fetching. 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Requests that are waiting for the fetching results of this Fetcher can be 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// added to the Fetcher by calling 9858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// OAuth2TokenService::Fetcher::AddWaitingRequest() before the Fetcher 9958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// completes fetching. 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 10158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// The waiting requests are taken as weak pointers and they can be deleted. 10258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// The waiting requests will be called back with fetching results if they are 10358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// not deleted 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - when the Fetcher completes fetching, if the Fetcher is not destructed 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// before it completes fetching, or 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - when the Fetcher is destructed if the Fetcher is destructed before it 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// completes fetching (in this case, the waiting requests will be called 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// back with error). 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates a Fetcher and starts fetching an OAuth2 access token for 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |refresh_token| and |scopes| in the request context obtained by |getter|. 113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The given |oauth2_token_service| will be informed when fetching is done. 114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service, 11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestContextGetter* getter, 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 11858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_secret, 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& refresh_token, 12058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet& scopes, 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<RequestImpl> waiting_request); 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~Fetcher(); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add a request that is waiting for the result of this Fetcher. 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Returns count of waiting requests. 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t GetWaitingRequestCount() const; 12958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<base::WeakPtr<RequestImpl> >& waiting_requests() const { 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return waiting_requests_; 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 134a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void Cancel(); 135a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet& GetScopeSet() const; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& GetRefreshToken() const; 13858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& GetClientId() const; 13968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& GetAccountId() const; 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The error result from this fetcher. 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GoogleServiceAuthError& error() const { return error_; } 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OAuth2AccessTokenConsumer 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnGetTokenSuccess(const std::string& access_token, 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& expiration_date) OVERRIDE; 14858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual void OnGetTokenFailure( 14958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const GoogleServiceAuthError& error) OVERRIDE; 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Fetcher(OAuth2TokenService* oauth2_token_service, 15368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestContextGetter* getter, 15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_secret, 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& refresh_token, 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<RequestImpl> waiting_request); 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Start(); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void InformWaitingRequests(); 162eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void InformWaitingRequestsAndDelete(); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool ShouldRetry(const GoogleServiceAuthError& error); 164eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 ComputeExponentialBackOffMilliseconds(int retry_num); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |oauth2_token_service_| remains valid for the life of this Fetcher, since 167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // this Fetcher is destructed in the dtor of the OAuth2TokenService or is 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess 169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // (whichever comes first). 170c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2TokenService* const oauth2_token_service_; 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> getter_; 17268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string account_id_; 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string refresh_token_; 17458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet scopes_; 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int retry_number_; 17858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::OneShotTimer<Fetcher> retry_timer_; 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Variables that store fetch results. 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // destruction. 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GoogleServiceAuthError error_; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string access_token_; 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time expiration_date_; 18758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 188a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // OAuth2 client id and secret. 18958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string client_id_; 19058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string client_secret_; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Fetcher); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart( 197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2TokenService* oauth2_token_service, 19868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestContextGetter* getter, 20058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 20158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_secret, 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& refresh_token, 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<RequestImpl> waiting_request) { 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuth2TokenService::Fetcher* fetcher = new Fetcher( 206a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) oauth2_token_service, 20768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 208a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) getter, 20958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_id, 21058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_secret, 211a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) refresh_token, 212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 213a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) waiting_request); 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fetcher->Start(); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return fetcher; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Fetcher::Fetcher( 219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2TokenService* oauth2_token_service, 22068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestContextGetter* getter, 22258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 22358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_secret, 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& refresh_token, 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<RequestImpl> waiting_request) 227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : oauth2_token_service_(oauth2_token_service), 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) getter_(getter), 22968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id_(account_id), 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) refresh_token_(refresh_token), 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scopes_(scopes), 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) retry_number_(0), 233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE), 23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_id_(client_id), 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_secret_(client_secret) { 236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(oauth2_token_service_); 237868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(getter_.get()); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(refresh_token_.length()); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_requests_.push_back(waiting_request); 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Fetcher::~Fetcher() { 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Inform the waiting requests if it has not done so. 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (waiting_requests_.size()) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InformWaitingRequests(); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::Fetcher::Start() { 249868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) fetcher_.reset(new OAuth2AccessTokenFetcher(this, getter_.get())); 25058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fetcher_->Start(client_id_, 25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_secret_, 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) refresh_token_, 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string>(scopes_.begin(), scopes_.end())); 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) retry_timer_.Stop(); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::Fetcher::OnGetTokenSuccess( 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& access_token, 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& expiration_date) { 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fetcher_.reset(); 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fetch completes. 263c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = GoogleServiceAuthError::AuthErrorNone(); 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) access_token_ = access_token; 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expiration_date_ = expiration_date; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Subclasses may override this method to skip caching in some cases, but 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // we still inform all waiting Consumers of a successful token fetch below. 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This is intentional -- some consumers may need the token for cleanup 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // tasks. https://chromiumcodereview.appspot.com/11312124/ 27158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) oauth2_token_service_->RegisterCacheEntry(client_id_, 27268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id_, 273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scopes_, 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) access_token_, 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expiration_date_); 276eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch InformWaitingRequestsAndDelete(); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::Fetcher::OnGetTokenFailure( 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GoogleServiceAuthError& error) { 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fetcher_.reset(); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 283eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ShouldRetry(error) && retry_number_ < max_fetch_retry_num_) { 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta backoff = base::TimeDelta::FromMilliseconds( 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ComputeExponentialBackOffMilliseconds(retry_number_)); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++retry_number_; 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) retry_timer_.Stop(); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) retry_timer_.Start(FROM_HERE, 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) backoff, 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &OAuth2TokenService::Fetcher::Start); 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_ = error; 296eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch InformWaitingRequestsAndDelete(); 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 299eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Returns an exponential backoff in milliseconds including randomness less than 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 1000 ms when retrying fetching an OAuth2 access token. 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint64 OAuth2TokenService::Fetcher::ComputeExponentialBackOffMilliseconds( 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int retry_num) { 303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(retry_num < max_fetch_retry_num_); 304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 exponential_backoff_in_seconds = 1 << retry_num; 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns a backoff with randomness < 1000ms 306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return (exponential_backoff_in_seconds + base::RandDouble()) * 1000; 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool OAuth2TokenService::Fetcher::ShouldRetry( 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GoogleServiceAuthError& error) { 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GoogleServiceAuthError::State error_state = error.state(); 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return error_state == GoogleServiceAuthError::CONNECTION_FAILED || 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_state == GoogleServiceAuthError::REQUEST_CANCELED || 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_state == GoogleServiceAuthError::SERVICE_UNAVAILABLE; 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::Fetcher::InformWaitingRequests() { 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::WeakPtr<RequestImpl> >::const_iterator iter = 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_requests_.begin(); 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (; iter != waiting_requests_.end(); ++iter) { 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<RequestImpl> waiting_request = *iter; 323868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (waiting_request.get()) 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_request->InformConsumer(error_, access_token_, expiration_date_); 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_requests_.clear(); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OAuth2TokenService::Fetcher::InformWaitingRequestsAndDelete() { 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Deregisters itself from the service to prevent more waiting requests to 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // be added when it calls back the waiting requests. 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch oauth2_token_service_->OnFetchComplete(this); 333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch InformWaitingRequests(); 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::Fetcher::AddWaitingRequest( 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<OAuth2TokenService::RequestImpl> waiting_request) { 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_requests_.push_back(waiting_request); 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)size_t OAuth2TokenService::Fetcher::GetWaitingRequestCount() const { 34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return waiting_requests_.size(); 34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void OAuth2TokenService::Fetcher::Cancel() { 347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetcher_.reset(); 348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) retry_timer_.Stop(); 349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) error_ = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED); 350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) InformWaitingRequestsAndDelete(); 351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet() 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const { 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scopes_; 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const std::string& OAuth2TokenService::Fetcher::GetRefreshToken() const { 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return refresh_token_; 3602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const std::string& OAuth2TokenService::Fetcher::GetClientId() const { 36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return client_id_; 36458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 36558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const std::string& OAuth2TokenService::Fetcher::GetAccountId() const { 36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return account_id_; 36868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 36968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Request::Request() { 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Request::~Request() { 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)OAuth2TokenService::Consumer::Consumer(const std::string& id) 3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : id_(id) {} 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Consumer::~Consumer() { 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 382ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben MurdochOAuth2TokenService::OAuth2TokenService() { 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::~OAuth2TokenService() { 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Release all the pending fetchers. 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STLDeleteContainerPairSecondPointers( 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_fetchers_.begin(), pending_fetchers_.end()); 3892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::AddObserver(Observer* observer) { 3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch observer_list_.AddObserver(observer); 3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::RemoveObserver(Observer* observer) { 3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch observer_list_.RemoveObserver(observer); 3977dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3987dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OAuth2TokenService::AddDiagnosticsObserver(DiagnosticsObserver* observer) { 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) diagnostics_observer_list_.AddObserver(observer); 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OAuth2TokenService::RemoveDiagnosticsObserver( 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DiagnosticsObserver* observer) { 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) diagnostics_observer_list_.RemoveObserver(observer); 4065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 40868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool OAuth2TokenService::RefreshTokenIsAvailable( 40968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id) { 41068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(CalledOnValidThread()); 41168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return !GetRefreshToken(account_id).empty(); 41268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 41368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 41468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<std::string> OAuth2TokenService::GetAccounts() { 41568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return std::vector<std::string>(); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( 41968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return StartRequestForClientWithContext( 42368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetRequestContext(), 425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) consumer); 429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<OAuth2TokenService::Request> 432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)OAuth2TokenService::StartRequestForClient( 43368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, 435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_secret, 436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 437a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 438a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return StartRequestForClientWithContext( 43968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 440a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetRequestContext(), 441a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_id, 442a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_secret, 443a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) consumer); 44558e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch} 44658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 44758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochscoped_ptr<OAuth2TokenService::Request> 44858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochOAuth2TokenService::StartRequestWithContext( 44968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 45058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch net::URLRequestContextGetter* getter, 45158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch const ScopeSet& scopes, 45258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch Consumer* consumer) { 453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return StartRequestForClientWithContext( 45468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) getter, 456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 457a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) consumer); 460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 462a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<OAuth2TokenService::Request> 463a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)OAuth2TokenService::StartRequestForClientWithContext( 46468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 465a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) net::URLRequestContextGetter* getter, 466a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, 467a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_secret, 468a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const ScopeSet& scopes, 469a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Consumer* consumer) { 470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 4712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_ptr<RequestImpl> request = CreateRequest(account_id, consumer); 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnAccessTokenRequested(account_id, 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consumer->id(), 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scopes)); 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 47868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!RefreshTokenIsAvailable(account_id)) { 4795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GoogleServiceAuthError error(GoogleServiceAuthError::USER_NOT_SIGNED_UP); 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 4825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnFetchAccessTokenComplete( 4835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) account_id, consumer->id(), scopes, error, 4845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time())); 4855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 48690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 487868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &RequestImpl::InformConsumer, 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request->AsWeakPtr(), 4895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error, 4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string(), 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time())); 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return request.PassAs<Request>(); 4932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 49568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RequestParameters request_parameters(client_id, 49668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 49768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes); 49868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (HasCacheEntry(request_parameters)) { 49968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) StartCacheLookupRequest(request.get(), request_parameters, consumer); 5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FetchOAuth2Token(request.get(), 50268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) getter, 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_id, 5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_secret, 5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scopes); 5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return request.PassAs<Request>(); 5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 51168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)scoped_ptr<OAuth2TokenService::RequestImpl> OAuth2TokenService::CreateRequest( 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& account_id, 51368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) Consumer* consumer) { 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return scoped_ptr<RequestImpl>(new RequestImpl(account_id, consumer)); 51568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 51668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void OAuth2TokenService::FetchOAuth2Token(RequestImpl* request, 51868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::URLRequestContextGetter* getter, 5203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& client_id, 5213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& client_secret, 5223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ScopeSet& scopes) { 52368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::string refresh_token = GetRefreshToken(account_id); 524c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 52568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If there is already a pending fetcher for |scopes| and |account_id|, 526eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // simply register this |request| for those results rather than starting 527eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // a new fetcher. 52868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RequestParameters request_parameters = RequestParameters(client_id, 52968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 53068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes); 53168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::map<RequestParameters, Fetcher*>::iterator iter = 53268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending_fetchers_.find(request_parameters); 5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter != pending_fetchers_.end()) { 5342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter->second->AddWaitingRequest(request->AsWeakPtr()); 5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 537eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 53868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending_fetchers_[request_parameters] = 539a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Fetcher::CreateAndStart(this, 54068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 541a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) getter, 542a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_id, 543a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_secret, 544a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) refresh_token, 545a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->AsWeakPtr()); 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void OAuth2TokenService::StartCacheLookupRequest( 5503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RequestImpl* request, 55168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const OAuth2TokenService::RequestParameters& request_parameters, 5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 55368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CHECK(HasCacheEntry(request_parameters)); 55468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CacheEntry* cache_entry = GetCacheEntry(request_parameters); 5555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 5565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnFetchAccessTokenComplete( 5575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_parameters.account_id, 5585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consumer->id(), 5595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_parameters.scopes, 5605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GoogleServiceAuthError::AuthErrorNone(), 5615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cache_entry->expiration_date)); 56290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 563868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &RequestImpl::InformConsumer, 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request->AsWeakPtr(), 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GoogleServiceAuthError(GoogleServiceAuthError::NONE), 566c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache_entry->access_token, 567c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache_entry->expiration_date)); 5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 57068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::InvalidateToken(const std::string& account_id, 57168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 57268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 57368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InvalidateOAuth2Token(account_id, 57468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 57568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes, 57668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) access_token); 57768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 57868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 57968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::InvalidateTokenForClient( 58068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 58168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& client_id, 58268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 58368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 58468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InvalidateOAuth2Token(account_id, client_id, scopes, access_token); 58568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 58668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 58768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::InvalidateOAuth2Token( 58868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 58968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& client_id, 59068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 59168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 592424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 59358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RemoveCacheEntry( 59468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RequestParameters(client_id, 59568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 59668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes), 59768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) access_token); 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 599c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { 601424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update the auth error state so auth errors are appropriately communicated 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to the user. 60568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UpdateAuthError(fetcher->GetAccountId(), fetcher->error()); 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // token and scope set. This is guaranteed as follows; here a Fetcher is said 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to be uncompleted if it has not finished calling back 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OAuth2TokenService::OnFetchComplete(). 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (1) All the live Fetchers are created by this service. 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is because (1) all the live Fetchers are created by a live 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // service, as all the fetchers created by a service are destructed in the 615c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // service's dtor. 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 6172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (2) All the uncompleted Fetchers created by this service are recorded in 6182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |pending_fetchers_|. 6192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is because (1) all the created Fetchers are added to 6202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |pending_fetchers_| (in method StartRequest()) and (2) method 6212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnFetchComplete() is the only place where a Fetcher is erased from 6222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |pending_fetchers_|. Note no Fetcher is erased in method 6232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StartRequest(). 6242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 6252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its 6262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // refresh token and ScopeSet. This is guaranteed by Fetcher creation in 627c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // method StartRequest(). 6282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 6292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When this method is called, |fetcher| is alive and uncompleted. 6302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // By (1), |fetcher| is created by this service. 6312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then by (2), |fetcher| is recorded in |pending_fetchers_|. 6322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RequestParameters request_param(fetcher->GetClientId(), 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->GetAccountId(), 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->GetScopeSet()); 6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const OAuth2TokenService::CacheEntry* entry = GetCacheEntry(request_param); 6385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<base::WeakPtr<RequestImpl> >& requests = 6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->waiting_requests(); 6405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < requests.size(); ++i) { 6415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const RequestImpl* req = requests[i].get(); 6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (req) { 6435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 6445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnFetchAccessTokenComplete( 6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) req->GetAccountId(), req->GetConsumerId(), 6465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->GetScopeSet(), fetcher->error(), 6475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry ? entry->expiration_date : base::Time())); 6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 65168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::map<RequestParameters, Fetcher*>::iterator iter = 6525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_fetchers_.find(request_param); 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(iter != pending_fetchers_.end()); 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(fetcher, iter->second); 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_fetchers_.erase(iter); 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 658c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OAuth2TokenService::HasCacheEntry( 65968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& request_parameters) { 66068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CacheEntry* cache_entry = GetCacheEntry(request_parameters); 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return cache_entry && cache_entry->access_token.length(); 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 663c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry( 66568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& request_parameters) { 666424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 66768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TokenCache::iterator token_iterator = token_cache_.find(request_parameters); 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (token_iterator == token_cache_.end()) 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (token_iterator->second.expiration_date <= base::Time::Now()) { 6712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token_cache_.erase(token_iterator); 6722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &token_iterator->second; 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 677c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OAuth2TokenService::RemoveCacheEntry( 67868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& request_parameters, 679c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& token_to_remove) { 680424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 68168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TokenCache::iterator token_iterator = token_cache_.find(request_parameters); 682868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (token_iterator != token_cache_.end() && 683c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_iterator->second.access_token == token_to_remove) { 6845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 6855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnTokenRemoved(request_parameters.account_id, 6865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_parameters.scopes)); 687c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_cache_.erase(token_iterator); 688c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 689c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 690c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 691c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 692c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::RegisterCacheEntry( 69458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 69568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& access_token, 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& expiration_date) { 699424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 70168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CacheEntry& token = token_cache_[RequestParameters(client_id, 70268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 70368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes)]; 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token.access_token = access_token; 7052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token.expiration_date = expiration_date; 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 70868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::UpdateAuthError( 70968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 71068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const GoogleServiceAuthError& error) { 711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Default implementation does nothing. 712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 714c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OAuth2TokenService::ClearCache() { 715424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (TokenCache::iterator iter = token_cache_.begin(); 7175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter != token_cache_.end(); ++iter) { 7185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 7195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnTokenRemoved(iter->first.account_id, 7205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->first.scopes)); 7215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 723c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_cache_.clear(); 7242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::ClearCacheForAccount(const std::string& account_id) { 72768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(CalledOnValidThread()); 72868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (TokenCache::iterator iter = token_cache_.begin(); 72968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) iter != token_cache_.end(); 73068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /* iter incremented in body */) { 73168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (iter->first.account_id == account_id) { 7325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 7335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnTokenRemoved(account_id, iter->first.scopes)); 73468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) token_cache_.erase(iter++); 73568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 73668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ++iter; 73768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 73868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 73968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 74068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 741a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void OAuth2TokenService::CancelAllRequests() { 742a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Fetcher*> fetchers_to_cancel; 74368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (std::map<RequestParameters, Fetcher*>::iterator iter = 744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pending_fetchers_.begin(); 745a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != pending_fetchers_.end(); 746a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++iter) { 747a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetchers_to_cancel.push_back(iter->second); 748a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 749a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CancelFetchers(fetchers_to_cancel); 750a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 751a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 75268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::CancelRequestsForAccount( 75368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id) { 754a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Fetcher*> fetchers_to_cancel; 75568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (std::map<RequestParameters, Fetcher*>::iterator iter = 756a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pending_fetchers_.begin(); 757a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != pending_fetchers_.end(); 758a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++iter) { 75968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (iter->first.account_id == account_id) 760a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetchers_to_cancel.push_back(iter->second); 761a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 762a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CancelFetchers(fetchers_to_cancel); 763a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 764a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 765a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void OAuth2TokenService::CancelFetchers( 766a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Fetcher*> fetchers_to_cancel) { 767a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = 768a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetchers_to_cancel.begin(); 769a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != fetchers_to_cancel.end(); 770a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++iter) { 771a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) (*iter)->Cancel(); 772a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 773a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 774a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::FireRefreshTokenAvailable( 7767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& account_id) { 7777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, 7787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch OnRefreshTokenAvailable(account_id)); 7797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::FireRefreshTokenRevoked( 7823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& account_id) { 7837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, 7843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OnRefreshTokenRevoked(account_id)); 7857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7867dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::FireRefreshTokensLoaded() { 7887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, OnRefreshTokensLoaded()); 7897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 791c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int OAuth2TokenService::cache_size_for_testing() const { 792c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return token_cache_.size(); 7932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( 796eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int max_retries) { 797424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 798eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch max_fetch_retry_num_ = max_retries; 799eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 80058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 80158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)size_t OAuth2TokenService::GetNumPendingRequestsForTesting( 80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 80368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 80458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet& scopes) const { 80558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PendingFetcherMap::const_iterator iter = pending_fetchers_.find( 80668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) OAuth2TokenService::RequestParameters( 80758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_id, 80868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 80958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scopes)); 81058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return iter == pending_fetchers_.end() ? 81158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0 : iter->second->GetWaitingRequestCount(); 81258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 813