146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved. 246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// found in the LICENSE file. 446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "google_apis/gaia/oauth2_token_service_request.h" 646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/bind.h" 846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/ref_counted.h" 946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 1046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/single_thread_task_runner.h" 1146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "base/thread_task_runner_handle.h" 1246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "google_apis/gaia/google_service_auth_error.h" 1346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "google_apis/gaia/oauth2_access_token_consumer.h" 1446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)OAuth2TokenServiceRequest::TokenServiceProvider::TokenServiceProvider() { 1646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 1746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 1846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)OAuth2TokenServiceRequest::TokenServiceProvider::~TokenServiceProvider() { 1946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 2046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 2146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Core serves as the base class for OAuth2TokenService operations. Each 2246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// operation should be modeled as a derived type. 2346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 2446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// Core is used like this: 2546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 2646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 1. Constructed on owner thread. 2746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 2846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 2. Start() is called on owner thread, which calls StartOnTokenServiceThread() 2946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// on token service thread. 3046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 3146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 3. Request is executed. 3246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 3346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 4. Stop() is called on owner thread, which calls StopOnTokenServiceThread() 3446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// on token service thread. 3546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 3646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// 5. Core is destroyed on owner thread. 3746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class OAuth2TokenServiceRequest::Core 3846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : public base::NonThreadSafe, 3946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public base::RefCountedThreadSafe<OAuth2TokenServiceRequest::Core> { 4046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 4146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Note the thread where an instance of Core is constructed is referred to as 4246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // the "owner thread" here. 436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) Core(OAuth2TokenServiceRequest* owner, 446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const scoped_refptr<TokenServiceProvider>& provider); 4546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Starts the core. Must be called on the owner thread. 4746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void Start(); 4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Stops the core. Must be called on the owner thread. 5046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void Stop(); 5146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Returns true if this object has been stopped. Must be called on the owner 5346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // thread. 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) bool IsStopped() const; 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) protected: 5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Core must be destroyed on the owner thread. If data members must be 5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // cleaned up or destroyed on the token service thread, do so in the 5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // StopOnTokenServiceThread method. 6046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual ~Core(); 6146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Called on the token service thread. 6346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void StartOnTokenServiceThread() = 0; 6446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Called on the token service thread. 6646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void StopOnTokenServiceThread() = 0; 6746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 6846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::SingleThreadTaskRunner* token_service_task_runner(); 6946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenService* token_service(); 7046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenServiceRequest* owner(); 7146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 7346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) friend class base::RefCountedThreadSafe<OAuth2TokenServiceRequest::Core>; 7446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void DoNothing(); 7646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 7746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> token_service_task_runner_; 7846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenServiceRequest* owner_; 796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // Clear on owner thread. OAuth2TokenServiceRequest promises to clear its 816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // last reference to TokenServiceProvider on the owner thread so the caller 826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) // can ensure it is destroyed on the owner thread if desired. 836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) scoped_refptr<TokenServiceProvider> provider_; 846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 8546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Core); 8646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 8746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)OAuth2TokenServiceRequest::Core::Core( 896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) OAuth2TokenServiceRequest* owner, 906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const scoped_refptr<TokenServiceProvider>& provider) 9146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : owner_(owner), provider_(provider) { 9246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(owner_); 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(provider_.get()); 9446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) token_service_task_runner_ = provider_->GetTokenServiceTaskRunner(); 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(token_service_task_runner_.get()); 9646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 9746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 9846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)OAuth2TokenServiceRequest::Core::~Core() { 9946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 10046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void OAuth2TokenServiceRequest::Core::Start() { 10246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(CalledOnValidThread()); 10346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) token_service_task_runner_->PostTask( 10446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 10546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&OAuth2TokenServiceRequest::Core::StartOnTokenServiceThread, 10646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this)); 10746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 10846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 10946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void OAuth2TokenServiceRequest::Core::Stop() { 11046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(CalledOnValidThread()); 11146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!IsStopped()); 11246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 11346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Detaches |owner_| from this instance so |owner_| will be called back only 11446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // if |Stop()| has never been called. 11546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) owner_ = NULL; 11646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 11746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // We are stopping and will likely be destroyed soon. Use a reply closure 11846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // (DoNothing) to retain "this" and ensure we are destroyed in the owner 11946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // thread, not the task runner thread. PostTaskAndReply guarantees that the 12046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // reply closure will execute after StopOnTokenServiceThread has completed. 12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) token_service_task_runner_->PostTaskAndReply( 12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&OAuth2TokenServiceRequest::Core::StopOnTokenServiceThread, 12446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this), 12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&OAuth2TokenServiceRequest::Core::DoNothing, this)); 12646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 12746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 12846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool OAuth2TokenServiceRequest::Core::IsStopped() const { 12946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(CalledOnValidThread()); 13046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return owner_ == NULL; 13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 13246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)base::SingleThreadTaskRunner* 13446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)OAuth2TokenServiceRequest::Core::token_service_task_runner() { 1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return token_service_task_runner_.get(); 13646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 13746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)OAuth2TokenService* OAuth2TokenServiceRequest::Core::token_service() { 13946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(token_service_task_runner_->BelongsToCurrentThread()); 14046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return provider_->GetTokenService(); 14146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 14246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)OAuth2TokenServiceRequest* OAuth2TokenServiceRequest::Core::owner() { 14446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(CalledOnValidThread()); 14546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return owner_; 14646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 14746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 14846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void OAuth2TokenServiceRequest::Core::DoNothing() { 14946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(CalledOnValidThread()); 15046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 15146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 15246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)namespace { 15346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 15446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// An implementation of Core for getting an access token. 15546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class RequestCore : public OAuth2TokenServiceRequest::Core, 15646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public OAuth2TokenService::Consumer { 15746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 15846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) RequestCore(OAuth2TokenServiceRequest* owner, 1596e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const scoped_refptr< 1606e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) OAuth2TokenServiceRequest::TokenServiceProvider>& provider, 16146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenService::Consumer* consumer, 16246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& account_id, 16346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes); 16446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 16546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // OAuth2TokenService::Consumer. Must be called on the token service thread. 16646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void OnGetTokenSuccess(const OAuth2TokenService::Request* request, 16746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& access_token, 16846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::Time& expiration_time) OVERRIDE; 16946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void OnGetTokenFailure(const OAuth2TokenService::Request* request, 17046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const GoogleServiceAuthError& error) OVERRIDE; 17146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 17346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) friend class base::RefCountedThreadSafe<RequestCore>; 17446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Must be destroyed on the owner thread. 17646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual ~RequestCore(); 17746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 17846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Core implementation. 17946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void StartOnTokenServiceThread() OVERRIDE; 18046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void StopOnTokenServiceThread() OVERRIDE; 18146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 18246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void InformOwnerOnGetTokenSuccess(std::string access_token, 18346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Time expiration_time); 18446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) void InformOwnerOnGetTokenFailure(GoogleServiceAuthError error); 18546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 18646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<base::SingleThreadTaskRunner> owner_task_runner_; 18746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenService::Consumer* const consumer_; 18846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string account_id_; 18946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenService::ScopeSet scopes_; 19046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 19146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // OAuth2TokenService request for fetching OAuth2 access token; it should be 19246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // created, reset and accessed only on the token service thread. 19346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<OAuth2TokenService::Request> request_; 19446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 19546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(RequestCore); 19646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 19746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 19846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)RequestCore::RequestCore( 19946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenServiceRequest* owner, 2006e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>& 2016e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) provider, 20246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenService::Consumer* consumer, 20346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& account_id, 20446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes) 20546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : OAuth2TokenServiceRequest::Core(owner, provider), 20646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenService::Consumer("oauth2_token_service"), 20746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) owner_task_runner_(base::ThreadTaskRunnerHandle::Get()), 20846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) consumer_(consumer), 20946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) account_id_(account_id), 21046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scopes_(scopes) { 21146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(consumer_); 21246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!account_id_.empty()); 21346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!scopes_.empty()); 21446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 21546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 21646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)RequestCore::~RequestCore() { 21746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 21846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 21946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void RequestCore::StartOnTokenServiceThread() { 22046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(token_service_task_runner()->BelongsToCurrentThread()); 22146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request_ = token_service()->StartRequest(account_id_, scopes_, this).Pass(); 22246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 22346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 22446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void RequestCore::StopOnTokenServiceThread() { 22546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(token_service_task_runner()->BelongsToCurrentThread()); 22646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request_.reset(); 22746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 22846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 22946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void RequestCore::OnGetTokenSuccess(const OAuth2TokenService::Request* request, 23046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& access_token, 23146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const base::Time& expiration_time) { 23246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(token_service_task_runner()->BelongsToCurrentThread()); 23346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_EQ(request_.get(), request); 23446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) owner_task_runner_->PostTask( 23546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 23646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&RequestCore::InformOwnerOnGetTokenSuccess, 23746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) this, 23846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) access_token, 23946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) expiration_time)); 24046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request_.reset(); 24146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 24246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 24346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void RequestCore::OnGetTokenFailure(const OAuth2TokenService::Request* request, 24446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const GoogleServiceAuthError& error) { 24546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(token_service_task_runner()->BelongsToCurrentThread()); 24646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK_EQ(request_.get(), request); 24746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) owner_task_runner_->PostTask( 24846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) FROM_HERE, 24946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Bind(&RequestCore::InformOwnerOnGetTokenFailure, this, error)); 25046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request_.reset(); 25146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 25246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 25346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void RequestCore::InformOwnerOnGetTokenSuccess(std::string access_token, 25446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) base::Time expiration_time) { 25546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(CalledOnValidThread()); 25646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!IsStopped()) { 25746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) consumer_->OnGetTokenSuccess(owner(), access_token, expiration_time); 25846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 25946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 26046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 26146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void RequestCore::InformOwnerOnGetTokenFailure(GoogleServiceAuthError error) { 26246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(CalledOnValidThread()); 26346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (!IsStopped()) { 26446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) consumer_->OnGetTokenFailure(owner(), error); 26546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) } 26646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 26746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 26846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// An implementation of Core for invalidating an access token. 26946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)class InvalidateCore : public OAuth2TokenServiceRequest::Core { 27046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) public: 27146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) InvalidateCore(OAuth2TokenServiceRequest* owner, 2726e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const scoped_refptr< 2736e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) OAuth2TokenServiceRequest::TokenServiceProvider>& provider, 27446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& access_token, 27546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& account_id, 27646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes); 27746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 27846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) private: 27946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) friend class base::RefCountedThreadSafe<InvalidateCore>; 28046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 28146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Must be destroyed on the owner thread. 28246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual ~InvalidateCore(); 28346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 28446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Core implementation. 28546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void StartOnTokenServiceThread() OVERRIDE; 28646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) virtual void StopOnTokenServiceThread() OVERRIDE; 28746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 28846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string access_token_; 28946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) std::string account_id_; 29046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenService::ScopeSet scopes_; 29146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 29246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(InvalidateCore); 29346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)}; 29446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 29546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)InvalidateCore::InvalidateCore( 29646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenServiceRequest* owner, 2976e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const scoped_refptr<OAuth2TokenServiceRequest::TokenServiceProvider>& 2986e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) provider, 29946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& access_token, 30046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& account_id, 30146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes) 30246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : OAuth2TokenServiceRequest::Core(owner, provider), 30346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) access_token_(access_token), 30446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) account_id_(account_id), 30546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scopes_(scopes) { 30646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!access_token_.empty()); 30746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!account_id_.empty()); 30846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!scopes.empty()); 30946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 31046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 31146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)InvalidateCore::~InvalidateCore() { 31246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 31346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 31446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void InvalidateCore::StartOnTokenServiceThread() { 31546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(token_service_task_runner()->BelongsToCurrentThread()); 31646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) token_service()->InvalidateToken(account_id_, scopes_, access_token_); 31746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 31846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 31946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void InvalidateCore::StopOnTokenServiceThread() { 32046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(token_service_task_runner()->BelongsToCurrentThread()); 32146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Nothing to do. 32246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 32346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 32446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} // namespace 32546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 32646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static 32746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)scoped_ptr<OAuth2TokenServiceRequest> OAuth2TokenServiceRequest::CreateAndStart( 3286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const scoped_refptr<TokenServiceProvider>& provider, 32946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& account_id, 33046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 33146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) OAuth2TokenService::Consumer* consumer) { 33246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<OAuth2TokenServiceRequest> request( 33346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new OAuth2TokenServiceRequest(account_id)); 33446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<Core> core( 33546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new RequestCore(request.get(), provider, consumer, account_id, scopes)); 33646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request->StartWithCore(core); 33746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return request.Pass(); 33846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 33946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 34046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)// static 34146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void OAuth2TokenServiceRequest::InvalidateToken( 3426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const scoped_refptr<TokenServiceProvider>& provider, 34346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& account_id, 34446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const OAuth2TokenService::ScopeSet& scopes, 34546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& access_token) { 34646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_ptr<OAuth2TokenServiceRequest> request( 34746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) new OAuth2TokenServiceRequest(account_id)); 34846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) scoped_refptr<Core> core(new InvalidateCore( 34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request.get(), provider, access_token, account_id, scopes)); 35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) request->StartWithCore(core); 35146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 35246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 35346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)OAuth2TokenServiceRequest::~OAuth2TokenServiceRequest() { 35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) core_->Stop(); 35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 35646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 35746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)std::string OAuth2TokenServiceRequest::GetAccountId() const { 35846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) return account_id_; 35946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 36046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 36146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)OAuth2TokenServiceRequest::OAuth2TokenServiceRequest( 36246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const std::string& account_id) 36346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : account_id_(account_id) { 36446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) DCHECK(!account_id_.empty()); 36546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 36646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 36746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void OAuth2TokenServiceRequest::StartWithCore(const scoped_refptr<Core>& core) { 3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(core.get()); 36946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) core_ = core; 37046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) core_->Start(); 37146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 372