GN + Android: extract android_standalone_library rule.
[chromium-blink-merge.git] / components / signin / core / browser / refresh_token_annotation_request.cc
blob768e8d8a2539a582061e1e778426a05a799512fc
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 "components/signin/core/browser/refresh_token_annotation_request.h"
7 #include "base/message_loop/message_loop.h"
8 #include "base/prefs/pref_service.h"
9 #include "base/rand_util.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/time/time.h"
12 #include "components/signin/core/browser/signin_client.h"
13 #include "components/signin/core/common/signin_pref_names.h"
14 #include "google_apis/gaia/gaia_constants.h"
15 #include "google_apis/gaia/gaia_urls.h"
16 #include "net/base/escape.h"
17 #include "net/url_request/url_request_context_getter.h"
19 RefreshTokenAnnotationRequest::RefreshTokenAnnotationRequest(
20 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
21 const std::string& device_id,
22 const std::string& client_id,
23 const base::Closure& request_callback)
24 : OAuth2TokenService::Consumer("refresh_token_annotation"),
25 request_context_getter_(request_context_getter),
26 device_id_(device_id),
27 client_id_(client_id),
28 request_callback_(request_callback) {
31 RefreshTokenAnnotationRequest::~RefreshTokenAnnotationRequest() {
32 DCHECK(CalledOnValidThread());
35 // static
36 scoped_ptr<RefreshTokenAnnotationRequest>
37 RefreshTokenAnnotationRequest::SendIfNeeded(
38 PrefService* pref_service,
39 OAuth2TokenService* token_service,
40 SigninClient* signin_client,
41 const scoped_refptr<net::URLRequestContextGetter>& request_context_getter,
42 const std::string& account_id,
43 const base::Closure& request_callback) {
44 scoped_ptr<RefreshTokenAnnotationRequest> request;
45 if (ShouldSendNow(pref_service)) {
46 request.reset(new RefreshTokenAnnotationRequest(
47 request_context_getter, signin_client->GetSigninScopedDeviceId(),
48 GaiaUrls::GetInstance()->oauth2_chrome_client_id(), request_callback));
49 request->RequestAccessToken(token_service, account_id);
51 return request.Pass();
54 // static
55 bool RefreshTokenAnnotationRequest::ShouldSendNow(PrefService* pref_service) {
56 bool should_send_now = false;
57 // Read scheduled time from prefs.
58 base::Time scheduled_time =
59 base::Time::FromInternalValue(pref_service->GetInt64(
60 prefs::kGoogleServicesRefreshTokenAnnotateScheduledTime));
62 if (!scheduled_time.is_null() && scheduled_time <= base::Time::Now()) {
63 DVLOG(2) << "Sending RefreshTokenAnnotationRequest";
64 should_send_now = true;
65 // Reset scheduled_time so that it gets rescheduled later in the function.
66 scheduled_time = base::Time();
69 if (scheduled_time.is_null()) {
70 // Random delay in interval [0, 20] days.
71 double delay_in_sec = base::RandDouble() * 20.0 * 24.0 * 3600.0;
72 scheduled_time =
73 base::Time::Now() + base::TimeDelta::FromSecondsD(delay_in_sec);
74 DVLOG(2) << "RefreshTokenAnnotationRequest scheduled for "
75 << scheduled_time;
76 pref_service->SetInt64(
77 prefs::kGoogleServicesRefreshTokenAnnotateScheduledTime,
78 scheduled_time.ToInternalValue());
80 return should_send_now;
83 void RefreshTokenAnnotationRequest::RequestAccessToken(
84 OAuth2TokenService* token_service,
85 const std::string& account_id) {
86 DCHECK(CalledOnValidThread());
87 OAuth2TokenService::ScopeSet scopes;
88 scopes.insert(GaiaConstants::kOAuth1LoginScope);
89 access_token_request_ = token_service->StartRequest(account_id, scopes, this);
92 void RefreshTokenAnnotationRequest::OnGetTokenSuccess(
93 const OAuth2TokenService::Request* request,
94 const std::string& access_token,
95 const base::Time& expiration_time) {
96 DCHECK(CalledOnValidThread());
97 DVLOG(2) << "Got access token";
98 Start(request_context_getter_.get(), access_token);
101 void RefreshTokenAnnotationRequest::OnGetTokenFailure(
102 const OAuth2TokenService::Request* request,
103 const GoogleServiceAuthError& error) {
104 DCHECK(CalledOnValidThread());
105 DVLOG(2) << "Failed to get access token";
106 base::MessageLoop::current()->PostTask(FROM_HERE, request_callback_);
107 request_callback_.Reset();
110 GURL RefreshTokenAnnotationRequest::CreateApiCallUrl() {
111 return GaiaUrls::GetInstance()->oauth2_issue_token_url();
114 std::string RefreshTokenAnnotationRequest::CreateApiCallBody() {
115 // response_type=none means we don't want any token back, just record that
116 // this request was sent.
117 const char kIssueTokenBodyFormat[] =
118 "force=true"
119 "&response_type=none"
120 "&scope=%s"
121 "&client_id=%s"
122 "&device_id=%s"
123 "&device_type=chrome";
125 // It doesn't matter which scope to use for IssueToken request, any common
126 // scope would do. In this case I'm using "userinfo.email".
127 return base::StringPrintf(
128 kIssueTokenBodyFormat,
129 net::EscapeUrlEncodedData(GaiaConstants::kGoogleUserInfoEmail, true)
130 .c_str(),
131 net::EscapeUrlEncodedData(client_id_, true).c_str(),
132 net::EscapeUrlEncodedData(device_id_, true).c_str());
135 void RefreshTokenAnnotationRequest::ProcessApiCallSuccess(
136 const net::URLFetcher* source) {
137 DCHECK(CalledOnValidThread());
138 DVLOG(2) << "Request succeeded";
139 base::MessageLoop::current()->PostTask(FROM_HERE, request_callback_);
140 request_callback_.Reset();
143 void RefreshTokenAnnotationRequest::ProcessApiCallFailure(
144 const net::URLFetcher* source) {
145 DCHECK(CalledOnValidThread());
146 DVLOG(2) << "Request failed";
147 base::MessageLoop::current()->PostTask(FROM_HERE, request_callback_);
148 request_callback_.Reset();