1 // Copyright 2014 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 "chrome/browser/sync/profile_sync_auth_provider.h"
8 #include "base/location.h"
9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/single_thread_task_runner.h"
11 #include "components/signin/core/browser/profile_oauth2_token_service.h"
12 #include "google_apis/gaia/gaia_constants.h"
14 // This is thin proxy class for forwarding calls between sync and UI threads.
15 // The main purpose is to hide the fact that ProfileSyncAuthProvider and
16 // SyncThreadProxy have independent lifetimes. If ProfileSyncAuthProvider is
17 // destroyed first calls to RequestAccessToken will never complete. This is fine
18 // since sync thread is not blocked and is in the process of shutdown anyway.
19 class ProfileSyncAuthProvider::SyncThreadProxy
20 : public syncer::SyncAuthProvider
,
21 public base::NonThreadSafe
{
24 base::WeakPtr
<ProfileSyncAuthProvider
> provider_impl
,
25 scoped_refptr
<base::SingleThreadTaskRunner
> provider_task_runner
);
27 // syncer::SyncAuthProvider implementation.
28 void RequestAccessToken(const RequestTokenCallback
& callback
) override
;
29 void InvalidateAccessToken(const std::string
& token
) override
;
32 base::WeakPtr
<ProfileSyncAuthProvider
> provider_impl_
;
33 scoped_refptr
<base::SingleThreadTaskRunner
> provider_task_runner_
;
35 DISALLOW_COPY_AND_ASSIGN(SyncThreadProxy
);
38 ProfileSyncAuthProvider::SyncThreadProxy::SyncThreadProxy(
39 base::WeakPtr
<ProfileSyncAuthProvider
> provider_impl
,
40 scoped_refptr
<base::SingleThreadTaskRunner
> provider_task_runner
)
41 : provider_impl_(provider_impl
),
42 provider_task_runner_(provider_task_runner
) {
43 // SyncThreadProxy is created on UI thread but used on sync thread.
44 // Detach NonThreadSafe from UI thread so that it can reattach to sync thread
45 // on first invocation.
49 void ProfileSyncAuthProvider::SyncThreadProxy::RequestAccessToken(
50 const RequestTokenCallback
& callback
) {
51 DCHECK(CalledOnValidThread());
52 provider_task_runner_
->PostTask(
54 base::Bind(&ProfileSyncAuthProvider::RequestAccessToken
,
57 base::MessageLoopProxy::current()));
60 void ProfileSyncAuthProvider::SyncThreadProxy::InvalidateAccessToken(
61 const std::string
& token
) {
62 DCHECK(CalledOnValidThread());
63 provider_task_runner_
->PostTask(
65 base::Bind(&ProfileSyncAuthProvider::InvalidateAccessToken
,
70 ProfileSyncAuthProvider::ProfileSyncAuthProvider(
71 ProfileOAuth2TokenService
* token_service
,
72 const std::string
& account_id
,
73 const std::string
& scope
)
74 : OAuth2TokenService::Consumer("sync_auth_provider"),
75 token_service_(token_service
),
76 account_id_(account_id
),
78 oauth2_scope_
.insert(scope
);
81 ProfileSyncAuthProvider::~ProfileSyncAuthProvider() {
82 DCHECK(CalledOnValidThread());
85 void ProfileSyncAuthProvider::RequestAccessToken(
86 const syncer::SyncAuthProvider::RequestTokenCallback
& callback
,
87 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
) {
88 DCHECK(CalledOnValidThread());
89 if (access_token_request_
!= NULL
) {
90 // If there is already pending request report it as cancelled.
91 GoogleServiceAuthError
error(GoogleServiceAuthError::REQUEST_CANCELED
);
92 RespondToTokenRequest(error
, std::string());
94 request_token_callback_
= callback
;
95 callback_task_runner_
= task_runner
;
96 access_token_request_
=
97 token_service_
->StartRequest(account_id_
, oauth2_scope_
, this);
100 void ProfileSyncAuthProvider::OnGetTokenSuccess(
101 const OAuth2TokenService::Request
* request
,
102 const std::string
& access_token
,
103 const base::Time
& expiration_time
) {
104 DCHECK_EQ(access_token_request_
, request
);
105 RespondToTokenRequest(GoogleServiceAuthError::AuthErrorNone(), access_token
);
108 void ProfileSyncAuthProvider::OnGetTokenFailure(
109 const OAuth2TokenService::Request
* request
,
110 const GoogleServiceAuthError
& error
) {
111 DCHECK_EQ(access_token_request_
, request
);
112 RespondToTokenRequest(error
, std::string());
115 void ProfileSyncAuthProvider::RespondToTokenRequest(
116 const GoogleServiceAuthError
& error
,
117 const std::string
& token
) {
118 DCHECK(CalledOnValidThread());
119 callback_task_runner_
->PostTask(
120 FROM_HERE
, base::Bind(request_token_callback_
, error
, token
));
121 access_token_request_
.reset();
122 request_token_callback_
.Reset();
123 callback_task_runner_
= NULL
;
126 void ProfileSyncAuthProvider::InvalidateAccessToken(const std::string
& token
) {
127 DCHECK(CalledOnValidThread());
128 token_service_
->InvalidateToken(account_id_
, oauth2_scope_
, token
);
131 scoped_ptr
<syncer::SyncAuthProvider
>
132 ProfileSyncAuthProvider::CreateProviderForSyncThread() {
133 DCHECK(CalledOnValidThread());
134 scoped_ptr
<syncer::SyncAuthProvider
> auth_provider(new SyncThreadProxy(
135 weak_factory_
.GetWeakPtr(), base::MessageLoopProxy::current()));
136 return auth_provider
.Pass();