OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "google_apis/gcm/engine/registration_request.h" | 5 #include "google_apis/gcm/engine/registration_request.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <utility> | 8 #include <utility> |
9 | 9 |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 15 matching lines...) Expand all Loading... | |
26 #include "url/gurl.h" | 26 #include "url/gurl.h" |
27 | 27 |
28 namespace gcm { | 28 namespace gcm { |
29 | 29 |
30 namespace { | 30 namespace { |
31 | 31 |
32 const char kRegistrationRequestContentType[] = | 32 const char kRegistrationRequestContentType[] = |
33 "application/x-www-form-urlencoded"; | 33 "application/x-www-form-urlencoded"; |
34 | 34 |
35 // Request constants. | 35 // Request constants. |
36 const char kAppIdKey[] = "app"; | 36 const char kCategoryKey[] = "app"; |
37 const char kSubtypeKey[] = "X-subtype"; | |
37 const char kDeviceIdKey[] = "device"; | 38 const char kDeviceIdKey[] = "device"; |
38 const char kLoginHeader[] = "AidLogin"; | 39 const char kLoginHeader[] = "AidLogin"; |
39 | 40 |
40 // Response constants. | 41 // Response constants. |
41 const char kErrorPrefix[] = "Error="; | 42 const char kErrorPrefix[] = "Error="; |
42 const char kTokenPrefix[] = "token="; | 43 const char kTokenPrefix[] = "token="; |
43 const char kDeviceRegistrationError[] = "PHONE_REGISTRATION_ERROR"; | 44 const char kDeviceRegistrationError[] = "PHONE_REGISTRATION_ERROR"; |
44 const char kAuthenticationFailed[] = "AUTHENTICATION_FAILED"; | 45 const char kAuthenticationFailed[] = "AUTHENTICATION_FAILED"; |
45 const char kInvalidSender[] = "INVALID_SENDER"; | 46 const char kInvalidSender[] = "INVALID_SENDER"; |
46 const char kInvalidParameters[] = "INVALID_PARAMETERS"; | 47 const char kInvalidParameters[] = "INVALID_PARAMETERS"; |
(...skipping 21 matching lines...) Expand all Loading... | |
68 status == RegistrationRequest::DEVICE_REGISTRATION_ERROR || | 69 status == RegistrationRequest::DEVICE_REGISTRATION_ERROR || |
69 status == RegistrationRequest::HTTP_NOT_OK || | 70 status == RegistrationRequest::HTTP_NOT_OK || |
70 status == RegistrationRequest::URL_FETCHING_FAILED || | 71 status == RegistrationRequest::URL_FETCHING_FAILED || |
71 status == RegistrationRequest::RESPONSE_PARSING_FAILED; | 72 status == RegistrationRequest::RESPONSE_PARSING_FAILED; |
72 } | 73 } |
73 | 74 |
74 } // namespace | 75 } // namespace |
75 | 76 |
76 RegistrationRequest::RequestInfo::RequestInfo(uint64_t android_id, | 77 RegistrationRequest::RequestInfo::RequestInfo(uint64_t android_id, |
77 uint64_t security_token, | 78 uint64_t security_token, |
78 const std::string& app_id) | 79 const std::string& category, |
79 : android_id(android_id), security_token(security_token), app_id(app_id) { | 80 const std::string& subtype) |
81 : android_id(android_id), | |
82 security_token(security_token), | |
83 category(category), | |
84 subtype(subtype) { | |
80 DCHECK(android_id != 0UL); | 85 DCHECK(android_id != 0UL); |
81 DCHECK(security_token != 0UL); | 86 DCHECK(security_token != 0UL); |
87 DCHECK(!category.empty()); | |
82 } | 88 } |
83 | 89 |
84 RegistrationRequest::RequestInfo::~RequestInfo() {} | 90 RegistrationRequest::RequestInfo::~RequestInfo() {} |
85 | 91 |
86 RegistrationRequest::CustomRequestHandler::CustomRequestHandler() {} | 92 RegistrationRequest::CustomRequestHandler::CustomRequestHandler() {} |
87 | 93 |
88 RegistrationRequest::CustomRequestHandler::~CustomRequestHandler() {} | 94 RegistrationRequest::CustomRequestHandler::~CustomRequestHandler() {} |
89 | 95 |
90 RegistrationRequest::RegistrationRequest( | 96 RegistrationRequest::RegistrationRequest( |
91 const GURL& registration_url, | 97 const GURL& registration_url, |
(...skipping 30 matching lines...) Expand all Loading... | |
122 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 128 url_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
123 net::LOAD_DO_NOT_SAVE_COOKIES); | 129 net::LOAD_DO_NOT_SAVE_COOKIES); |
124 | 130 |
125 std::string extra_headers; | 131 std::string extra_headers; |
126 BuildRequestHeaders(&extra_headers); | 132 BuildRequestHeaders(&extra_headers); |
127 url_fetcher_->SetExtraRequestHeaders(extra_headers); | 133 url_fetcher_->SetExtraRequestHeaders(extra_headers); |
128 | 134 |
129 std::string body; | 135 std::string body; |
130 BuildRequestBody(&body); | 136 BuildRequestBody(&body); |
131 | 137 |
132 DVLOG(1) << "Performing registration for: " << request_info_.app_id; | 138 DVLOG(1) << "Performing registration for: " << request_info_.app_id(); |
133 DVLOG(1) << "Registration request: " << body; | 139 DVLOG(1) << "Registration request: " << body; |
134 url_fetcher_->SetUploadData(kRegistrationRequestContentType, body); | 140 url_fetcher_->SetUploadData(kRegistrationRequestContentType, body); |
135 recorder_->RecordRegistrationSent(request_info_.app_id, source_to_record_); | 141 recorder_->RecordRegistrationSent(request_info_.app_id(), source_to_record_); |
136 request_start_time_ = base::TimeTicks::Now(); | 142 request_start_time_ = base::TimeTicks::Now(); |
137 url_fetcher_->Start(); | 143 url_fetcher_->Start(); |
138 } | 144 } |
139 | 145 |
140 void RegistrationRequest::BuildRequestHeaders(std::string* extra_headers) { | 146 void RegistrationRequest::BuildRequestHeaders(std::string* extra_headers) { |
141 net::HttpRequestHeaders headers; | 147 net::HttpRequestHeaders headers; |
142 headers.SetHeader( | 148 headers.SetHeader( |
143 net::HttpRequestHeaders::kAuthorization, | 149 net::HttpRequestHeaders::kAuthorization, |
144 std::string(kLoginHeader) + " " + | 150 std::string(kLoginHeader) + " " + |
145 base::Uint64ToString(request_info_.android_id) + ":" + | 151 base::Uint64ToString(request_info_.android_id) + ":" + |
146 base::Uint64ToString(request_info_.security_token)); | 152 base::Uint64ToString(request_info_.security_token)); |
147 *extra_headers = headers.ToString(); | 153 *extra_headers = headers.ToString(); |
148 } | 154 } |
149 | 155 |
150 void RegistrationRequest::BuildRequestBody(std::string* body) { | 156 void RegistrationRequest::BuildRequestBody(std::string* body) { |
151 BuildFormEncoding(kAppIdKey, request_info_.app_id, body); | 157 BuildFormEncoding(kCategoryKey, request_info_.category, body); |
158 if (!request_info_.subtype.empty()) | |
Nicolas Zea
2016/08/17 20:54:09
nit: make this an if/else?
johnme
2016/08/18 17:43:21
|subtype| is an additional field that is sent if n
| |
159 BuildFormEncoding(kSubtypeKey, request_info_.subtype, body); | |
160 | |
152 BuildFormEncoding(kDeviceIdKey, | 161 BuildFormEncoding(kDeviceIdKey, |
153 base::Uint64ToString(request_info_.android_id), | 162 base::Uint64ToString(request_info_.android_id), |
154 body); | 163 body); |
155 | 164 |
156 DCHECK(custom_request_handler_.get()); | 165 DCHECK(custom_request_handler_.get()); |
157 custom_request_handler_->BuildRequestBody(body); | 166 custom_request_handler_->BuildRequestBody(body); |
158 } | 167 } |
159 | 168 |
160 void RegistrationRequest::RetryWithBackoff() { | 169 void RegistrationRequest::RetryWithBackoff() { |
161 DCHECK_GT(retries_left_, 0); | 170 DCHECK_GT(retries_left_, 0); |
162 --retries_left_; | 171 --retries_left_; |
163 url_fetcher_.reset(); | 172 url_fetcher_.reset(); |
164 backoff_entry_.InformOfRequest(false); | 173 backoff_entry_.InformOfRequest(false); |
165 | 174 |
166 DVLOG(1) << "Delaying GCM registration of app: " | 175 DVLOG(1) << "Delaying GCM registration of app: " << request_info_.app_id() |
167 << request_info_.app_id << ", for " | 176 << ", for " << backoff_entry_.GetTimeUntilRelease().InMilliseconds() |
168 << backoff_entry_.GetTimeUntilRelease().InMilliseconds() | |
169 << " milliseconds."; | 177 << " milliseconds."; |
170 recorder_->RecordRegistrationRetryDelayed( | 178 recorder_->RecordRegistrationRetryDelayed( |
171 request_info_.app_id, | 179 request_info_.app_id(), source_to_record_, |
172 source_to_record_, | 180 backoff_entry_.GetTimeUntilRelease().InMilliseconds(), retries_left_ + 1); |
173 backoff_entry_.GetTimeUntilRelease().InMilliseconds(), | |
174 retries_left_ + 1); | |
175 DCHECK(!weak_ptr_factory_.HasWeakPtrs()); | 181 DCHECK(!weak_ptr_factory_.HasWeakPtrs()); |
176 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 182 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
177 FROM_HERE, | 183 FROM_HERE, |
178 base::Bind(&RegistrationRequest::Start, weak_ptr_factory_.GetWeakPtr()), | 184 base::Bind(&RegistrationRequest::Start, weak_ptr_factory_.GetWeakPtr()), |
179 backoff_entry_.GetTimeUntilRelease()); | 185 backoff_entry_.GetTimeUntilRelease()); |
180 } | 186 } |
181 | 187 |
182 RegistrationRequest::Status RegistrationRequest::ParseResponse( | 188 RegistrationRequest::Status RegistrationRequest::ParseResponse( |
183 const net::URLFetcher* source, std::string* token) { | 189 const net::URLFetcher* source, std::string* token) { |
184 if (!source->GetStatus().is_success()) { | 190 if (!source->GetStatus().is_success()) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
216 << source->GetResponseCode(); | 222 << source->GetResponseCode(); |
217 return HTTP_NOT_OK; | 223 return HTTP_NOT_OK; |
218 } | 224 } |
219 | 225 |
220 return UNKNOWN_ERROR; | 226 return UNKNOWN_ERROR; |
221 } | 227 } |
222 | 228 |
223 void RegistrationRequest::OnURLFetchComplete(const net::URLFetcher* source) { | 229 void RegistrationRequest::OnURLFetchComplete(const net::URLFetcher* source) { |
224 std::string token; | 230 std::string token; |
225 Status status = ParseResponse(source, &token); | 231 Status status = ParseResponse(source, &token); |
226 recorder_->RecordRegistrationResponse( | 232 recorder_->RecordRegistrationResponse(request_info_.app_id(), |
227 request_info_.app_id, | 233 source_to_record_, status); |
228 source_to_record_, | |
229 status); | |
230 | 234 |
231 DCHECK(custom_request_handler_.get()); | 235 DCHECK(custom_request_handler_.get()); |
232 custom_request_handler_->ReportUMAs( | 236 custom_request_handler_->ReportUMAs( |
233 status, | 237 status, |
234 backoff_entry_.failure_count(), | 238 backoff_entry_.failure_count(), |
235 base::TimeTicks::Now() - request_start_time_); | 239 base::TimeTicks::Now() - request_start_time_); |
236 | 240 |
237 if (ShouldRetryWithStatus(status)) { | 241 if (ShouldRetryWithStatus(status)) { |
238 if (retries_left_ > 0) { | 242 if (retries_left_ > 0) { |
239 RetryWithBackoff(); | 243 RetryWithBackoff(); |
240 return; | 244 return; |
241 } | 245 } |
242 | 246 |
243 status = REACHED_MAX_RETRIES; | 247 status = REACHED_MAX_RETRIES; |
244 recorder_->RecordRegistrationResponse( | 248 recorder_->RecordRegistrationResponse(request_info_.app_id(), |
245 request_info_.app_id, | 249 source_to_record_, status); |
246 source_to_record_, | |
247 status); | |
248 | 250 |
249 // Only REACHED_MAX_RETRIES is reported because the function will skip | 251 // Only REACHED_MAX_RETRIES is reported because the function will skip |
250 // reporting count and time when status is not SUCCESS. | 252 // reporting count and time when status is not SUCCESS. |
251 DCHECK(custom_request_handler_.get()); | 253 DCHECK(custom_request_handler_.get()); |
252 custom_request_handler_->ReportUMAs(status, 0, base::TimeDelta()); | 254 custom_request_handler_->ReportUMAs(status, 0, base::TimeDelta()); |
253 } | 255 } |
254 | 256 |
255 callback_.Run(status, token); | 257 callback_.Run(status, token); |
256 } | 258 } |
257 | 259 |
258 } // namespace gcm | 260 } // namespace gcm |
OLD | NEW |