Revert of [Android WebView] Synthesize a fake page loading event on page source modif...
[chromium-blink-merge.git] / google_apis / gaia / oauth2_token_service.cc
blobb0c4aa4a52f2fe3bc78e1caa84672d76fad7e3a8
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"
7 #include <vector>
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"
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),
29 scopes(scopes) {
32 OAuth2TokenService::RequestParameters::~RequestParameters() {
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;
42 if (account_id < p.account_id)
43 return true;
44 else if (p.account_id < account_id)
45 return false;
47 return scopes < p.scopes;
50 OAuth2TokenService::RequestImpl::RequestImpl(
51 const std::string& account_id,
52 OAuth2TokenService::Consumer* consumer)
53 : account_id_(account_id),
54 consumer_(consumer) {
57 OAuth2TokenService::RequestImpl::~RequestImpl() {
58 DCHECK(CalledOnValidThread());
61 std::string OAuth2TokenService::RequestImpl::GetAccountId() const {
62 return account_id_;
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);
76 else
77 consumer_->OnGetTokenFailure(this, error);
80 OAuth2TokenService::ScopedBatchChange::ScopedBatchChange(
81 OAuth2TokenService* token_service) : token_service_(token_service) {
82 DCHECK(token_service_);
83 token_service_->StartBatchChanges();
86 OAuth2TokenService::ScopedBatchChange::~ScopedBatchChange() {
87 token_service_->EndBatchChanges();
90 // Class that fetches an OAuth2 access token for a given account id and set of
91 // scopes.
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
103 // fetching.
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
112 // not deleted
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
117 // back with error).
118 class OAuth2TokenService::Fetcher : public OAuth2AccessTokenConsumer {
119 public:
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);
130 ~Fetcher() override;
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_;
142 void Cancel();
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_; }
151 protected:
152 // OAuth2AccessTokenConsumer
153 void OnGetTokenSuccess(const std::string& access_token,
154 const base::Time& expiration_date) override;
155 void OnGetTokenFailure(const GoogleServiceAuthError& error) override;
157 private:
158 Fetcher(OAuth2TokenService* oauth2_token_service,
159 const std::string& account_id,
160 net::URLRequestContextGetter* getter,
161 const std::string& client_id,
162 const std::string& client_secret,
163 const OAuth2TokenService::ScopeSet& scopes,
164 base::WeakPtr<RequestImpl> waiting_request);
165 void Start();
166 void InformWaitingRequests();
167 void InformWaitingRequestsAndDelete();
168 static bool ShouldRetry(const GoogleServiceAuthError& error);
169 int64 ComputeExponentialBackOffMilliseconds(int retry_num);
171 // |oauth2_token_service_| remains valid for the life of this Fetcher, since
172 // this Fetcher is destructed in the dtor of the OAuth2TokenService or is
173 // scheduled for deletion at the end of OnGetTokenFailure/OnGetTokenSuccess
174 // (whichever comes first).
175 OAuth2TokenService* const oauth2_token_service_;
176 scoped_refptr<net::URLRequestContextGetter> getter_;
177 const std::string account_id_;
178 const ScopeSet scopes_;
179 std::vector<base::WeakPtr<RequestImpl> > waiting_requests_;
181 int retry_number_;
182 base::OneShotTimer<Fetcher> retry_timer_;
183 scoped_ptr<OAuth2AccessTokenFetcher> fetcher_;
185 // Variables that store fetch results.
186 // Initialized to be GoogleServiceAuthError::SERVICE_UNAVAILABLE to handle
187 // destruction.
188 GoogleServiceAuthError error_;
189 std::string access_token_;
190 base::Time expiration_date_;
192 // OAuth2 client id and secret.
193 std::string client_id_;
194 std::string client_secret_;
196 DISALLOW_COPY_AND_ASSIGN(Fetcher);
199 // static
200 OAuth2TokenService::Fetcher* OAuth2TokenService::Fetcher::CreateAndStart(
201 OAuth2TokenService* oauth2_token_service,
202 const std::string& account_id,
203 net::URLRequestContextGetter* getter,
204 const std::string& client_id,
205 const std::string& client_secret,
206 const OAuth2TokenService::ScopeSet& scopes,
207 base::WeakPtr<RequestImpl> waiting_request) {
208 OAuth2TokenService::Fetcher* fetcher = new Fetcher(
209 oauth2_token_service,
210 account_id,
211 getter,
212 client_id,
213 client_secret,
214 scopes,
215 waiting_request);
217 fetcher->Start();
218 return fetcher;
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),
230 getter_(getter),
231 account_id_(account_id),
232 scopes_(scopes),
233 retry_number_(0),
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));
250 DCHECK(fetcher_);
251 fetcher_->Start(client_id_,
252 client_secret_,
253 std::vector<std::string>(scopes_.begin(), scopes_.end()));
254 retry_timer_.Stop();
257 void OAuth2TokenService::Fetcher::OnGetTokenSuccess(
258 const std::string& access_token,
259 const base::Time& expiration_date) {
260 fetcher_.reset();
262 // Fetch completes.
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_,
272 account_id_,
273 scopes_,
274 access_token_,
275 expiration_date_);
276 InformWaitingRequestsAndDelete();
279 void OAuth2TokenService::Fetcher::OnGetTokenFailure(
280 const GoogleServiceAuthError& error) {
281 fetcher_.reset();
283 if (ShouldRetry(error) && retry_number_ < max_fetch_retry_num_) {
284 base::TimeDelta backoff = base::TimeDelta::FromMilliseconds(
285 ComputeExponentialBackOffMilliseconds(retry_number_));
286 ++retry_number_;
287 retry_timer_.Stop();
288 retry_timer_.Start(FROM_HERE,
289 backoff,
290 this,
291 &OAuth2TokenService::Fetcher::Start);
292 return;
295 error_ = error;
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(
302 int retry_num) {
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;
309 // static
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() {
347 if (fetcher_)
348 fetcher_->CancelRequest();
349 fetcher_.reset();
350 retry_timer_.Stop();
351 error_ = GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
352 InformWaitingRequestsAndDelete();
355 const OAuth2TokenService::ScopeSet& OAuth2TokenService::Fetcher::GetScopeSet()
356 const {
357 return scopes_;
360 const std::string& OAuth2TokenService::Fetcher::GetClientId() const {
361 return client_id_;
364 const std::string& OAuth2TokenService::Fetcher::GetAccountId() const {
365 return account_id_;
368 OAuth2TokenService::Request::Request() {
371 OAuth2TokenService::Request::~Request() {
374 OAuth2TokenService::Consumer::Consumer(const std::string& id)
375 : id_(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(
415 account_id,
416 GetRequestContext(),
417 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
418 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
419 scopes,
420 consumer);
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(
431 account_id,
432 GetRequestContext(),
433 client_id,
434 client_secret,
435 scopes,
436 consumer);
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(
446 account_id,
447 getter,
448 GaiaUrls::GetInstance()->oauth2_chrome_client_id(),
449 GaiaUrls::GetInstance()->oauth2_chrome_client_secret(),
450 scopes,
451 consumer);
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,
467 consumer->id(),
468 scopes));
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,
476 base::Time()));
478 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
479 &RequestImpl::InformConsumer,
480 request->AsWeakPtr(),
481 error,
482 std::string(),
483 base::Time()));
484 return request.Pass();
487 RequestParameters request_parameters(client_id,
488 account_id,
489 scopes);
490 if (HasCacheEntry(request_parameters)) {
491 StartCacheLookupRequest(request.get(), request_parameters, consumer);
492 } else {
493 FetchOAuth2Token(request.get(),
494 account_id,
495 getter,
496 client_id,
497 client_secret,
498 scopes);
500 return request.Pass();
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
511 // a new fetcher.
512 RequestParameters request_parameters = RequestParameters(client_id,
513 account_id,
514 scopes);
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());
519 return;
522 pending_fetchers_[request_parameters] =
523 Fetcher::CreateAndStart(this,
524 account_id,
525 getter,
526 client_id,
527 client_secret,
528 scopes,
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,
541 consumer->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(),
558 scopes,
559 access_token);
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());
576 RemoveCacheEntry(
577 RequestParameters(client_id,
578 account_id,
579 scopes),
580 access_token);
583 void OAuth2TokenService::OnFetchComplete(Fetcher* fetcher) {
584 DCHECK(CalledOnValidThread());
586 // Update the auth error state so auth errors are appropriately communicated
587 // to the user.
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
598 // service's dtor.
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
606 // StartRequest().
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();
625 if (req) {
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())
652 return NULL;
653 if (token_iterator->second.expiration_date <= base::Time::Now()) {
654 token_cache_.erase(token_iterator);
655 return NULL;
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);
671 return true;
673 return false;
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,
685 account_id,
686 scopes)];
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++);
718 } else {
719 ++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();
729 ++iter) {
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();
741 ++iter) {
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();
753 ++iter) {
754 (*iter)->Cancel();
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(
792 int max_retries) {
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(
803 client_id,
804 account_id,
805 scopes));
806 return iter == pending_fetchers_.end() ?
807 0 : iter->second->GetWaitingRequestCount();