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 OAuth2TokenService::ScopedBacthChange::ScopedBacthChange(
81 OAuth2TokenService
* token_service
) : token_service_(token_service
) {
82 DCHECK(token_service_
);
83 token_service_
->StartBatchChanges();
86 OAuth2TokenService::ScopedBacthChange::~ScopedBacthChange() {
87 token_service_
->EndBatchChanges();
90 // Class that fetches an OAuth2 access token for a given account id and set of
93 // It aims to meet OAuth2TokenService's requirements on token fetching. Retry
94 // mechanism is used to handle failures.
96 // To use this class, call CreateAndStart() to create and start a Fetcher.
98 // The Fetcher will call back the service by calling
99 // OAuth2TokenService::OnFetchComplete() when it completes fetching, if it is
100 // not destructed before it completes fetching; if the Fetcher is destructed
101 // before it completes fetching, the service will never be called back. The
102 // Fetcher destructs itself after calling back the service when finishes
105 // Requests that are waiting for the fetching results of this Fetcher can be
106 // added to the Fetcher by calling
107 // OAuth2TokenService::Fetcher::AddWaitingRequest() before the Fetcher
108 // completes fetching.
110 // The waiting requests are taken as weak pointers and they can be deleted.
111 // The waiting requests will be called back with fetching results if they are
113 // - when the Fetcher completes fetching, if the Fetcher is not destructed
114 // before it completes fetching, or
115 // - when the Fetcher is destructed if the Fetcher is destructed before it
116 // completes fetching (in this case, the waiting requests will be called
118 class OAuth2TokenService::Fetcher
: public OAuth2AccessTokenConsumer
{
120 // Creates a Fetcher and starts fetching an OAuth2 access token for
121 // |account_id| and |scopes| in the request context obtained by |getter|.
122 // The given |oauth2_token_service| will be informed when fetching is done.
123 static Fetcher
* CreateAndStart(OAuth2TokenService
* oauth2_token_service
,
124 const std::string
& account_id
,
125 net::URLRequestContextGetter
* getter
,
126 const std::string
& client_id
,
127 const std::string
& client_secret
,
128 const ScopeSet
& scopes
,
129 base::WeakPtr
<RequestImpl
> waiting_request
);
132 // Add a request that is waiting for the result of this Fetcher.
133 void AddWaitingRequest(base::WeakPtr
<RequestImpl
> waiting_request
);
135 // Returns count of waiting requests.
136 size_t GetWaitingRequestCount() const;
138 const std::vector
<base::WeakPtr
<RequestImpl
> >& waiting_requests() const {
139 return waiting_requests_
;
144 const ScopeSet
& GetScopeSet() const;
145 const std::string
& GetClientId() const;
146 const std::string
& GetAccountId() const;
148 // The error result from this fetcher.
149 const GoogleServiceAuthError
& error() const { return error_
; }
152 // OAuth2AccessTokenConsumer
153 virtual void OnGetTokenSuccess(const std::string
& access_token
,
154 const base::Time
& expiration_date
) OVERRIDE
;
155 virtual void OnGetTokenFailure(
156 const GoogleServiceAuthError
& error
) OVERRIDE
;
159 Fetcher(OAuth2TokenService
* oauth2_token_service
,
160 const std::string
& account_id
,
161 net::URLRequestContextGetter
* getter
,
162 const std::string
& client_id
,
163 const std::string
& client_secret
,
164 const OAuth2TokenService::ScopeSet
& scopes
,
165 base::WeakPtr
<RequestImpl
> waiting_request
);
167 void InformWaitingRequests();
168 void InformWaitingRequestsAndDelete();
169 static bool ShouldRetry(const GoogleServiceAuthError
& error
);
170 int64
ComputeExponentialBackOffMilliseconds(int retry_num
);
172 // |oauth2_token_service_| remains valid for the life of this Fetcher, since
173 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is
174 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess
175 // (whichever comes first).
176 OAuth2TokenService
* const oauth2_token_service_
;
177 scoped_refptr
<net::URLRequestContextGetter
> getter_
;
178 const std::string account_id_
;
179 const ScopeSet scopes_
;
180 std::vector
<base::WeakPtr
<RequestImpl
> > waiting_requests_
;
183 base::OneShotTimer
<Fetcher
> retry_timer_
;
184 scoped_ptr
<OAuth2AccessTokenFetcher
> fetcher_
;
186 // Variables that store fetch results.
187 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle
189 GoogleServiceAuthError error_
;
190 std::string access_token_
;
191 base::Time expiration_date_
;
193 // OAuth2 client id and secret.
194 std::string client_id_
;
195 std::string client_secret_
;
197 DISALLOW_COPY_AND_ASSIGN(Fetcher
);
201 OAuth2TokenService::Fetcher
* OAuth2TokenService::Fetcher::CreateAndStart(
202 OAuth2TokenService
* oauth2_token_service
,
203 const std::string
& account_id
,
204 net::URLRequestContextGetter
* getter
,
205 const std::string
& client_id
,
206 const std::string
& client_secret
,
207 const OAuth2TokenService::ScopeSet
& scopes
,
208 base::WeakPtr
<RequestImpl
> waiting_request
) {
209 OAuth2TokenService::Fetcher
* fetcher
= new Fetcher(
210 oauth2_token_service
,
221 OAuth2TokenService::Fetcher::Fetcher(
222 OAuth2TokenService
* oauth2_token_service
,
223 const std::string
& account_id
,
224 net::URLRequestContextGetter
* getter
,
225 const std::string
& client_id
,
226 const std::string
& client_secret
,
227 const OAuth2TokenService::ScopeSet
& scopes
,
228 base::WeakPtr
<RequestImpl
> waiting_request
)
229 : oauth2_token_service_(oauth2_token_service
),
231 account_id_(account_id
),
234 error_(GoogleServiceAuthError::SERVICE_UNAVAILABLE
),
235 client_id_(client_id
),
236 client_secret_(client_secret
) {
237 DCHECK(oauth2_token_service_
);
238 waiting_requests_
.push_back(waiting_request
);
241 OAuth2TokenService::Fetcher::~Fetcher() {
242 // Inform the waiting requests if it has not done so.
243 if (waiting_requests_
.size())
244 InformWaitingRequests();
247 void OAuth2TokenService::Fetcher::Start() {
248 fetcher_
.reset(oauth2_token_service_
->CreateAccessTokenFetcher(
249 account_id_
, getter_
.get(), this));
251 fetcher_
->Start(client_id_
,
253 std::vector
<std::string
>(scopes_
.begin(), scopes_
.end()));
257 void OAuth2TokenService::Fetcher::OnGetTokenSuccess(
258 const std::string
& access_token
,
259 const base::Time
& expiration_date
) {
263 error_
= GoogleServiceAuthError::AuthErrorNone();
264 access_token_
= access_token
;
265 expiration_date_
= expiration_date
;
267 // Subclasses may override this method to skip caching in some cases, but
268 // we still inform all waiting Consumers of a successful token fetch below.
269 // This is intentional -- some consumers may need the token for cleanup
270 // tasks. https://chromiumcodereview.appspot.com/11312124/
271 oauth2_token_service_
->RegisterCacheEntry(client_id_
,
276 InformWaitingRequestsAndDelete();
279 void OAuth2TokenService::Fetcher::OnGetTokenFailure(
280 const GoogleServiceAuthError
& error
) {
283 if (ShouldRetry(error
) && retry_number_
< max_fetch_retry_num_
) {
284 base::TimeDelta backoff
= base::TimeDelta::FromMilliseconds(
285 ComputeExponentialBackOffMilliseconds(retry_number_
));
288 retry_timer_
.Start(FROM_HERE
,
291 &OAuth2TokenService::Fetcher::Start
);
296 InformWaitingRequestsAndDelete();
299 // Returns an exponential backoff in milliseconds including randomness less than
300 // 1000 ms when retrying fetching an OAuth2 access token.
301 int64
OAuth2TokenService::Fetcher::ComputeExponentialBackOffMilliseconds(
303 DCHECK(retry_num
< max_fetch_retry_num_
);
304 int64 exponential_backoff_in_seconds
= 1 << retry_num
;
305 // Returns a backoff with randomness < 1000ms
306 return (exponential_backoff_in_seconds
+ base::RandDouble()) * 1000;
310 bool OAuth2TokenService::Fetcher::ShouldRetry(
311 const GoogleServiceAuthError
& error
) {
312 GoogleServiceAuthError::State error_state
= error
.state();
313 return error_state
== GoogleServiceAuthError::CONNECTION_FAILED
||
314 error_state
== GoogleServiceAuthError::REQUEST_CANCELED
||
315 error_state
== GoogleServiceAuthError::SERVICE_UNAVAILABLE
;
318 void OAuth2TokenService::Fetcher::InformWaitingRequests() {
319 std::vector
<base::WeakPtr
<RequestImpl
> >::const_iterator iter
=
320 waiting_requests_
.begin();
321 for (; iter
!= waiting_requests_
.end(); ++iter
) {
322 base::WeakPtr
<RequestImpl
> waiting_request
= *iter
;
323 if (waiting_request
.get())
324 waiting_request
->InformConsumer(error_
, access_token_
, expiration_date_
);
326 waiting_requests_
.clear();
329 void OAuth2TokenService::Fetcher::InformWaitingRequestsAndDelete() {
330 // Deregisters itself from the service to prevent more waiting requests to
331 // be added when it calls back the waiting requests.
332 oauth2_token_service_
->OnFetchComplete(this);
333 InformWaitingRequests();
334 base::MessageLoop::current()->DeleteSoon(FROM_HERE
, this);
337 void OAuth2TokenService::Fetcher::AddWaitingRequest(
338 base::WeakPtr
<OAuth2TokenService::RequestImpl
> waiting_request
) {
339 waiting_requests_
.push_back(waiting_request
);
342 size_t OAuth2TokenService::Fetcher::GetWaitingRequestCount() const {
343 return waiting_requests_
.size();
346 void OAuth2TokenService::Fetcher::Cancel() {
348 fetcher_
->CancelRequest();
351 error_
= GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED
);
352 InformWaitingRequestsAndDelete();
355 const OAuth2TokenService::ScopeSet
& OAuth2TokenService::Fetcher::GetScopeSet()
360 const std::string
& OAuth2TokenService::Fetcher::GetClientId() const {
364 const std::string
& OAuth2TokenService::Fetcher::GetAccountId() const {
368 OAuth2TokenService::Request::Request() {
371 OAuth2TokenService::Request::~Request() {
374 OAuth2TokenService::Consumer::Consumer(const std::string
& id
)
377 OAuth2TokenService::Consumer::~Consumer() {
380 OAuth2TokenService::OAuth2TokenService() : batch_change_depth_(0) {
383 OAuth2TokenService::~OAuth2TokenService() {
384 // Release all the pending fetchers.
385 STLDeleteContainerPairSecondPointers(
386 pending_fetchers_
.begin(), pending_fetchers_
.end());
389 void OAuth2TokenService::AddObserver(Observer
* observer
) {
390 observer_list_
.AddObserver(observer
);
393 void OAuth2TokenService::RemoveObserver(Observer
* observer
) {
394 observer_list_
.RemoveObserver(observer
);
397 void OAuth2TokenService::AddDiagnosticsObserver(DiagnosticsObserver
* observer
) {
398 diagnostics_observer_list_
.AddObserver(observer
);
401 void OAuth2TokenService::RemoveDiagnosticsObserver(
402 DiagnosticsObserver
* observer
) {
403 diagnostics_observer_list_
.RemoveObserver(observer
);
406 std::vector
<std::string
> OAuth2TokenService::GetAccounts() {
407 return std::vector
<std::string
>();
410 scoped_ptr
<OAuth2TokenService::Request
> OAuth2TokenService::StartRequest(
411 const std::string
& account_id
,
412 const OAuth2TokenService::ScopeSet
& scopes
,
413 OAuth2TokenService::Consumer
* consumer
) {
414 return StartRequestForClientWithContext(
417 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
418 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
423 scoped_ptr
<OAuth2TokenService::Request
>
424 OAuth2TokenService::StartRequestForClient(
425 const std::string
& account_id
,
426 const std::string
& client_id
,
427 const std::string
& client_secret
,
428 const OAuth2TokenService::ScopeSet
& scopes
,
429 OAuth2TokenService::Consumer
* consumer
) {
430 return StartRequestForClientWithContext(
439 scoped_ptr
<OAuth2TokenService::Request
>
440 OAuth2TokenService::StartRequestWithContext(
441 const std::string
& account_id
,
442 net::URLRequestContextGetter
* getter
,
443 const ScopeSet
& scopes
,
444 Consumer
* consumer
) {
445 return StartRequestForClientWithContext(
448 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
449 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
454 scoped_ptr
<OAuth2TokenService::Request
>
455 OAuth2TokenService::StartRequestForClientWithContext(
456 const std::string
& account_id
,
457 net::URLRequestContextGetter
* getter
,
458 const std::string
& client_id
,
459 const std::string
& client_secret
,
460 const ScopeSet
& scopes
,
461 Consumer
* consumer
) {
462 DCHECK(CalledOnValidThread());
464 scoped_ptr
<RequestImpl
> request(new RequestImpl(account_id
, consumer
));
465 FOR_EACH_OBSERVER(DiagnosticsObserver
, diagnostics_observer_list_
,
466 OnAccessTokenRequested(account_id
,
470 if (!RefreshTokenIsAvailable(account_id
)) {
471 GoogleServiceAuthError
error(GoogleServiceAuthError::USER_NOT_SIGNED_UP
);
473 FOR_EACH_OBSERVER(DiagnosticsObserver
, diagnostics_observer_list_
,
474 OnFetchAccessTokenComplete(
475 account_id
, consumer
->id(), scopes
, error
,
478 base::MessageLoop::current()->PostTask(FROM_HERE
, base::Bind(
479 &RequestImpl::InformConsumer
,
480 request
->AsWeakPtr(),
484 return request
.PassAs
<Request
>();
487 RequestParameters
request_parameters(client_id
,
490 if (HasCacheEntry(request_parameters
)) {
491 StartCacheLookupRequest(request
.get(), request_parameters
, consumer
);
493 FetchOAuth2Token(request
.get(),
500 return request
.PassAs
<Request
>();
503 void OAuth2TokenService::FetchOAuth2Token(RequestImpl
* request
,
504 const std::string
& account_id
,
505 net::URLRequestContextGetter
* getter
,
506 const std::string
& client_id
,
507 const std::string
& client_secret
,
508 const ScopeSet
& scopes
) {
509 // If there is already a pending fetcher for |scopes| and |account_id|,
510 // simply register this |request| for those results rather than starting
512 RequestParameters request_parameters
= RequestParameters(client_id
,
515 std::map
<RequestParameters
, Fetcher
*>::iterator iter
=
516 pending_fetchers_
.find(request_parameters
);
517 if (iter
!= pending_fetchers_
.end()) {
518 iter
->second
->AddWaitingRequest(request
->AsWeakPtr());
522 pending_fetchers_
[request_parameters
] =
523 Fetcher::CreateAndStart(this,
529 request
->AsWeakPtr());
532 void OAuth2TokenService::StartCacheLookupRequest(
533 RequestImpl
* request
,
534 const OAuth2TokenService::RequestParameters
& request_parameters
,
535 OAuth2TokenService::Consumer
* consumer
) {
536 CHECK(HasCacheEntry(request_parameters
));
537 const CacheEntry
* cache_entry
= GetCacheEntry(request_parameters
);
538 FOR_EACH_OBSERVER(DiagnosticsObserver
, diagnostics_observer_list_
,
539 OnFetchAccessTokenComplete(
540 request_parameters
.account_id
,
542 request_parameters
.scopes
,
543 GoogleServiceAuthError::AuthErrorNone(),
544 cache_entry
->expiration_date
));
545 base::MessageLoop::current()->PostTask(FROM_HERE
, base::Bind(
546 &RequestImpl::InformConsumer
,
547 request
->AsWeakPtr(),
548 GoogleServiceAuthError(GoogleServiceAuthError::NONE
),
549 cache_entry
->access_token
,
550 cache_entry
->expiration_date
));
553 void OAuth2TokenService::InvalidateToken(const std::string
& account_id
,
554 const ScopeSet
& scopes
,
555 const std::string
& access_token
) {
556 InvalidateOAuth2Token(account_id
,
557 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
562 void OAuth2TokenService::InvalidateTokenForClient(
563 const std::string
& account_id
,
564 const std::string
& client_id
,
565 const ScopeSet
& scopes
,
566 const std::string
& access_token
) {
567 InvalidateOAuth2Token(account_id
, client_id
, scopes
, access_token
);
570 void OAuth2TokenService::InvalidateOAuth2Token(
571 const std::string
& account_id
,
572 const std::string
& client_id
,
573 const ScopeSet
& scopes
,
574 const std::string
& access_token
) {
575 DCHECK(CalledOnValidThread());
577 RequestParameters(client_id
,
583 void OAuth2TokenService::OnFetchComplete(Fetcher
* fetcher
) {
584 DCHECK(CalledOnValidThread());
586 // Update the auth error state so auth errors are appropriately communicated
588 UpdateAuthError(fetcher
->GetAccountId(), fetcher
->error());
590 // Note |fetcher| is recorded in |pending_fetcher_| mapped to its refresh
591 // token and scope set. This is guaranteed as follows; here a Fetcher is said
592 // to be uncompleted if it has not finished calling back
593 // OAuth2TokenService::OnFetchComplete().
595 // (1) All the live Fetchers are created by this service.
596 // This is because (1) all the live Fetchers are created by a live
597 // service, as all the fetchers created by a service are destructed in the
600 // (2) All the uncompleted Fetchers created by this service are recorded in
601 // |pending_fetchers_|.
602 // This is because (1) all the created Fetchers are added to
603 // |pending_fetchers_| (in method StartRequest()) and (2) method
604 // OnFetchComplete() is the only place where a Fetcher is erased from
605 // |pending_fetchers_|. Note no Fetcher is erased in method
608 // (3) Each of the Fetchers recorded in |pending_fetchers_| is mapped to its
609 // refresh token and ScopeSet. This is guaranteed by Fetcher creation in
610 // method StartRequest().
612 // When this method is called, |fetcher| is alive and uncompleted.
613 // By (1), |fetcher| is created by this service.
614 // Then by (2), |fetcher| is recorded in |pending_fetchers_|.
615 // Then by (3), |fetcher_| is mapped to its refresh token and ScopeSet.
616 RequestParameters
request_param(fetcher
->GetClientId(),
617 fetcher
->GetAccountId(),
618 fetcher
->GetScopeSet());
620 const OAuth2TokenService::CacheEntry
* entry
= GetCacheEntry(request_param
);
621 const std::vector
<base::WeakPtr
<RequestImpl
> >& requests
=
622 fetcher
->waiting_requests();
623 for (size_t i
= 0; i
< requests
.size(); ++i
) {
624 const RequestImpl
* req
= requests
[i
].get();
626 FOR_EACH_OBSERVER(DiagnosticsObserver
, diagnostics_observer_list_
,
627 OnFetchAccessTokenComplete(
628 req
->GetAccountId(), req
->GetConsumerId(),
629 fetcher
->GetScopeSet(), fetcher
->error(),
630 entry
? entry
->expiration_date
: base::Time()));
634 std::map
<RequestParameters
, Fetcher
*>::iterator iter
=
635 pending_fetchers_
.find(request_param
);
636 DCHECK(iter
!= pending_fetchers_
.end());
637 DCHECK_EQ(fetcher
, iter
->second
);
638 pending_fetchers_
.erase(iter
);
641 bool OAuth2TokenService::HasCacheEntry(
642 const RequestParameters
& request_parameters
) {
643 const CacheEntry
* cache_entry
= GetCacheEntry(request_parameters
);
644 return cache_entry
&& cache_entry
->access_token
.length();
647 const OAuth2TokenService::CacheEntry
* OAuth2TokenService::GetCacheEntry(
648 const RequestParameters
& request_parameters
) {
649 DCHECK(CalledOnValidThread());
650 TokenCache::iterator token_iterator
= token_cache_
.find(request_parameters
);
651 if (token_iterator
== token_cache_
.end())
653 if (token_iterator
->second
.expiration_date
<= base::Time::Now()) {
654 token_cache_
.erase(token_iterator
);
657 return &token_iterator
->second
;
660 bool OAuth2TokenService::RemoveCacheEntry(
661 const RequestParameters
& request_parameters
,
662 const std::string
& token_to_remove
) {
663 DCHECK(CalledOnValidThread());
664 TokenCache::iterator token_iterator
= token_cache_
.find(request_parameters
);
665 if (token_iterator
!= token_cache_
.end() &&
666 token_iterator
->second
.access_token
== token_to_remove
) {
667 FOR_EACH_OBSERVER(DiagnosticsObserver
, diagnostics_observer_list_
,
668 OnTokenRemoved(request_parameters
.account_id
,
669 request_parameters
.scopes
));
670 token_cache_
.erase(token_iterator
);
676 void OAuth2TokenService::RegisterCacheEntry(
677 const std::string
& client_id
,
678 const std::string
& account_id
,
679 const OAuth2TokenService::ScopeSet
& scopes
,
680 const std::string
& access_token
,
681 const base::Time
& expiration_date
) {
682 DCHECK(CalledOnValidThread());
684 CacheEntry
& token
= token_cache_
[RequestParameters(client_id
,
687 token
.access_token
= access_token
;
688 token
.expiration_date
= expiration_date
;
691 void OAuth2TokenService::UpdateAuthError(
692 const std::string
& account_id
,
693 const GoogleServiceAuthError
& error
) {
694 // Default implementation does nothing.
697 void OAuth2TokenService::ClearCache() {
698 DCHECK(CalledOnValidThread());
699 for (TokenCache::iterator iter
= token_cache_
.begin();
700 iter
!= token_cache_
.end(); ++iter
) {
701 FOR_EACH_OBSERVER(DiagnosticsObserver
, diagnostics_observer_list_
,
702 OnTokenRemoved(iter
->first
.account_id
,
703 iter
->first
.scopes
));
706 token_cache_
.clear();
709 void OAuth2TokenService::ClearCacheForAccount(const std::string
& account_id
) {
710 DCHECK(CalledOnValidThread());
711 for (TokenCache::iterator iter
= token_cache_
.begin();
712 iter
!= token_cache_
.end();
713 /* iter incremented in body */) {
714 if (iter
->first
.account_id
== account_id
) {
715 FOR_EACH_OBSERVER(DiagnosticsObserver
, diagnostics_observer_list_
,
716 OnTokenRemoved(account_id
, iter
->first
.scopes
));
717 token_cache_
.erase(iter
++);
724 void OAuth2TokenService::CancelAllRequests() {
725 std::vector
<Fetcher
*> fetchers_to_cancel
;
726 for (std::map
<RequestParameters
, Fetcher
*>::iterator iter
=
727 pending_fetchers_
.begin();
728 iter
!= pending_fetchers_
.end();
730 fetchers_to_cancel
.push_back(iter
->second
);
732 CancelFetchers(fetchers_to_cancel
);
735 void OAuth2TokenService::CancelRequestsForAccount(
736 const std::string
& account_id
) {
737 std::vector
<Fetcher
*> fetchers_to_cancel
;
738 for (std::map
<RequestParameters
, Fetcher
*>::iterator iter
=
739 pending_fetchers_
.begin();
740 iter
!= pending_fetchers_
.end();
742 if (iter
->first
.account_id
== account_id
)
743 fetchers_to_cancel
.push_back(iter
->second
);
745 CancelFetchers(fetchers_to_cancel
);
748 void OAuth2TokenService::CancelFetchers(
749 std::vector
<Fetcher
*> fetchers_to_cancel
) {
750 for (std::vector
<OAuth2TokenService::Fetcher
*>::iterator iter
=
751 fetchers_to_cancel
.begin();
752 iter
!= fetchers_to_cancel
.end();
758 void OAuth2TokenService::FireRefreshTokenAvailable(
759 const std::string
& account_id
) {
760 FOR_EACH_OBSERVER(Observer
, observer_list_
,
761 OnRefreshTokenAvailable(account_id
));
764 void OAuth2TokenService::FireRefreshTokenRevoked(
765 const std::string
& account_id
) {
766 FOR_EACH_OBSERVER(Observer
, observer_list_
,
767 OnRefreshTokenRevoked(account_id
));
770 void OAuth2TokenService::FireRefreshTokensLoaded() {
771 FOR_EACH_OBSERVER(Observer
, observer_list_
, OnRefreshTokensLoaded());
774 void OAuth2TokenService::StartBatchChanges() {
775 ++batch_change_depth_
;
776 if (batch_change_depth_
== 1)
777 FOR_EACH_OBSERVER(Observer
, observer_list_
, OnStartBatchChanges());
780 void OAuth2TokenService::EndBatchChanges() {
781 --batch_change_depth_
;
782 DCHECK_LE(0, batch_change_depth_
);
783 if (batch_change_depth_
== 0)
784 FOR_EACH_OBSERVER(Observer
, observer_list_
, OnEndBatchChanges());
787 int OAuth2TokenService::cache_size_for_testing() const {
788 return token_cache_
.size();
791 void OAuth2TokenService::set_max_authorization_token_fetch_retries_for_testing(
793 DCHECK(CalledOnValidThread());
794 max_fetch_retry_num_
= max_retries
;
797 size_t OAuth2TokenService::GetNumPendingRequestsForTesting(
798 const std::string
& client_id
,
799 const std::string
& account_id
,
800 const ScopeSet
& scopes
) const {
801 PendingFetcherMap::const_iterator iter
= pending_fetchers_
.find(
802 OAuth2TokenService::RequestParameters(
806 return iter
== pending_fetchers_
.end() ?
807 0 : iter
->second
->GetWaitingRequestCount();