oauth2_token_service.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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" 18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "google_apis/gaia/oauth2_access_token_fetcher_impl.h" 19c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/url_request/url_request_context_getter.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 21eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint OAuth2TokenService::max_fetch_retry_num_ = 5; 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)OAuth2TokenService::RequestParameters::RequestParameters( 2458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 2658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet& scopes) 2758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) : client_id(client_id), 2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id(account_id), 2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scopes(scopes) { 3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)OAuth2TokenService::RequestParameters::~RequestParameters() { 3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 3458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool OAuth2TokenService::RequestParameters::operator<( 3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& p) const { 3758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (client_id < p.client_id) 3858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 3958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) else if (p.client_id < client_id) 4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 4158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (account_id < p.account_id) 4358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return true; 4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) else if (p.account_id < account_id) 4558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return false; 4658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 4758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return scopes < p.scopes; 4858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 4958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::RequestImpl::RequestImpl( 51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const std::string& account_id, 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuth2TokenService::Consumer* consumer) 53f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) : account_id_(account_id), 54f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) consumer_(consumer) { 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::RequestImpl::~RequestImpl() { 58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 61f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)std::string OAuth2TokenService::RequestImpl::GetAccountId() const { 62f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return account_id_; 63f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 64f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)std::string OAuth2TokenService::RequestImpl::GetConsumerId() const { 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return consumer_->id(); 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::RequestImpl::InformConsumer( 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GoogleServiceAuthError& error, 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& access_token, 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& expiration_date) { 73424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error.state() == GoogleServiceAuthError::NONE) 75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) consumer_->OnGetTokenSuccess(this, access_token, expiration_date); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 77c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) consumer_->OnGetTokenFailure(this, error); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 80116680a4aac90f2aa7413d9095a592090648e557Ben MurdochOAuth2TokenService::ScopedBacthChange::ScopedBacthChange( 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch OAuth2TokenService* token_service) : token_service_(token_service) { 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK(token_service_); 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch token_service_->StartBatchChanges(); 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 86116680a4aac90f2aa7413d9095a592090648e557Ben MurdochOAuth2TokenService::ScopedBacthChange::~ScopedBacthChange() { 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch token_service_->EndBatchChanges(); 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// Class that fetches an OAuth2 access token for a given account id and set of 91a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)// scopes. 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// It aims to meet OAuth2TokenService's requirements on token fetching. Retry 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// mechanism is used to handle failures. 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// To use this class, call CreateAndStart() to create and start a Fetcher. 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// The Fetcher will call back the service by calling 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// not destructed before it completes fetching; if the Fetcher is destructed 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// before it completes fetching, the service will never be called back. The 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Fetcher destructs itself after calling back the service when finishes 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// fetching. 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Requests that are waiting for the fetching results of this Fetcher can be 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// added to the Fetcher by calling 10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// OAuth2TokenService::Fetcher::AddWaitingRequest() before the Fetcher 10858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// completes fetching. 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// The waiting requests are taken as weak pointers and they can be deleted. 11158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// The waiting requests will be called back with fetching results if they are 11258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// not deleted 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - when the Fetcher completes fetching, if the Fetcher is not destructed 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// before it completes fetching, or 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// - when the Fetcher is destructed if the Fetcher is destructed before it 11658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// completes fetching (in this case, the waiting requests will be called 11758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)// back with error). 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer { 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates a Fetcher and starts fetching an OAuth2 access token for 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) // |account_id| and |scopes| in the request context obtained by |getter|. 122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The given |oauth2_token_service| will be informed when fetching is done. 123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service, 12468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestContextGetter* getter, 12658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 12758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_secret, 12858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet& scopes, 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<RequestImpl> waiting_request); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~Fetcher(); 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Add a request that is waiting for the result of this Fetcher. 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request); 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 13558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // Returns count of waiting requests. 13658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) size_t GetWaitingRequestCount() const; 13758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<base::WeakPtr<RequestImpl> >& waiting_requests() const { 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return waiting_requests_; 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 142a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) void Cancel(); 143a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 14458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet& GetScopeSet() const; 14558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& GetClientId() const; 14668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& GetAccountId() const; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The error result from this fetcher. 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GoogleServiceAuthError& error() const { return error_; } 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) protected: 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OAuth2AccessTokenConsumer 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnGetTokenSuccess(const std::string& access_token, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& expiration_date) OVERRIDE; 15558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) virtual void OnGetTokenFailure( 15658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const GoogleServiceAuthError& error) OVERRIDE; 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Fetcher(OAuth2TokenService* oauth2_token_service, 16068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestContextGetter* getter, 16258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 16358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_secret, 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<RequestImpl> waiting_request); 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Start(); 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void InformWaitingRequests(); 168eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch void InformWaitingRequestsAndDelete(); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static bool ShouldRetry(const GoogleServiceAuthError& error); 170eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 ComputeExponentialBackOffMilliseconds(int retry_num); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 172c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // |oauth2_token_service_| remains valid for the life of this Fetcher, since 173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // this Fetcher is destructed in the dtor of the OAuth2TokenService or is 174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess 175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // (whichever comes first). 176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2TokenService* const oauth2_token_service_; 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<net::URLRequestContextGetter> getter_; 17868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string account_id_; 17958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet scopes_; 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::WeakPtr<RequestImpl> > waiting_requests_; 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int retry_number_; 18358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) base::OneShotTimer<Fetcher> retry_timer_; 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<OAuth2AccessTokenFetcher> fetcher_; 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Variables that store fetch results. 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // destruction. 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GoogleServiceAuthError error_; 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string access_token_; 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time expiration_date_; 19258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) // OAuth2 client id and secret. 19458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string client_id_; 19558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) std::string client_secret_; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Fetcher); 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart( 202c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2TokenService* oauth2_token_service, 20368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestContextGetter* getter, 20558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 20658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_secret, 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<RequestImpl> waiting_request) { 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuth2TokenService::Fetcher* fetcher = new Fetcher( 210a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) oauth2_token_service, 21168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 212a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) getter, 21358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_id, 21458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_secret, 215a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 216a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) waiting_request); 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fetcher->Start(); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return fetcher; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Fetcher::Fetcher( 222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) OAuth2TokenService* oauth2_token_service, 22368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net::URLRequestContextGetter* getter, 22558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 22658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_secret, 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<RequestImpl> waiting_request) 229c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) : oauth2_token_service_(oauth2_token_service), 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) getter_(getter), 23168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id_(account_id), 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scopes_(scopes), 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) retry_number_(0), 234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE), 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_id_(client_id), 23658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_secret_(client_secret) { 237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(oauth2_token_service_); 238868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(getter_.get()); 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() { 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetcher_.reset(oauth2_token_service_->CreateAccessTokenFetcher( 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) account_id_, getter_.get(), this)); 251a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(fetcher_); 25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fetcher_->Start(client_id_, 25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_secret_, 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<std::string>(scopes_.begin(), scopes_.end())); 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) retry_timer_.Stop(); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::Fetcher::OnGetTokenSuccess( 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& access_token, 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& expiration_date) { 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fetcher_.reset(); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Fetch completes. 264c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) error_ = GoogleServiceAuthError::AuthErrorNone(); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) access_token_ = access_token; 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) expiration_date_ = expiration_date; 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Subclasses may override this method to skip caching in some cases, but 269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // we still inform all waiting Consumers of a successful token fetch below. 270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // This is intentional -- some consumers may need the token for cleanup 271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // tasks. https://chromiumcodereview.appspot.com/11312124/ 27258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) oauth2_token_service_->RegisterCacheEntry(client_id_, 27368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id_, 274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scopes_, 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) access_token_, 276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) expiration_date_); 277eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch InformWaitingRequestsAndDelete(); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::Fetcher::OnGetTokenFailure( 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GoogleServiceAuthError& error) { 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) fetcher_.reset(); 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 284eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch if (ShouldRetry(error) && retry_number_ < max_fetch_retry_num_) { 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeDelta backoff = base::TimeDelta::FromMilliseconds( 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ComputeExponentialBackOffMilliseconds(retry_number_)); 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ++retry_number_; 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) retry_timer_.Stop(); 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) retry_timer_.Start(FROM_HERE, 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) backoff, 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &OAuth2TokenService::Fetcher::Start); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_ = error; 297eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch InformWaitingRequestsAndDelete(); 298eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 300eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// Returns an exponential backoff in milliseconds including randomness less than 301eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch// 1000 ms when retrying fetching an OAuth2 access token. 302eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochint64 OAuth2TokenService::Fetcher::ComputeExponentialBackOffMilliseconds( 303eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int retry_num) { 304eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch DCHECK(retry_num < max_fetch_retry_num_); 305eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int64 exponential_backoff_in_seconds = 1 << retry_num; 306eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Returns a backoff with randomness < 1000ms 307eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return (exponential_backoff_in_seconds + base::RandDouble()) * 1000; 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool OAuth2TokenService::Fetcher::ShouldRetry( 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const GoogleServiceAuthError& error) { 3132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GoogleServiceAuthError::State error_state = error.state(); 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return error_state == GoogleServiceAuthError::CONNECTION_FAILED || 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_state == GoogleServiceAuthError::REQUEST_CANCELED || 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) error_state == GoogleServiceAuthError::SERVICE_UNAVAILABLE; 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::Fetcher::InformWaitingRequests() { 3202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::vector<base::WeakPtr<RequestImpl> >::const_iterator iter = 3212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_requests_.begin(); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (; iter != waiting_requests_.end(); ++iter) { 3232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<RequestImpl> waiting_request = *iter; 324868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (waiting_request.get()) 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_request->InformConsumer(error_, access_token_, expiration_date_); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_requests_.clear(); 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 330eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OAuth2TokenService::Fetcher::InformWaitingRequestsAndDelete() { 331eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Deregisters itself from the service to prevent more waiting requests to 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // be added when it calls back the waiting requests. 333eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch oauth2_token_service_->OnFetchComplete(this); 334eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch InformWaitingRequests(); 335eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 336eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 337eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::Fetcher::AddWaitingRequest( 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WeakPtr<OAuth2TokenService::RequestImpl> waiting_request) { 3402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_requests_.push_back(waiting_request); 3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 34358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)size_t OAuth2TokenService::Fetcher::GetWaitingRequestCount() const { 34458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return waiting_requests_.size(); 34558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 34658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void OAuth2TokenService::Fetcher::Cancel() { 348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetcher_.reset(); 349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) retry_timer_.Stop(); 350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) error_ = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED); 351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) InformWaitingRequestsAndDelete(); 352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet() 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const { 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scopes_; 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const std::string& OAuth2TokenService::Fetcher::GetClientId() const { 36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return client_id_; 36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 36368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const std::string& OAuth2TokenService::Fetcher::GetAccountId() const { 36468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return account_id_; 36568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Request::Request() { 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Request::~Request() { 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)OAuth2TokenService::Consumer::Consumer(const std::string& id) 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : id_(id) {} 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Consumer::~Consumer() { 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 379116680a4aac90f2aa7413d9095a592090648e557Ben MurdochOAuth2TokenService::OAuth2TokenService() : batch_change_depth_(0) { 3802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::~OAuth2TokenService() { 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Release all the pending fetchers. 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STLDeleteContainerPairSecondPointers( 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_fetchers_.begin(), pending_fetchers_.end()); 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::AddObserver(Observer* observer) { 3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch observer_list_.AddObserver(observer); 3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::RemoveObserver(Observer* observer) { 3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch observer_list_.RemoveObserver(observer); 3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OAuth2TokenService::AddDiagnosticsObserver(DiagnosticsObserver* observer) { 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) diagnostics_observer_list_.AddObserver(observer); 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OAuth2TokenService::RemoveDiagnosticsObserver( 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DiagnosticsObserver* observer) { 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) diagnostics_observer_list_.RemoveObserver(observer); 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 40568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<std::string> OAuth2TokenService::GetAccounts() { 40668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return std::vector<std::string>(); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( 41068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return StartRequestForClientWithContext( 41468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 415a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetRequestContext(), 416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) consumer); 420a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<OAuth2TokenService::Request> 423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)OAuth2TokenService::StartRequestForClient( 42468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, 426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_secret, 427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return StartRequestForClientWithContext( 43068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 431a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetRequestContext(), 432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_id, 433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_secret, 434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) consumer); 43658e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch} 43758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 43858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochscoped_ptr<OAuth2TokenService::Request> 43958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochOAuth2TokenService::StartRequestWithContext( 44068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 44158e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch net::URLRequestContextGetter* getter, 44258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch const ScopeSet& scopes, 44358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch Consumer* consumer) { 444a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return StartRequestForClientWithContext( 44568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 446a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) getter, 447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 450a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) consumer); 451a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 452a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<OAuth2TokenService::Request> 454a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)OAuth2TokenService::StartRequestForClientWithContext( 45568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 456a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) net::URLRequestContextGetter* getter, 457a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, 458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_secret, 459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const ScopeSet& scopes, 460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Consumer* consumer) { 461424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 463a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<RequestImpl> request(new RequestImpl(account_id, consumer)); 4645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnAccessTokenRequested(account_id, 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consumer->id(), 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scopes)); 4682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 46968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!RefreshTokenIsAvailable(account_id)) { 4705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GoogleServiceAuthError error(GoogleServiceAuthError::USER_NOT_SIGNED_UP); 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnFetchAccessTokenComplete( 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) account_id, consumer->id(), scopes, error, 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time())); 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 47790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 478868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &RequestImpl::InformConsumer, 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request->AsWeakPtr(), 4805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error, 4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string(), 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time())); 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return request.PassAs<Request>(); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 48668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RequestParameters request_parameters(client_id, 48768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 48868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes); 48968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (HasCacheEntry(request_parameters)) { 49068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) StartCacheLookupRequest(request.get(), request_parameters, consumer); 4913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FetchOAuth2Token(request.get(), 49368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 4943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) getter, 4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_id, 4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_secret, 4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scopes); 4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return request.PassAs<Request>(); 5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void OAuth2TokenService::FetchOAuth2Token(RequestImpl* request, 50368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::URLRequestContextGetter* getter, 5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& client_id, 5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& client_secret, 5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ScopeSet& scopes) { 50868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If there is already a pending fetcher for |scopes| and |account_id|, 509eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // simply register this |request| for those results rather than starting 510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // a new fetcher. 51168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RequestParameters request_parameters = RequestParameters(client_id, 51268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 51368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes); 51468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::map<RequestParameters, Fetcher*>::iterator iter = 51568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending_fetchers_.find(request_parameters); 5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter != pending_fetchers_.end()) { 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter->second->AddWaitingRequest(request->AsWeakPtr()); 5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 520eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 52168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending_fetchers_[request_parameters] = 522a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Fetcher::CreateAndStart(this, 52368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 524a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) getter, 525a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_id, 526a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_secret, 527a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 528868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->AsWeakPtr()); 529c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void OAuth2TokenService::StartCacheLookupRequest( 5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RequestImpl* request, 53368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const OAuth2TokenService::RequestParameters& request_parameters, 5343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 53568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CHECK(HasCacheEntry(request_parameters)); 53668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CacheEntry* cache_entry = GetCacheEntry(request_parameters); 5375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnFetchAccessTokenComplete( 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_parameters.account_id, 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consumer->id(), 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_parameters.scopes, 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GoogleServiceAuthError::AuthErrorNone(), 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cache_entry->expiration_date)); 54490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 545868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &RequestImpl::InformConsumer, 546c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request->AsWeakPtr(), 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GoogleServiceAuthError(GoogleServiceAuthError::NONE), 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache_entry->access_token, 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache_entry->expiration_date)); 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 55268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::InvalidateToken(const std::string& account_id, 55368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 55468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 55568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InvalidateOAuth2Token(account_id, 55668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 55768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes, 55868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) access_token); 55968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 56068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 56168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::InvalidateTokenForClient( 56268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 56368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& client_id, 56468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 56568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 56668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InvalidateOAuth2Token(account_id, client_id, scopes, access_token); 56768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 56868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 56968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::InvalidateOAuth2Token( 57068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 57168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& client_id, 57268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 57368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 574424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 57558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RemoveCacheEntry( 57668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RequestParameters(client_id, 57768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 57868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes), 57968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) access_token); 580c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { 583424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 5842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update the auth error state so auth errors are appropriately communicated 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to the user. 58768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UpdateAuthError(fetcher->GetAccountId(), fetcher->error()); 5882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // token and scope set. This is guaranteed as follows; here a Fetcher is said 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to be uncompleted if it has not finished calling back 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OAuth2TokenService::OnFetchComplete(). 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (1) All the live Fetchers are created by this service. 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is because (1) all the live Fetchers are created by a live 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // service, as all the fetchers created by a service are destructed in the 597c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // service's dtor. 5982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (2) All the uncompleted Fetchers created by this service are recorded in 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |pending_fetchers_|. 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is because (1) all the created Fetchers are added to 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |pending_fetchers_| (in method StartRequest()) and (2) method 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnFetchComplete() is the only place where a Fetcher is erased from 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |pending_fetchers_|. Note no Fetcher is erased in method 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StartRequest(). 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // refresh token and ScopeSet. This is guaranteed by Fetcher creation in 609c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // method StartRequest(). 6102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When this method is called, |fetcher| is alive and uncompleted. 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // By (1), |fetcher| is created by this service. 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then by (2), |fetcher| is recorded in |pending_fetchers_|. 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. 6155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RequestParameters request_param(fetcher->GetClientId(), 6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->GetAccountId(), 6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->GetScopeSet()); 6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const OAuth2TokenService::CacheEntry* entry = GetCacheEntry(request_param); 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<base::WeakPtr<RequestImpl> >& requests = 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->waiting_requests(); 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < requests.size(); ++i) { 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const RequestImpl* req = requests[i].get(); 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (req) { 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnFetchAccessTokenComplete( 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) req->GetAccountId(), req->GetConsumerId(), 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->GetScopeSet(), fetcher->error(), 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry ? entry->expiration_date : base::Time())); 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 63368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::map<RequestParameters, Fetcher*>::iterator iter = 6345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_fetchers_.find(request_param); 6352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(iter != pending_fetchers_.end()); 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(fetcher, iter->second); 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_fetchers_.erase(iter); 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 640c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OAuth2TokenService::HasCacheEntry( 64168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& request_parameters) { 64268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CacheEntry* cache_entry = GetCacheEntry(request_parameters); 643c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return cache_entry && cache_entry->access_token.length(); 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry( 64768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& request_parameters) { 648424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 64968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TokenCache::iterator token_iterator = token_cache_.find(request_parameters); 6502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (token_iterator == token_cache_.end()) 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (token_iterator->second.expiration_date <= base::Time::Now()) { 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token_cache_.erase(token_iterator); 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &token_iterator->second; 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 659c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OAuth2TokenService::RemoveCacheEntry( 66068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& request_parameters, 661c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& token_to_remove) { 662424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 66368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TokenCache::iterator token_iterator = token_cache_.find(request_parameters); 664868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (token_iterator != token_cache_.end() && 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_iterator->second.access_token == token_to_remove) { 6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnTokenRemoved(request_parameters.account_id, 6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_parameters.scopes)); 669c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_cache_.erase(token_iterator); 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::RegisterCacheEntry( 67658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 67768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& access_token, 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& expiration_date) { 681424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 6822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 68368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CacheEntry& token = token_cache_[RequestParameters(client_id, 68468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 68568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes)]; 6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token.access_token = access_token; 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token.expiration_date = expiration_date; 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 69068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::UpdateAuthError( 69168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 69268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const GoogleServiceAuthError& error) { 693c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Default implementation does nothing. 694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 6952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 696c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OAuth2TokenService::ClearCache() { 697424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 6985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (TokenCache::iterator iter = token_cache_.begin(); 6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter != token_cache_.end(); ++iter) { 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnTokenRemoved(iter->first.account_id, 7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->first.scopes)); 7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 705c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_cache_.clear(); 7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 70868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::ClearCacheForAccount(const std::string& account_id) { 70968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(CalledOnValidThread()); 71068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (TokenCache::iterator iter = token_cache_.begin(); 71168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) iter != token_cache_.end(); 71268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /* iter incremented in body */) { 71368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (iter->first.account_id == account_id) { 7145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnTokenRemoved(account_id, iter->first.scopes)); 71668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) token_cache_.erase(iter++); 71768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 71868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ++iter; 71968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 72068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 72168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 72268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 723a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void OAuth2TokenService::CancelAllRequests() { 724a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Fetcher*> fetchers_to_cancel; 72568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (std::map<RequestParameters, Fetcher*>::iterator iter = 726a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pending_fetchers_.begin(); 727a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != pending_fetchers_.end(); 728a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++iter) { 729a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetchers_to_cancel.push_back(iter->second); 730a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 731a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CancelFetchers(fetchers_to_cancel); 732a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 733a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 73468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::CancelRequestsForAccount( 73568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id) { 736a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Fetcher*> fetchers_to_cancel; 73768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (std::map<RequestParameters, Fetcher*>::iterator iter = 738a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pending_fetchers_.begin(); 739a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != pending_fetchers_.end(); 740a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++iter) { 74168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (iter->first.account_id == account_id) 742a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetchers_to_cancel.push_back(iter->second); 743a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CancelFetchers(fetchers_to_cancel); 745a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 746a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 747a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void OAuth2TokenService::CancelFetchers( 748a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Fetcher*> fetchers_to_cancel) { 749a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = 750a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetchers_to_cancel.begin(); 751a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != fetchers_to_cancel.end(); 752a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++iter) { 753a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) (*iter)->Cancel(); 754a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 755a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 756a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::FireRefreshTokenAvailable( 7587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& account_id) { 7597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, 7607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch OnRefreshTokenAvailable(account_id)); 7617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::FireRefreshTokenRevoked( 7643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& account_id) { 7657dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, 7663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OnRefreshTokenRevoked(account_id)); 7677dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::FireRefreshTokensLoaded() { 7707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, OnRefreshTokensLoaded()); 7717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 773116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid OAuth2TokenService::StartBatchChanges() { 774116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++batch_change_depth_; 775116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (batch_change_depth_ == 1) 776116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, OnStartBatchChanges()); 777116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 778116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 779116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid OAuth2TokenService::EndBatchChanges() { 780116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch --batch_change_depth_; 781116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_LE(0, batch_change_depth_); 782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (batch_change_depth_ == 0) 783116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, OnEndBatchChanges()); 784116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 785116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int OAuth2TokenService::cache_size_for_testing() const { 787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return token_cache_.size(); 7882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 789eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( 791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int max_retries) { 792424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 793eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch max_fetch_retry_num_ = max_retries; 794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 79558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 79658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)size_t OAuth2TokenService::GetNumPendingRequestsForTesting( 79758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 79868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 79958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet& scopes) const { 80058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PendingFetcherMap::const_iterator iter = pending_fetchers_.find( 80168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) OAuth2TokenService::RequestParameters( 80258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_id, 80368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 80458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scopes)); 80558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return iter == pending_fetchers_.end() ? 80658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0 : iter->second->GetWaitingRequestCount(); 80758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 808