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.
5 #include "google_apis/gaia/oauth2_token_service.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"
21 int OAuth2TokenService::max_fetch_retry_num_
= 5;
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
),
32 OAuth2TokenService::RequestParameters::~RequestParameters() {
35 bool OAuth2TokenService::RequestParameters::operator<(
36 const RequestParameters
& p
) const {
37 if (client_id
< p
.client_id
)
39 else if (p
.client_id
< client_id
)
42 if (account_id
< p
.account_id
)
44 else if (p
.account_id
< account_id
)
47 return scopes
< p
.scopes
;
50 OAuth2TokenService::RequestImpl::RequestImpl(
51 const std::string
& account_id
,
52 OAuth2TokenService::Consumer
* consumer
)
53 : account_id_(account_id
),
57 OAuth2TokenService::RequestImpl::~RequestImpl() {
58 DCHECK(CalledOnValidThread());
61 std::string
OAuth2TokenService::RequestImpl::GetAccountId() const {
65 std::string
OAuth2TokenService::RequestImpl::GetConsumerId() const {
66 return consumer_
->id();
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
);
77 consumer_
->OnGetTokenFailure(this, error
);
80 // Class that fetches an OAuth2 access token for a given account id and set of
83 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry
84 // mechanism is used to handle failures.
86 // To use this class, call CreateAndStart() to create and start a Fetcher.
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
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.
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
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
108 class OAuth2TokenService::Fetcher
: public OAuth2AccessTokenConsumer
{
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
);
122 // Add a request that is waiting for the result of this Fetcher.
123 void AddWaitingRequest(base::WeakPtr
<RequestImpl
> waiting_request
);
125 // Returns count of waiting requests.
126 size_t GetWaitingRequestCount() const;
128 const std::vector
<base::WeakPtr
<RequestImpl
> >& waiting_requests() const {
129 return waiting_requests_
;
134 const ScopeSet
& GetScopeSet() const;
135 const std::string
& GetClientId() const;
136 const std::string
& GetAccountId() const;
138 // The error result from this fetcher.
139 const GoogleServiceAuthError
& error() const { return error_
; }
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
;
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
);
157 void InformWaitingRequests();
158 void InformWaitingRequestsAndDelete();
159 static bool ShouldRetry(const GoogleServiceAuthError
& error
);
160 int64
ComputeExponentialBackOffMilliseconds(int retry_num
);
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_
;
173 base::OneShotTimer
<Fetcher
> retry_timer_
;
174 scoped_ptr
<OAuth2AccessTokenFetcher
> fetcher_
;
176 // Variables that store fetch results.
177 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle
179 GoogleServiceAuthError error_
;
180 std::string access_token_
;
181 base::Time expiration_date_
;
183 // OAuth2 client id and secret.
184 std::string client_id_
;
185 std::string client_secret_
;
187 DISALLOW_COPY_AND_ASSIGN(Fetcher
);
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
,
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
),
221 account_id_(account_id
),
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
);
232 OAuth2TokenService::Fetcher::~Fetcher() {
233 // Inform the waiting requests if it has not done so.
234 if (waiting_requests_
.size())
235 InformWaitingRequests();
238 void OAuth2TokenService::Fetcher::Start() {
239 fetcher_
.reset(oauth2_token_service_
->CreateAccessTokenFetcher(
240 account_id_
, getter_
.get(), this));
242 fetcher_
->Start(client_id_
,
244 std::vector
<std::string
>(scopes_
.begin(), scopes_
.end()));
248 void OAuth2TokenService::Fetcher::OnGetTokenSuccess(
249 const std::string
& access_token
,
250 const base::Time
& expiration_date
) {
254 error_
= GoogleServiceAuthError::AuthErrorNone();
255 access_token_
= access_token
;
256 expiration_date_
= expiration_date
;
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_
,
267 InformWaitingRequestsAndDelete();
270 void OAuth2TokenService::Fetcher::OnGetTokenFailure(
271 const GoogleServiceAuthError
& error
) {
274 if (ShouldRetry(error
) && retry_number_
< max_fetch_retry_num_
) {
275 base::TimeDelta backoff
= base::TimeDelta::FromMilliseconds(
276 ComputeExponentialBackOffMilliseconds(retry_number_
));
279 retry_timer_
.Start(FROM_HERE
,
282 &OAuth2TokenService::Fetcher::Start
);
287 InformWaitingRequestsAndDelete();
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(
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;
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
;
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_
);
317 waiting_requests_
.clear();
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);
328 void OAuth2TokenService::Fetcher::AddWaitingRequest(
329 base::WeakPtr
<OAuth2TokenService::RequestImpl
> waiting_request
) {
330 waiting_requests_
.push_back(waiting_request
);
333 size_t OAuth2TokenService::Fetcher::GetWaitingRequestCount() const {
334 return waiting_requests_
.size();
337 void OAuth2TokenService::Fetcher::Cancel() {
340 error_
= GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED
);
341 InformWaitingRequestsAndDelete();
344 const OAuth2TokenService::ScopeSet
& OAuth2TokenService::Fetcher::GetScopeSet()
349 const std::string
& OAuth2TokenService::Fetcher::GetClientId() const {
353 const std::string
& OAuth2TokenService::Fetcher::GetAccountId() const {
357 OAuth2TokenService::Request::Request() {
360 OAuth2TokenService::Request::~Request() {
363 OAuth2TokenService::Consumer::Consumer(const std::string
& id
)
366 OAuth2TokenService::Consumer::~Consumer() {
369 OAuth2TokenService::OAuth2TokenService() {
372 OAuth2TokenService::~OAuth2TokenService() {
373 // Release all the pending fetchers.
374 STLDeleteContainerPairSecondPointers(
375 pending_fetchers_
.begin(), pending_fetchers_
.end());
378 void OAuth2TokenService::AddObserver(Observer
* observer
) {
379 observer_list_
.AddObserver(observer
);
382 void OAuth2TokenService::RemoveObserver(Observer
* observer
) {
383 observer_list_
.RemoveObserver(observer
);
386 void OAuth2TokenService::AddDiagnosticsObserver(DiagnosticsObserver
* observer
) {
387 diagnostics_observer_list_
.AddObserver(observer
);
390 void OAuth2TokenService::RemoveDiagnosticsObserver(
391 DiagnosticsObserver
* observer
) {
392 diagnostics_observer_list_
.RemoveObserver(observer
);
395 std::vector
<std::string
> OAuth2TokenService::GetAccounts() {
396 return std::vector
<std::string
>();
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(
406 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
407 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
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(
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(
437 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
438 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
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());
453 scoped_ptr
<RequestImpl
> request(new RequestImpl(account_id
, consumer
));
454 FOR_EACH_OBSERVER(DiagnosticsObserver
, diagnostics_observer_list_
,
455 OnAccessTokenRequested(account_id
,
459 if (!RefreshTokenIsAvailable(account_id
)) {
460 GoogleServiceAuthError
error(GoogleServiceAuthError::USER_NOT_SIGNED_UP
);
462 FOR_EACH_OBSERVER(DiagnosticsObserver
, diagnostics_observer_list_
,
463 OnFetchAccessTokenComplete(
464 account_id
, consumer
->id(), scopes
, error
,
467 base::MessageLoop::current()->PostTask(FROM_HERE
, base::Bind(
468 &RequestImpl::InformConsumer
,
469 request
->AsWeakPtr(),
473 return request
.PassAs
<Request
>();
476 RequestParameters
request_parameters(client_id
,
479 if (HasCacheEntry(request_parameters
)) {
480 StartCacheLookupRequest(request
.get(), request_parameters
, consumer
);
482 FetchOAuth2Token(request
.get(),
489 return request
.PassAs
<Request
>();
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
501 RequestParameters request_parameters
= RequestParameters(client_id
,
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());
511 pending_fetchers_
[request_parameters
] =
512 Fetcher::CreateAndStart(this,
518 request
->AsWeakPtr());
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
,
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
));
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(),
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
);
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());
566 RequestParameters(client_id
,
572 void OAuth2TokenService::OnFetchComplete(Fetcher
* fetcher
) {
573 DCHECK(CalledOnValidThread());
575 // Update the auth error state so auth errors are appropriately communicated
577 UpdateAuthError(fetcher
->GetAccountId(), fetcher
->error());
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().
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
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
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().
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());
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();
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()));
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
);
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();
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())
642 if (token_iterator
->second
.expiration_date
<= base::Time::Now()) {
643 token_cache_
.erase(token_iterator
);
646 return &token_iterator
->second
;
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
);
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());
673 CacheEntry
& token
= token_cache_
[RequestParameters(client_id
,
676 token
.access_token
= access_token
;
677 token
.expiration_date
= expiration_date
;
680 void OAuth2TokenService::UpdateAuthError(
681 const std::string
& account_id
,
682 const GoogleServiceAuthError
& error
) {
683 // Default implementation does nothing.
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
));
695 token_cache_
.clear();
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
++);
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();
719 fetchers_to_cancel
.push_back(iter
->second
);
721 CancelFetchers(fetchers_to_cancel
);
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();
731 if (iter
->first
.account_id
== account_id
)
732 fetchers_to_cancel
.push_back(iter
->second
);
734 CancelFetchers(fetchers_to_cancel
);
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();
747 void OAuth2TokenService::FireRefreshTokenAvailable(
748 const std::string
& account_id
) {
749 FOR_EACH_OBSERVER(Observer
, observer_list_
,
750 OnRefreshTokenAvailable(account_id
));
753 void OAuth2TokenService::FireRefreshTokenRevoked(
754 const std::string
& account_id
) {
755 FOR_EACH_OBSERVER(Observer
, observer_list_
,
756 OnRefreshTokenRevoked(account_id
));
759 void OAuth2TokenService::FireRefreshTokensLoaded() {
760 FOR_EACH_OBSERVER(Observer
, observer_list_
, OnRefreshTokensLoaded());
763 int OAuth2TokenService::cache_size_for_testing() const {
764 return token_cache_
.size();
767 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing(
769 DCHECK(CalledOnValidThread());
770 max_fetch_retry_num_
= max_retries
;
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(
782 return iter
== pending_fetchers_
.end() ?
783 0 : iter
->second
->GetWaitingRequestCount();