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