Home | History | Annotate | Download | only in gaia
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "google_apis/gaia/oauth2_token_service.h"
      6 
      7 #include <vector>
      8 
      9 #include "base/bind.h"
     10 #include "base/memory/weak_ptr.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/rand_util.h"
     13 #include "base/stl_util.h"
     14 #include "base/time/time.h"
     15 #include "base/timer/timer.h"
     16 #include "google_apis/gaia/gaia_urls.h"
     17 #include "google_apis/gaia/google_service_auth_error.h"
     18 #include "google_apis/gaia/oauth2_access_token_fetcher_impl.h"
     19 #include "net/url_request/url_request_context_getter.h"
     20 
     21 int OAuth2TokenService::max_fetch_retry_num_ = 5;
     22 
     23 OAuth2TokenService::RequestParameters::RequestParameters(
     24     const std::string& client_id,
     25     const std::string& account_id,
     26     const ScopeSet& scopes)
     27     : client_id(client_id),
     28       account_id(account_id),
     29       scopes(scopes) {
     30 }
     31 
     32 OAuth2TokenService::RequestParameters::~RequestParameters() {
     33 }
     34 
     35 bool OAuth2TokenService::RequestParameters::operator<(
     36     const RequestParameters& p) const {
     37   if (client_id < p.client_id)
     38     return true;
     39   else if (p.client_id < client_id)
     40     return false;
     41 
     42   if (account_id < p.account_id)
     43     return true;
     44   else if (p.account_id < account_id)
     45     return false;
     46 
     47   return scopes < p.scopes;
     48 }
     49 
     50 OAuth2TokenService::RequestImpl::RequestImpl(
     51     const std::string& account_id,
     52     OAuth2TokenService::Consumer* consumer)
     53     : account_id_(account_id),
     54       consumer_(consumer) {
     55 }
     56 
     57 OAuth2TokenService::RequestImpl::~RequestImpl() {
     58   DCHECK(CalledOnValidThread());
     59 }
     60 
     61 std::string OAuth2TokenService::RequestImpl::GetAccountId() const {
     62   return account_id_;
     63 }
     64 
     65 std::string OAuth2TokenService::RequestImpl::GetConsumerId() const {
     66   return consumer_->id();
     67 }
     68 
     69 void OAuth2TokenService::RequestImpl::InformConsumer(
     70     const GoogleServiceAuthError& error,
     71     const std::string& access_token,
     72     const base::Time& expiration_date) {
     73   DCHECK(CalledOnValidThread());
     74   if (error.state() == GoogleServiceAuthError::NONE)
     75     consumer_->OnGetTokenSuccess(this, access_token, expiration_date);
     76   else
     77     consumer_->OnGetTokenFailure(this, error);
     78 }
     79 
     80 // Class that fetches an OAuth2 access token for a given account id and set of
     81 // scopes.
     82 //
     83 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry
     84 // mechanism is used to handle failures.
     85 //
     86 // To use this class, call CreateAndStart() to create and start a Fetcher.
     87 //
     88 // The Fetcher will call back the service by calling
     89 // OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is
     90 // not destructed before it completes fetching; if the Fetcher is destructed
     91 // before it completes fetching, the service will never be called back. The
     92 // Fetcher destructs itself after calling back the service when finishes
     93 // fetching.
     94 //
     95 // Requests that are waiting for the fetching results of this Fetcher can be
     96 // added to the Fetcher by calling
     97 // OAuth2TokenService::Fetcher::AddWaitingRequest() before the Fetcher
     98 // completes fetching.
     99 //
    100 // The waiting requests are taken as weak pointers and they can be deleted.
    101 // The waiting requests will be called back with fetching results if they are
    102 // not deleted
    103 // - when the Fetcher completes fetching, if the Fetcher is not destructed
    104 //   before it completes fetching, or
    105 // - when the Fetcher is destructed if the Fetcher is destructed before it
    106 //   completes fetching (in this case, the waiting requests will be called
    107 //   back with error).
    108 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer {
    109  public:
    110   // Creates a Fetcher and starts fetching an OAuth2 access token for
    111   // |account_id| and |scopes| in the request context obtained by |getter|.
    112   // The given |oauth2_token_service| will be informed when fetching is done.
    113   static Fetcher* CreateAndStart(OAuth2TokenService* oauth2_token_service,
    114                                  const std::string& account_id,
    115                                  net::URLRequestContextGetter* getter,
    116                                  const std::string& client_id,
    117                                  const std::string& client_secret,
    118                                  const ScopeSet& scopes,
    119                                  base::WeakPtr<RequestImpl> waiting_request);
    120   virtual ~Fetcher();
    121 
    122   // Add a request that is waiting for the result of this Fetcher.
    123   void AddWaitingRequest(base::WeakPtr<RequestImpl> waiting_request);
    124 
    125   // Returns count of waiting requests.
    126   size_t GetWaitingRequestCount() const;
    127 
    128   const std::vector<base::WeakPtr<RequestImpl> >& waiting_requests() const {
    129     return waiting_requests_;
    130   }
    131 
    132   void Cancel();
    133 
    134   const ScopeSet& GetScopeSet() const;
    135   const std::string& GetClientId() const;
    136   const std::string& GetAccountId() const;
    137 
    138   // The error result from this fetcher.
    139   const GoogleServiceAuthError& error() const { return error_; }
    140 
    141  protected:
    142    // OAuth2AccessTokenConsumer
    143   virtual void OnGetTokenSuccess(const std::string& access_token,
    144                                  const base::Time& expiration_date) OVERRIDE;
    145   virtual void OnGetTokenFailure(
    146       const GoogleServiceAuthError& error) OVERRIDE;
    147 
    148  private:
    149   Fetcher(OAuth2TokenService* oauth2_token_service,
    150           const std::string& account_id,
    151           net::URLRequestContextGetter* getter,
    152           const std::string& client_id,
    153           const std::string& client_secret,
    154           const OAuth2TokenService::ScopeSet& scopes,
    155           base::WeakPtr<RequestImpl> waiting_request);
    156   void Start();
    157   void InformWaitingRequests();
    158   void InformWaitingRequestsAndDelete();
    159   static bool ShouldRetry(const GoogleServiceAuthError& error);
    160   int64 ComputeExponentialBackOffMilliseconds(int retry_num);
    161 
    162   // |oauth2_token_service_| remains valid for the life of this Fetcher, since
    163   // this Fetcher is destructed in the dtor of the OAuth2TokenService or is
    164   // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess
    165   // (whichever comes first).
    166   OAuth2TokenService* const oauth2_token_service_;
    167   scoped_refptr<net::URLRequestContextGetter> getter_;
    168   const std::string account_id_;
    169   const ScopeSet scopes_;
    170   std::vector<base::WeakPtr<RequestImpl> > waiting_requests_;
    171 
    172   int retry_number_;
    173   base::OneShotTimer<Fetcher> retry_timer_;
    174   scoped_ptr<OAuth2AccessTokenFetcher> fetcher_;
    175 
    176   // Variables that store fetch results.
    177   // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle
    178   // destruction.
    179   GoogleServiceAuthError error_;
    180   std::string access_token_;
    181   base::Time expiration_date_;
    182 
    183   // OAuth2 client id and secret.
    184   std::string client_id_;
    185   std::string client_secret_;
    186 
    187   DISALLOW_COPY_AND_ASSIGN(Fetcher);
    188 };
    189 
    190 // static
    191 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart(
    192     OAuth2TokenService* oauth2_token_service,
    193     const std::string& account_id,
    194     net::URLRequestContextGetter* getter,
    195     const std::string& client_id,
    196     const std::string& client_secret,
    197     const OAuth2TokenService::ScopeSet& scopes,
    198     base::WeakPtr<RequestImpl> waiting_request) {
    199   OAuth2TokenService::Fetcher* fetcher = new Fetcher(
    200       oauth2_token_service,
    201       account_id,
    202       getter,
    203       client_id,
    204       client_secret,
    205       scopes,
    206       waiting_request);
    207   fetcher->Start();
    208   return fetcher;
    209 }
    210 
    211 OAuth2TokenService::Fetcher::Fetcher(
    212     OAuth2TokenService* oauth2_token_service,
    213     const std::string& account_id,
    214     net::URLRequestContextGetter* getter,
    215     const std::string& client_id,
    216     const std::string& client_secret,
    217     const OAuth2TokenService::ScopeSet& scopes,
    218     base::WeakPtr<RequestImpl> waiting_request)
    219     : oauth2_token_service_(oauth2_token_service),
    220       getter_(getter),
    221       account_id_(account_id),
    222       scopes_(scopes),
    223       retry_number_(0),
    224       error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE),
    225       client_id_(client_id),
    226       client_secret_(client_secret) {
    227   DCHECK(oauth2_token_service_);
    228   DCHECK(getter_.get());
    229   waiting_requests_.push_back(waiting_request);
    230 }
    231 
    232 OAuth2TokenService::Fetcher::~Fetcher() {
    233   // Inform the waiting requests if it has not done so.
    234   if (waiting_requests_.size())
    235     InformWaitingRequests();
    236 }
    237 
    238 void OAuth2TokenService::Fetcher::Start() {
    239   fetcher_.reset(oauth2_token_service_->CreateAccessTokenFetcher(
    240       account_id_, getter_.get(), this));
    241   DCHECK(fetcher_);
    242   fetcher_->Start(client_id_,
    243                   client_secret_,
    244                   std::vector<std::string>(scopes_.begin(), scopes_.end()));
    245   retry_timer_.Stop();
    246 }
    247 
    248 void OAuth2TokenService::Fetcher::OnGetTokenSuccess(
    249     const std::string& access_token,
    250     const base::Time& expiration_date) {
    251   fetcher_.reset();
    252 
    253   // Fetch completes.
    254   error_ = GoogleServiceAuthError::AuthErrorNone();
    255   access_token_ = access_token;
    256   expiration_date_ = expiration_date;
    257 
    258   // Subclasses may override this method to skip caching in some cases, but
    259   // we still inform all waiting Consumers of a successful token fetch below.
    260   // This is intentional -- some consumers may need the token for cleanup
    261   // tasks. https://chromiumcodereview.appspot.com/11312124/
    262   oauth2_token_service_->RegisterCacheEntry(client_id_,
    263                                             account_id_,
    264                                             scopes_,
    265                                             access_token_,
    266                                             expiration_date_);
    267   InformWaitingRequestsAndDelete();
    268 }
    269 
    270 void OAuth2TokenService::Fetcher::OnGetTokenFailure(
    271     const GoogleServiceAuthError& error) {
    272   fetcher_.reset();
    273 
    274   if (ShouldRetry(error) && retry_number_ < max_fetch_retry_num_) {
    275     base::TimeDelta backoff = base::TimeDelta::FromMilliseconds(
    276         ComputeExponentialBackOffMilliseconds(retry_number_));
    277     ++retry_number_;
    278     retry_timer_.Stop();
    279     retry_timer_.Start(FROM_HERE,
    280                        backoff,
    281                        this,
    282                        &OAuth2TokenService::Fetcher::Start);
    283     return;
    284   }
    285 
    286   error_ = error;
    287   InformWaitingRequestsAndDelete();
    288 }
    289 
    290 // Returns an exponential backoff in milliseconds including randomness less than
    291 // 1000 ms when retrying fetching an OAuth2 access token.
    292 int64 OAuth2TokenService::Fetcher::ComputeExponentialBackOffMilliseconds(
    293     int retry_num) {
    294   DCHECK(retry_num < max_fetch_retry_num_);
    295   int64 exponential_backoff_in_seconds = 1 << retry_num;
    296   // Returns a backoff with randomness < 1000ms
    297   return (exponential_backoff_in_seconds + base::RandDouble()) * 1000;
    298 }
    299 
    300 // static
    301 bool OAuth2TokenService::Fetcher::ShouldRetry(
    302     const GoogleServiceAuthError& error) {
    303   GoogleServiceAuthError::State error_state = error.state();
    304   return error_state == GoogleServiceAuthError::CONNECTION_FAILED ||
    305          error_state == GoogleServiceAuthError::REQUEST_CANCELED ||
    306          error_state == GoogleServiceAuthError::SERVICE_UNAVAILABLE;
    307 }
    308 
    309 void OAuth2TokenService::Fetcher::InformWaitingRequests() {
    310   std::vector<base::WeakPtr<RequestImpl> >::const_iterator iter =
    311       waiting_requests_.begin();
    312   for (; iter != waiting_requests_.end(); ++iter) {
    313     base::WeakPtr<RequestImpl> waiting_request = *iter;
    314     if (waiting_request.get())
    315       waiting_request->InformConsumer(error_, access_token_, expiration_date_);
    316   }
    317   waiting_requests_.clear();
    318 }
    319 
    320 void OAuth2TokenService::Fetcher::InformWaitingRequestsAndDelete() {
    321   // Deregisters itself from the service to prevent more waiting requests to
    322   // be added when it calls back the waiting requests.
    323   oauth2_token_service_->OnFetchComplete(this);
    324   InformWaitingRequests();
    325   base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
    326 }
    327 
    328 void OAuth2TokenService::Fetcher::AddWaitingRequest(
    329     base::WeakPtr<OAuth2TokenService::RequestImpl> waiting_request) {
    330   waiting_requests_.push_back(waiting_request);
    331 }
    332 
    333 size_t OAuth2TokenService::Fetcher::GetWaitingRequestCount() const {
    334   return waiting_requests_.size();
    335 }
    336 
    337 void OAuth2TokenService::Fetcher::Cancel() {
    338   fetcher_.reset();
    339   retry_timer_.Stop();
    340   error_ = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
    341   InformWaitingRequestsAndDelete();
    342 }
    343 
    344 const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet()
    345     const {
    346   return scopes_;
    347 }
    348 
    349 const std::string& OAuth2TokenService::Fetcher::GetClientId() const {
    350   return client_id_;
    351 }
    352 
    353 const std::string& OAuth2TokenService::Fetcher::GetAccountId() const {
    354   return account_id_;
    355 }
    356 
    357 OAuth2TokenService::Request::Request() {
    358 }
    359 
    360 OAuth2TokenService::Request::~Request() {
    361 }
    362 
    363 OAuth2TokenService::Consumer::Consumer(const std::string& id)
    364     : id_(id) {}
    365 
    366 OAuth2TokenService::Consumer::~Consumer() {
    367 }
    368 
    369 OAuth2TokenService::OAuth2TokenService() {
    370 }
    371 
    372 OAuth2TokenService::~OAuth2TokenService() {
    373   // Release all the pending fetchers.
    374   STLDeleteContainerPairSecondPointers(
    375       pending_fetchers_.begin(), pending_fetchers_.end());
    376 }
    377 
    378 void OAuth2TokenService::AddObserver(Observer* observer) {
    379   observer_list_.AddObserver(observer);
    380 }
    381 
    382 void OAuth2TokenService::RemoveObserver(Observer* observer) {
    383   observer_list_.RemoveObserver(observer);
    384 }
    385 
    386 void OAuth2TokenService::AddDiagnosticsObserver(DiagnosticsObserver* observer) {
    387   diagnostics_observer_list_.AddObserver(observer);
    388 }
    389 
    390 void OAuth2TokenService::RemoveDiagnosticsObserver(
    391     DiagnosticsObserver* observer) {
    392   diagnostics_observer_list_.RemoveObserver(observer);
    393 }
    394 
    395 std::vector<std::string> OAuth2TokenService::GetAccounts() {
    396   return std::vector<std::string>();
    397 }
    398 
    399 scoped_ptr<OAuth2TokenService::Request> OAuth2TokenService::StartRequest(
    400     const std::string& account_id,
    401     const OAuth2TokenService::ScopeSet& scopes,
    402     OAuth2TokenService::Consumer* consumer) {
    403   return StartRequestForClientWithContext(
    404       account_id,
    405       GetRequestContext(),
    406       GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
    407       GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
    408       scopes,
    409       consumer);
    410 }
    411 
    412 scoped_ptr<OAuth2TokenService::Request>
    413 OAuth2TokenService::StartRequestForClient(
    414     const std::string& account_id,
    415     const std::string& client_id,
    416     const std::string& client_secret,
    417     const OAuth2TokenService::ScopeSet& scopes,
    418     OAuth2TokenService::Consumer* consumer) {
    419   return StartRequestForClientWithContext(
    420       account_id,
    421       GetRequestContext(),
    422       client_id,
    423       client_secret,
    424       scopes,
    425       consumer);
    426 }
    427 
    428 scoped_ptr<OAuth2TokenService::Request>
    429 OAuth2TokenService::StartRequestWithContext(
    430     const std::string& account_id,
    431     net::URLRequestContextGetter* getter,
    432     const ScopeSet& scopes,
    433     Consumer* consumer) {
    434   return StartRequestForClientWithContext(
    435       account_id,
    436       getter,
    437       GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
    438       GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
    439       scopes,
    440       consumer);
    441 }
    442 
    443 scoped_ptr<OAuth2TokenService::Request>
    444 OAuth2TokenService::StartRequestForClientWithContext(
    445     const std::string& account_id,
    446     net::URLRequestContextGetter* getter,
    447     const std::string& client_id,
    448     const std::string& client_secret,
    449     const ScopeSet& scopes,
    450     Consumer* consumer) {
    451   DCHECK(CalledOnValidThread());
    452 
    453   scoped_ptr<RequestImpl> request(new RequestImpl(account_id, consumer));
    454   FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_,
    455                     OnAccessTokenRequested(account_id,
    456                                            consumer->id(),
    457                                            scopes));
    458 
    459   if (!RefreshTokenIsAvailable(account_id)) {
    460     GoogleServiceAuthError error(GoogleServiceAuthError::USER_NOT_SIGNED_UP);
    461 
    462     FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_,
    463                       OnFetchAccessTokenComplete(
    464                           account_id, consumer->id(), scopes, error,
    465                           base::Time()));
    466 
    467     base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
    468         &RequestImpl::InformConsumer,
    469         request->AsWeakPtr(),
    470         error,
    471         std::string(),
    472         base::Time()));
    473     return request.PassAs<Request>();
    474   }
    475 
    476   RequestParameters request_parameters(client_id,
    477                                        account_id,
    478                                        scopes);
    479   if (HasCacheEntry(request_parameters)) {
    480     StartCacheLookupRequest(request.get(), request_parameters, consumer);
    481   } else {
    482     FetchOAuth2Token(request.get(),
    483                      account_id,
    484                      getter,
    485                      client_id,
    486                      client_secret,
    487                      scopes);
    488   }
    489   return request.PassAs<Request>();
    490 }
    491 
    492 void OAuth2TokenService::FetchOAuth2Token(RequestImpl* request,
    493                                           const std::string& account_id,
    494                                           net::URLRequestContextGetter* getter,
    495                                           const std::string& client_id,
    496                                           const std::string& client_secret,
    497                                           const ScopeSet& scopes) {
    498   // If there is already a pending fetcher for |scopes| and |account_id|,
    499   // simply register this |request| for those results rather than starting
    500   // a new fetcher.
    501   RequestParameters request_parameters = RequestParameters(client_id,
    502                                                            account_id,
    503                                                            scopes);
    504   std::map<RequestParameters, Fetcher*>::iterator iter =
    505       pending_fetchers_.find(request_parameters);
    506   if (iter != pending_fetchers_.end()) {
    507     iter->second->AddWaitingRequest(request->AsWeakPtr());
    508     return;
    509   }
    510 
    511   pending_fetchers_[request_parameters] =
    512       Fetcher::CreateAndStart(this,
    513                               account_id,
    514                               getter,
    515                               client_id,
    516                               client_secret,
    517                               scopes,
    518                               request->AsWeakPtr());
    519 }
    520 
    521 void OAuth2TokenService::StartCacheLookupRequest(
    522     RequestImpl* request,
    523     const OAuth2TokenService::RequestParameters& request_parameters,
    524     OAuth2TokenService::Consumer* consumer) {
    525   CHECK(HasCacheEntry(request_parameters));
    526   const CacheEntry* cache_entry = GetCacheEntry(request_parameters);
    527   FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_,
    528                     OnFetchAccessTokenComplete(
    529                         request_parameters.account_id,
    530                         consumer->id(),
    531                         request_parameters.scopes,
    532                         GoogleServiceAuthError::AuthErrorNone(),
    533                         cache_entry->expiration_date));
    534   base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
    535       &RequestImpl::InformConsumer,
    536       request->AsWeakPtr(),
    537       GoogleServiceAuthError(GoogleServiceAuthError::NONE),
    538       cache_entry->access_token,
    539       cache_entry->expiration_date));
    540 }
    541 
    542 void OAuth2TokenService::InvalidateToken(const std::string& account_id,
    543                                          const ScopeSet& scopes,
    544                                          const std::string& access_token) {
    545   InvalidateOAuth2Token(account_id,
    546                         GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
    547                         scopes,
    548                         access_token);
    549 }
    550 
    551 void OAuth2TokenService::InvalidateTokenForClient(
    552     const std::string& account_id,
    553     const std::string& client_id,
    554     const ScopeSet& scopes,
    555     const std::string& access_token) {
    556   InvalidateOAuth2Token(account_id, client_id, scopes, access_token);
    557 }
    558 
    559 void OAuth2TokenService::InvalidateOAuth2Token(
    560     const std::string& account_id,
    561     const std::string& client_id,
    562     const ScopeSet& scopes,
    563     const std::string& access_token) {
    564   DCHECK(CalledOnValidThread());
    565   RemoveCacheEntry(
    566       RequestParameters(client_id,
    567                         account_id,
    568                         scopes),
    569       access_token);
    570 }
    571 
    572 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) {
    573   DCHECK(CalledOnValidThread());
    574 
    575   // Update the auth error state so auth errors are appropriately communicated
    576   // to the user.
    577   UpdateAuthError(fetcher->GetAccountId(), fetcher->error());
    578 
    579   // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh
    580   // token and scope set. This is guaranteed as follows; here a Fetcher is said
    581   // to be uncompleted if it has not finished calling back
    582   // OAuth2TokenService::OnFetchComplete().
    583   //
    584   // (1) All the live Fetchers are created by this service.
    585   //     This is because (1) all the live Fetchers are created by a live
    586   //     service, as all the fetchers created by a service are destructed in the
    587   //     service's dtor.
    588   //
    589   // (2) All the uncompleted Fetchers created by this service are recorded in
    590   //     |pending_fetchers_|.
    591   //     This is because (1) all the created Fetchers are added to
    592   //     |pending_fetchers_| (in method StartRequest()) and (2) method
    593   //     OnFetchComplete() is the only place where a Fetcher is erased from
    594   //     |pending_fetchers_|. Note no Fetcher is erased in method
    595   //     StartRequest().
    596   //
    597   // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its
    598   //     refresh token and ScopeSet. This is guaranteed by Fetcher creation in
    599   //     method StartRequest().
    600   //
    601   // When this method is called, |fetcher| is alive and uncompleted.
    602   // By (1), |fetcher| is created by this service.
    603   // Then by (2), |fetcher| is recorded in |pending_fetchers_|.
    604   // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet.
    605   RequestParameters request_param(fetcher->GetClientId(),
    606                                   fetcher->GetAccountId(),
    607                                   fetcher->GetScopeSet());
    608 
    609   const OAuth2TokenService::CacheEntry* entry = GetCacheEntry(request_param);
    610   const std::vector<base::WeakPtr<RequestImpl> >& requests =
    611       fetcher->waiting_requests();
    612   for (size_t i = 0; i < requests.size(); ++i) {
    613     const RequestImpl* req = requests[i].get();
    614     if (req) {
    615       FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_,
    616                         OnFetchAccessTokenComplete(
    617                             req->GetAccountId(), req->GetConsumerId(),
    618                             fetcher->GetScopeSet(), fetcher->error(),
    619                             entry ? entry->expiration_date : base::Time()));
    620     }
    621   }
    622 
    623   std::map<RequestParameters, Fetcher*>::iterator iter =
    624     pending_fetchers_.find(request_param);
    625   DCHECK(iter != pending_fetchers_.end());
    626   DCHECK_EQ(fetcher, iter->second);
    627   pending_fetchers_.erase(iter);
    628 }
    629 
    630 bool OAuth2TokenService::HasCacheEntry(
    631     const RequestParameters& request_parameters) {
    632   const CacheEntry* cache_entry = GetCacheEntry(request_parameters);
    633   return cache_entry && cache_entry->access_token.length();
    634 }
    635 
    636 const OAuth2TokenService::CacheEntry* OAuth2TokenService::GetCacheEntry(
    637     const RequestParameters& request_parameters) {
    638   DCHECK(CalledOnValidThread());
    639   TokenCache::iterator token_iterator = token_cache_.find(request_parameters);
    640   if (token_iterator == token_cache_.end())
    641     return NULL;
    642   if (token_iterator->second.expiration_date <= base::Time::Now()) {
    643     token_cache_.erase(token_iterator);
    644     return NULL;
    645   }
    646   return &token_iterator->second;
    647 }
    648 
    649 bool OAuth2TokenService::RemoveCacheEntry(
    650     const RequestParameters& request_parameters,
    651     const std::string& token_to_remove) {
    652   DCHECK(CalledOnValidThread());
    653   TokenCache::iterator token_iterator = token_cache_.find(request_parameters);
    654   if (token_iterator != token_cache_.end() &&
    655       token_iterator->second.access_token == token_to_remove) {
    656     FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_,
    657                       OnTokenRemoved(request_parameters.account_id,
    658                                      request_parameters.scopes));
    659     token_cache_.erase(token_iterator);
    660     return true;
    661   }
    662   return false;
    663 }
    664 
    665 void OAuth2TokenService::RegisterCacheEntry(
    666     const std::string& client_id,
    667     const std::string& account_id,
    668     const OAuth2TokenService::ScopeSet& scopes,
    669     const std::string& access_token,
    670     const base::Time& expiration_date) {
    671   DCHECK(CalledOnValidThread());
    672 
    673   CacheEntry& token = token_cache_[RequestParameters(client_id,
    674                                                      account_id,
    675                                                      scopes)];
    676   token.access_token = access_token;
    677   token.expiration_date = expiration_date;
    678 }
    679 
    680 void OAuth2TokenService::UpdateAuthError(
    681     const std::string& account_id,
    682     const GoogleServiceAuthError& error) {
    683   // Default implementation does nothing.
    684 }
    685 
    686 void OAuth2TokenService::ClearCache() {
    687   DCHECK(CalledOnValidThread());
    688   for (TokenCache::iterator iter = token_cache_.begin();
    689        iter != token_cache_.end(); ++iter) {
    690     FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_,
    691                       OnTokenRemoved(iter->first.account_id,
    692                                      iter->first.scopes));
    693   }
    694 
    695   token_cache_.clear();
    696 }
    697 
    698 void OAuth2TokenService::ClearCacheForAccount(const std::string& account_id) {
    699   DCHECK(CalledOnValidThread());
    700   for (TokenCache::iterator iter = token_cache_.begin();
    701        iter != token_cache_.end();
    702        /* iter incremented in body */) {
    703     if (iter->first.account_id == account_id) {
    704       FOR_EACH_OBSERVER(DiagnosticsObserver, diagnostics_observer_list_,
    705                         OnTokenRemoved(account_id, iter->first.scopes));
    706       token_cache_.erase(iter++);
    707     } else {
    708       ++iter;
    709     }
    710   }
    711 }
    712 
    713 void OAuth2TokenService::CancelAllRequests() {
    714   std::vector<Fetcher*> fetchers_to_cancel;
    715   for (std::map<RequestParameters, Fetcher*>::iterator iter =
    716            pending_fetchers_.begin();
    717        iter != pending_fetchers_.end();
    718        ++iter) {
    719     fetchers_to_cancel.push_back(iter->second);
    720   }
    721   CancelFetchers(fetchers_to_cancel);
    722 }
    723 
    724 void OAuth2TokenService::CancelRequestsForAccount(
    725     const std::string& account_id) {
    726   std::vector<Fetcher*> fetchers_to_cancel;
    727   for (std::map<RequestParameters, Fetcher*>::iterator iter =
    728            pending_fetchers_.begin();
    729        iter != pending_fetchers_.end();
    730        ++iter) {
    731     if (iter->first.account_id == account_id)
    732       fetchers_to_cancel.push_back(iter->second);
    733   }
    734   CancelFetchers(fetchers_to_cancel);
    735 }
    736 
    737 void OAuth2TokenService::CancelFetchers(
    738     std::vector<Fetcher*> fetchers_to_cancel) {
    739   for (std::vector<OAuth2TokenService::Fetcher*>::iterator iter =
    740            fetchers_to_cancel.begin();
    741        iter != fetchers_to_cancel.end();
    742        ++iter) {
    743     (*iter)->Cancel();
    744   }
    745 }
    746 
    747 void OAuth2TokenService::FireRefreshTokenAvailable(
    748     const std::string& account_id) {
    749   FOR_EACH_OBSERVER(Observer, observer_list_,
    750                     OnRefreshTokenAvailable(account_id));
    751 }
    752 
    753 void OAuth2TokenService::FireRefreshTokenRevoked(
    754     const std::string& account_id) {
    755   FOR_EACH_OBSERVER(Observer, observer_list_,
    756                     OnRefreshTokenRevoked(account_id));
    757 }
    758 
    759 void OAuth2TokenService::FireRefreshTokensLoaded() {
    760   FOR_EACH_OBSERVER(Observer, observer_list_, OnRefreshTokensLoaded());
    761 }
    762 
    763 int OAuth2TokenService::cache_size_for_testing() const {
    764   return token_cache_.size();
    765 }
    766 
    767 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing(
    768     int max_retries) {
    769   DCHECK(CalledOnValidThread());
    770   max_fetch_retry_num_ = max_retries;
    771 }
    772 
    773 size_t OAuth2TokenService::GetNumPendingRequestsForTesting(
    774     const std::string& client_id,
    775     const std::string& account_id,
    776     const ScopeSet& scopes) const {
    777   PendingFetcherMap::const_iterator iter = pending_fetchers_.find(
    778       OAuth2TokenService::RequestParameters(
    779           client_id,
    780           account_id,
    781           scopes));
    782   return iter == pending_fetchers_.end() ?
    783              0 : iter->second->GetWaitingRequestCount();
    784 }
    785