Chromium Code Reviews| 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 |