oauth2_token_service.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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_); 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) waiting_requests_.push_back(waiting_request); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Fetcher::~Fetcher() { 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Inform the waiting requests if it has not done so. 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (waiting_requests_.size()) 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InformWaitingRequests(); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::Fetcher::Start() { 248a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) fetcher_.reset(oauth2_token_service_->CreateAccessTokenFetcher( 249a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) account_id_, getter_.get(), this)); 250a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) DCHECK(fetcher_); 25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) fetcher_->Start(client_id_, 25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_secret_, 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() { 3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (fetcher_) 3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci fetcher_->CancelRequest(); 349a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetcher_.reset(); 350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) retry_timer_.Stop(); 351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) error_ = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED); 352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) InformWaitingRequestsAndDelete(); 353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 3552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet() 3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const { 3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return scopes_; 3582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)const std::string& OAuth2TokenService::Fetcher::GetClientId() const { 36158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return client_id_; 36258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 36358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 36468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const std::string& OAuth2TokenService::Fetcher::GetAccountId() const { 36568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return account_id_; 36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 3682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Request::Request() { 3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Request::~Request() { 3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)OAuth2TokenService::Consumer::Consumer(const std::string& id) 3755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : id_(id) {} 3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::Consumer::~Consumer() { 3782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 380116680a4aac90f2aa7413d9095a592090648e557Ben MurdochOAuth2TokenService::OAuth2TokenService() : batch_change_depth_(0) { 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)OAuth2TokenService::~OAuth2TokenService() { 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Release all the pending fetchers. 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) STLDeleteContainerPairSecondPointers( 3862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_fetchers_.begin(), pending_fetchers_.end()); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::AddObserver(Observer* observer) { 3907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch observer_list_.AddObserver(observer); 3917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::RemoveObserver(Observer* observer) { 3947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch observer_list_.RemoveObserver(observer); 3957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 3967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 3975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OAuth2TokenService::AddDiagnosticsObserver(DiagnosticsObserver* observer) { 3985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) diagnostics_observer_list_.AddObserver(observer); 3995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OAuth2TokenService::RemoveDiagnosticsObserver( 4025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DiagnosticsObserver* observer) { 4035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) diagnostics_observer_list_.RemoveObserver(observer); 4045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 4055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 40668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)std::vector<std::string> OAuth2TokenService::GetAccounts() { 40768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) return std::vector<std::string>(); 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest( 41168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 414a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return StartRequestForClientWithContext( 41568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetRequestContext(), 417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 420a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) consumer); 421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<OAuth2TokenService::Request> 424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)OAuth2TokenService::StartRequestForClient( 42568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, 427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_secret, 428a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 429a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 430a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return StartRequestForClientWithContext( 43168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 432a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GetRequestContext(), 433a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_id, 434a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_secret, 435a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 436a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) consumer); 43758e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch} 43858e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch 43958e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdochscoped_ptr<OAuth2TokenService::Request> 44058e6fbe4ee35d65e14b626c557d37565bf8ad179Ben MurdochOAuth2TokenService::StartRequestWithContext( 44168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 44258e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch net::URLRequestContextGetter* getter, 44358e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch const ScopeSet& scopes, 44458e6fbe4ee35d65e14b626c557d37565bf8ad179Ben Murdoch Consumer* consumer) { 445a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) return StartRequestForClientWithContext( 44668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 447a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) getter, 448a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 449a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_secret(), 450a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 451a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) consumer); 452a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 453a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 454a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)scoped_ptr<OAuth2TokenService::Request> 455a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)OAuth2TokenService::StartRequestForClientWithContext( 45668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 457a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) net::URLRequestContextGetter* getter, 458a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_id, 459a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const std::string& client_secret, 460a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) const ScopeSet& scopes, 461a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Consumer* consumer) { 462424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 464a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) scoped_ptr<RequestImpl> request(new RequestImpl(account_id, consumer)); 4655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 4665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnAccessTokenRequested(account_id, 4675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consumer->id(), 4685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scopes)); 4692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 47068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (!RefreshTokenIsAvailable(account_id)) { 4715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GoogleServiceAuthError error(GoogleServiceAuthError::USER_NOT_SIGNED_UP); 4725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 4735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 4745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnFetchAccessTokenComplete( 4755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) account_id, consumer->id(), scopes, error, 4765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::Time())); 4775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 47890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 479868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &RequestImpl::InformConsumer, 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) request->AsWeakPtr(), 4815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) error, 4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string(), 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time())); 4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return request.PassAs<Request>(); 4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 48768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RequestParameters request_parameters(client_id, 48868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 48968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes); 49068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (HasCacheEntry(request_parameters)) { 49168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) StartCacheLookupRequest(request.get(), request_parameters, consumer); 4923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } else { 4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) FetchOAuth2Token(request.get(), 49468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) getter, 4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_id, 4973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) client_secret, 4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scopes); 4993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) } 5003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return request.PassAs<Request>(); 5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void OAuth2TokenService::FetchOAuth2Token(RequestImpl* request, 50468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 5053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net::URLRequestContextGetter* getter, 5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& client_id, 5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& client_secret, 5083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const ScopeSet& scopes) { 50968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) // If there is already a pending fetcher for |scopes| and |account_id|, 510eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // simply register this |request| for those results rather than starting 511eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // a new fetcher. 51268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RequestParameters request_parameters = RequestParameters(client_id, 51368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 51468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes); 51568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::map<RequestParameters, Fetcher*>::iterator iter = 51668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending_fetchers_.find(request_parameters); 5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (iter != pending_fetchers_.end()) { 5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) iter->second->AddWaitingRequest(request->AsWeakPtr()); 5193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return; 5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 521eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 52268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) pending_fetchers_[request_parameters] = 523a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) Fetcher::CreateAndStart(this, 52468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 525a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) getter, 526a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_id, 527a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) client_secret, 528a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) scopes, 529868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) request->AsWeakPtr()); 530c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 531c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void OAuth2TokenService::StartCacheLookupRequest( 5333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RequestImpl* request, 53468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const OAuth2TokenService::RequestParameters& request_parameters, 5353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 53668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CHECK(HasCacheEntry(request_parameters)); 53768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CacheEntry* cache_entry = GetCacheEntry(request_parameters); 5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 5395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnFetchAccessTokenComplete( 5405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_parameters.account_id, 5415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) consumer->id(), 5425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_parameters.scopes, 5435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) GoogleServiceAuthError::AuthErrorNone(), 5445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cache_entry->expiration_date)); 54590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind( 546868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) &RequestImpl::InformConsumer, 547c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) request->AsWeakPtr(), 548c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GoogleServiceAuthError(GoogleServiceAuthError::NONE), 549c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache_entry->access_token, 550c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cache_entry->expiration_date)); 5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 55368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::InvalidateToken(const std::string& account_id, 55468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 55568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 55668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InvalidateOAuth2Token(account_id, 55768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) GaiaUrls::GetInstance()->oauth2_chrome_client_id(), 55868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes, 55968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) access_token); 56068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 56168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 56268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::InvalidateTokenForClient( 56368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 56468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& client_id, 56568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 56668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 56768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) InvalidateOAuth2Token(account_id, client_id, scopes, access_token); 56868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 56968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 57068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::InvalidateOAuth2Token( 57168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 57268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& client_id, 57368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const ScopeSet& scopes, 57468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& access_token) { 575424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 57658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RemoveCacheEntry( 57768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) RequestParameters(client_id, 57868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 57968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes), 58068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) access_token); 581c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 582c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 5832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) { 584424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 5852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Update the auth error state so auth errors are appropriately communicated 5872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to the user. 58868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) UpdateAuthError(fetcher->GetAccountId(), fetcher->error()); 5892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 5902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh 5912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // token and scope set. This is guaranteed as follows; here a Fetcher is said 5922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // to be uncompleted if it has not finished calling back 5932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OAuth2TokenService::OnFetchComplete(). 5942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 5952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (1) All the live Fetchers are created by this service. 5962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is because (1) all the live Fetchers are created by a live 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // service, as all the fetchers created by a service are destructed in the 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // service's dtor. 5992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 6002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (2) All the uncompleted Fetchers created by this service are recorded in 6012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |pending_fetchers_|. 6022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This is because (1) all the created Fetchers are added to 6032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |pending_fetchers_| (in method StartRequest()) and (2) method 6042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // OnFetchComplete() is the only place where a Fetcher is erased from 6052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |pending_fetchers_|. Note no Fetcher is erased in method 6062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // StartRequest(). 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // refresh token and ScopeSet. This is guaranteed by Fetcher creation in 610c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // method StartRequest(). 6112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 6122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When this method is called, |fetcher| is alive and uncompleted. 6132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // By (1), |fetcher| is created by this service. 6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then by (2), |fetcher| is recorded in |pending_fetchers_|. 6152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet. 6165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) RequestParameters request_param(fetcher->GetClientId(), 6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->GetAccountId(), 6185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->GetScopeSet()); 6195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const OAuth2TokenService::CacheEntry* entry = GetCacheEntry(request_param); 6215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const std::vector<base::WeakPtr<RequestImpl> >& requests = 6225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->waiting_requests(); 6235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (size_t i = 0; i < requests.size(); ++i) { 6245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const RequestImpl* req = requests[i].get(); 6255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (req) { 6265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 6275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnFetchAccessTokenComplete( 6285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) req->GetAccountId(), req->GetConsumerId(), 6295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) fetcher->GetScopeSet(), fetcher->error(), 6305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) entry ? entry->expiration_date : base::Time())); 6315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 6335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 63468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) std::map<RequestParameters, Fetcher*>::iterator iter = 6355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) pending_fetchers_.find(request_param); 6362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(iter != pending_fetchers_.end()); 6372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(fetcher, iter->second); 6382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pending_fetchers_.erase(iter); 6392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 641c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OAuth2TokenService::HasCacheEntry( 64268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& request_parameters) { 64368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const CacheEntry* cache_entry = GetCacheEntry(request_parameters); 644c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return cache_entry && cache_entry->access_token.length(); 645c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 646c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry( 64868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& request_parameters) { 649424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 65068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TokenCache::iterator token_iterator = token_cache_.find(request_parameters); 6512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (token_iterator == token_cache_.end()) 6522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (token_iterator->second.expiration_date <= base::Time::Now()) { 6542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token_cache_.erase(token_iterator); 6552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return NULL; 6562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 6572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return &token_iterator->second; 6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 660c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool OAuth2TokenService::RemoveCacheEntry( 66168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const RequestParameters& request_parameters, 662c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& token_to_remove) { 663424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 66468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) TokenCache::iterator token_iterator = token_cache_.find(request_parameters); 665868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (token_iterator != token_cache_.end() && 666c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_iterator->second.access_token == token_to_remove) { 6675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 6685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnTokenRemoved(request_parameters.account_id, 6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) request_parameters.scopes)); 670c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_cache_.erase(token_iterator); 671c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 672c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 673c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 674c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 675c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 6762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void OAuth2TokenService::RegisterCacheEntry( 67758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 67868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& access_token, 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& expiration_date) { 682424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 68468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) CacheEntry& token = token_cache_[RequestParameters(client_id, 68568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 68668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) scopes)]; 6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token.access_token = access_token; 6882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) token.expiration_date = expiration_date; 6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 69168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::UpdateAuthError( 69268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 69368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const GoogleServiceAuthError& error) { 694c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Default implementation does nothing. 695c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 6962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 697c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void OAuth2TokenService::ClearCache() { 698424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (TokenCache::iterator iter = token_cache_.begin(); 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter != token_cache_.end(); ++iter) { 7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 7025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnTokenRemoved(iter->first.account_id, 7035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) iter->first.scopes)); 7045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 706c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) token_cache_.clear(); 7072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 70968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::ClearCacheForAccount(const std::string& account_id) { 71068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) DCHECK(CalledOnValidThread()); 71168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (TokenCache::iterator iter = token_cache_.begin(); 71268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) iter != token_cache_.end(); 71368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) /* iter incremented in body */) { 71468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (iter->first.account_id == account_id) { 7155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_, 7165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) OnTokenRemoved(account_id, iter->first.scopes)); 71768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) token_cache_.erase(iter++); 71868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } else { 71968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) ++iter; 72068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 72168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) } 72268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)} 72368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) 724a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void OAuth2TokenService::CancelAllRequests() { 725a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Fetcher*> fetchers_to_cancel; 72668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (std::map<RequestParameters, Fetcher*>::iterator iter = 727a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pending_fetchers_.begin(); 728a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != pending_fetchers_.end(); 729a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++iter) { 730a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetchers_to_cancel.push_back(iter->second); 731a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 732a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CancelFetchers(fetchers_to_cancel); 733a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 734a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 73568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void OAuth2TokenService::CancelRequestsForAccount( 73668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id) { 737a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Fetcher*> fetchers_to_cancel; 73868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) for (std::map<RequestParameters, Fetcher*>::iterator iter = 739a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) pending_fetchers_.begin(); 740a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != pending_fetchers_.end(); 741a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++iter) { 74268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) if (iter->first.account_id == account_id) 743a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetchers_to_cancel.push_back(iter->second); 744a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 745a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) CancelFetchers(fetchers_to_cancel); 746a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 747a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 748a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void OAuth2TokenService::CancelFetchers( 749a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) std::vector<Fetcher*> fetchers_to_cancel) { 750a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter = 751a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) fetchers_to_cancel.begin(); 752a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) iter != fetchers_to_cancel.end(); 753a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) ++iter) { 754a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) (*iter)->Cancel(); 755a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) } 756a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)} 757a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) 7587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::FireRefreshTokenAvailable( 7597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch const std::string& account_id) { 7607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, 7617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch OnRefreshTokenAvailable(account_id)); 7627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7637dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7647dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::FireRefreshTokenRevoked( 7653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) const std::string& account_id) { 7667dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, 7673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) OnRefreshTokenRevoked(account_id)); 7687dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 7707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochvoid OAuth2TokenService::FireRefreshTokensLoaded() { 7717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, OnRefreshTokensLoaded()); 7727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch} 7737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 774116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid OAuth2TokenService::StartBatchChanges() { 775116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch ++batch_change_depth_; 776116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (batch_change_depth_ == 1) 777116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, OnStartBatchChanges()); 778116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 779116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 780116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid OAuth2TokenService::EndBatchChanges() { 781116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch --batch_change_depth_; 782116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch DCHECK_LE(0, batch_change_depth_); 783116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (batch_change_depth_ == 0) 784116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch FOR_EACH_OBSERVER(Observer, observer_list_, OnEndBatchChanges()); 785116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 786116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 787c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)int OAuth2TokenService::cache_size_for_testing() const { 788c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return token_cache_.size(); 7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 790eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 791eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing( 792eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch int max_retries) { 793424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(CalledOnValidThread()); 794eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch max_fetch_retry_num_ = max_retries; 795eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch} 79658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 79758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)size_t OAuth2TokenService::GetNumPendingRequestsForTesting( 79858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const std::string& client_id, 79968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) const std::string& account_id, 80058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const ScopeSet& scopes) const { 80158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) PendingFetcherMap::const_iterator iter = pending_fetchers_.find( 80268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) OAuth2TokenService::RequestParameters( 80358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) client_id, 80468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles) account_id, 80558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) scopes)); 80658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) return iter == pending_fetchers_.end() ? 80758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 0 : iter->second->GetWaitingRequestCount(); 80858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 809