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 "chrome/browser/chromeos/settings/device_oauth2_token_service.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/memory/weak_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/prefs/pref_registry_simple.h"
15 #include "base/time/time.h"
16 #include "chrome/common/pref_names.h"
17 #include "google_apis/gaia/google_service_auth_error.h"
21 struct DeviceOAuth2TokenService::PendingRequest
{
22 PendingRequest(const base::WeakPtr
<RequestImpl
>& request
,
23 const std::string
& client_id
,
24 const std::string
& client_secret
,
25 const ScopeSet
& scopes
)
28 client_secret(client_secret
),
31 const base::WeakPtr
<RequestImpl
> request
;
32 const std::string client_id
;
33 const std::string client_secret
;
34 const ScopeSet scopes
;
37 void DeviceOAuth2TokenService::OnValidationCompleted(
38 GoogleServiceAuthError::State error
) {
39 if (error
== GoogleServiceAuthError::NONE
)
40 FlushPendingRequests(true, GoogleServiceAuthError::NONE
);
42 FlushPendingRequests(false, error
);
45 DeviceOAuth2TokenService::DeviceOAuth2TokenService(
46 DeviceOAuth2TokenServiceDelegate
* delegate
)
47 : OAuth2TokenService(delegate
),
48 delegate_(static_cast<DeviceOAuth2TokenServiceDelegate
*>(delegate
)) {
49 delegate_
->SetValidationStatusDelegate(this);
52 DeviceOAuth2TokenService::~DeviceOAuth2TokenService() {
53 delegate_
->SetValidationStatusDelegate(nullptr);
54 FlushPendingRequests(false, GoogleServiceAuthError::REQUEST_CANCELED
);
58 void DeviceOAuth2TokenService::RegisterPrefs(PrefRegistrySimple
* registry
) {
59 registry
->RegisterStringPref(prefs::kDeviceRobotAnyApiRefreshToken
,
63 void DeviceOAuth2TokenService::SetAndSaveRefreshToken(
64 const std::string
& refresh_token
,
65 const StatusCallback
& result_callback
) {
66 delegate_
->SetAndSaveRefreshToken(refresh_token
, result_callback
);
69 std::string
DeviceOAuth2TokenService::GetRobotAccountId() const {
70 return delegate_
->GetRobotAccountId();
73 void DeviceOAuth2TokenService::FetchOAuth2Token(
75 const std::string
& account_id
,
76 net::URLRequestContextGetter
* getter
,
77 const std::string
& client_id
,
78 const std::string
& client_secret
,
79 const ScopeSet
& scopes
) {
80 switch (delegate_
->state_
) {
81 case DeviceOAuth2TokenServiceDelegate::STATE_VALIDATION_PENDING
:
82 // If this is the first request for a token, start validation.
83 delegate_
->StartValidation();
85 case DeviceOAuth2TokenServiceDelegate::STATE_LOADING
:
86 case DeviceOAuth2TokenServiceDelegate::STATE_VALIDATION_STARTED
:
87 // Add a pending request that will be satisfied once validation completes.
88 pending_requests_
.push_back(new PendingRequest(
89 request
->AsWeakPtr(), client_id
, client_secret
, scopes
));
90 delegate_
->RequestValidation();
92 case DeviceOAuth2TokenServiceDelegate::STATE_NO_TOKEN
:
93 FailRequest(request
, GoogleServiceAuthError::USER_NOT_SIGNED_UP
);
95 case DeviceOAuth2TokenServiceDelegate::STATE_TOKEN_INVALID
:
96 FailRequest(request
, GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS
);
98 case DeviceOAuth2TokenServiceDelegate::STATE_TOKEN_VALID
:
99 // Pass through to OAuth2TokenService to satisfy the request.
100 OAuth2TokenService::FetchOAuth2Token(
101 request
, account_id
, getter
, client_id
, client_secret
, scopes
);
105 NOTREACHED() << "Unexpected state " << delegate_
->state_
;
108 void DeviceOAuth2TokenService::FlushPendingRequests(
110 GoogleServiceAuthError::State error
) {
111 std::vector
<PendingRequest
*> requests
;
112 requests
.swap(pending_requests_
);
113 for (std::vector
<PendingRequest
*>::iterator
request(requests
.begin());
114 request
!= requests
.end();
116 scoped_ptr
<PendingRequest
> scoped_request(*request
);
117 if (!scoped_request
->request
)
120 if (token_is_valid
) {
121 OAuth2TokenService::FetchOAuth2Token(
122 scoped_request
->request
.get(),
123 scoped_request
->request
->GetAccountId(),
124 delegate_
->GetRequestContext(), scoped_request
->client_id
,
125 scoped_request
->client_secret
, scoped_request
->scopes
);
127 FailRequest(scoped_request
->request
.get(), error
);
132 void DeviceOAuth2TokenService::FailRequest(
133 RequestImpl
* request
,
134 GoogleServiceAuthError::State error
) {
135 GoogleServiceAuthError
auth_error(error
);
136 base::MessageLoop::current()->PostTask(FROM_HERE
, base::Bind(
137 &RequestImpl::InformConsumer
,
138 request
->AsWeakPtr(),
144 } // namespace chromeos