Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(140)

Side by Side Diff: google_apis/gcm/engine/checkin_request.cc

Issue 261573002: Add checkin activity recording to gcm recorder. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/checkin_request.h" 5 #include "google_apis/gcm/engine/checkin_request.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "google_apis/gcm/monitoring/gcm_stats_recorder.h"
10 #include "google_apis/gcm/protocol/checkin.pb.h" 11 #include "google_apis/gcm/protocol/checkin.pb.h"
11 #include "net/http/http_status_code.h" 12 #include "net/http/http_status_code.h"
12 #include "net/url_request/url_fetcher.h" 13 #include "net/url_request/url_fetcher.h"
13 #include "net/url_request/url_request_status.h" 14 #include "net/url_request/url_request_status.h"
14 #include "url/gurl.h" 15 #include "url/gurl.h"
15 16
16 namespace gcm { 17 namespace gcm {
17 18
18 namespace { 19 namespace {
19 const char kCheckinURL[] = "https://android.clients.google.com/checkin"; 20 const char kCheckinURL[] = "https://android.clients.google.com/checkin";
20 const char kRequestContentType[] = "application/x-protobuf"; 21 const char kRequestContentType[] = "application/x-protobuf";
21 const int kRequestVersionValue = 2; 22 const int kRequestVersionValue = 2;
22 const int kDefaultUserSerialNumber = 0; 23 const int kDefaultUserSerialNumber = 0;
23 24
24 // This enum is also used in an UMA histogram (GCMCheckinRequestStatus 25 // This enum is also used in an UMA histogram (GCMCheckinRequestStatus
25 // enum defined in tools/metrics/histograms/histogram.xml). Hence the entries 26 // enum defined in tools/metrics/histograms/histogram.xml). Hence the entries
26 // here shouldn't be deleted or re-ordered and new ones should be added to 27 // here shouldn't be deleted or re-ordered and new ones should be added to
27 // the end. 28 // the end, and update the GetCheckinRequestStatusString(...) below.
28 enum CheckinRequestStatus { 29 enum CheckinRequestStatus {
29 SUCCESS, // Checkin completed successfully. 30 SUCCESS, // Checkin completed successfully.
30 URL_FETCHING_FAILED, // URL fetching failed. 31 URL_FETCHING_FAILED, // URL fetching failed.
31 HTTP_BAD_REQUEST, // The request was malformed. 32 HTTP_BAD_REQUEST, // The request was malformed.
32 HTTP_UNAUTHORIZED, // The security token didn't match the android id. 33 HTTP_UNAUTHORIZED, // The security token didn't match the android id.
33 HTTP_NOT_OK, // HTTP status was not OK. 34 HTTP_NOT_OK, // HTTP status was not OK.
34 RESPONSE_PARSING_FAILED, // Check in response parsing failed. 35 RESPONSE_PARSING_FAILED, // Check in response parsing failed.
35 ZERO_ID_OR_TOKEN, // Either returned android id or security token 36 ZERO_ID_OR_TOKEN, // Either returned android id or security token
36 // was zero. 37 // was zero.
37 // NOTE: always keep this entry at the end. Add new status types only 38 // NOTE: always keep this entry at the end. Add new status types only
38 // immediately above this line. Make sure to update the corresponding 39 // immediately above this line. Make sure to update the corresponding
39 // histogram enum accordingly. 40 // histogram enum accordingly.
40 STATUS_COUNT 41 STATUS_COUNT
41 }; 42 };
42 43
44 // Returns string representation of enum CheckinRequestStatus.
45 std::string GetCheckinRequestStatusString(CheckinRequestStatus status) {
46 switch (status) {
47 case SUCCESS:
48 return "SUCCESS";
49 case URL_FETCHING_FAILED:
50 return "URL_FETCHING_FAILED";
51 case HTTP_BAD_REQUEST:
52 return "HTTP_BAD_REQUEST";
53 case HTTP_UNAUTHORIZED:
54 return "HTTP_UNAUTHORIZED";
55 case HTTP_NOT_OK:
56 return "HTTP_NOT_OK";
57 case RESPONSE_PARSING_FAILED:
58 return "RESPONSE_PARSING_FAILED";
59 case ZERO_ID_OR_TOKEN:
60 return "ZERO_ID_OR_TOKEN";
61 default:
62 NOTREACHED();
63 return "UNKNOWN_STATUS";
64 }
65 }
66
43 void RecordCheckinStatusToUMA(CheckinRequestStatus status) { 67 void RecordCheckinStatusToUMA(CheckinRequestStatus status) {
44 UMA_HISTOGRAM_ENUMERATION("GCM.CheckinRequestStatus", status, STATUS_COUNT); 68 UMA_HISTOGRAM_ENUMERATION("GCM.CheckinRequestStatus", status, STATUS_COUNT);
45 } 69 }
46 70
47 } // namespace 71 } // namespace
48 72
49 CheckinRequest::RequestInfo::RequestInfo( 73 CheckinRequest::RequestInfo::RequestInfo(
50 uint64 android_id, 74 uint64 android_id,
51 uint64 security_token, 75 uint64 security_token,
52 const std::string& settings_digest, 76 const std::string& settings_digest,
53 const std::vector<std::string>& account_ids, 77 const std::vector<std::string>& account_ids,
54 const checkin_proto::ChromeBuildProto& chrome_build_proto) 78 const checkin_proto::ChromeBuildProto& chrome_build_proto)
55 : android_id(android_id), 79 : android_id(android_id),
56 security_token(security_token), 80 security_token(security_token),
57 settings_digest(settings_digest), 81 settings_digest(settings_digest),
58 account_ids(account_ids), 82 account_ids(account_ids),
59 chrome_build_proto(chrome_build_proto) { 83 chrome_build_proto(chrome_build_proto) {
60 } 84 }
61 85
62 CheckinRequest::RequestInfo::~RequestInfo() {} 86 CheckinRequest::RequestInfo::~RequestInfo() {}
63 87
64 CheckinRequest::CheckinRequest( 88 CheckinRequest::CheckinRequest(
65 const RequestInfo& request_info, 89 const RequestInfo& request_info,
66 const net::BackoffEntry::Policy& backoff_policy, 90 const net::BackoffEntry::Policy& backoff_policy,
67 const CheckinRequestCallback& callback, 91 const CheckinRequestCallback& callback,
68 net::URLRequestContextGetter* request_context_getter) 92 net::URLRequestContextGetter* request_context_getter,
93 GCMStatsRecorder* recorder)
69 : request_context_getter_(request_context_getter), 94 : request_context_getter_(request_context_getter),
70 callback_(callback), 95 callback_(callback),
71 backoff_entry_(&backoff_policy), 96 backoff_entry_(&backoff_policy),
72 request_info_(request_info), 97 request_info_(request_info),
98 recorder_(recorder),
73 weak_ptr_factory_(this) { 99 weak_ptr_factory_(this) {
74 } 100 }
75 101
76 CheckinRequest::~CheckinRequest() {} 102 CheckinRequest::~CheckinRequest() {}
77 103
78 void CheckinRequest::Start() { 104 void CheckinRequest::Start() {
79 DCHECK(!url_fetcher_.get()); 105 DCHECK(!url_fetcher_.get());
80 106
81 checkin_proto::AndroidCheckinRequest request; 107 checkin_proto::AndroidCheckinRequest request;
82 request.set_id(request_info_.android_id); 108 request.set_id(request_info_.android_id);
(...skipping 18 matching lines...) Expand all
101 request.add_account_cookie("[" + *iter + "]"); 127 request.add_account_cookie("[" + *iter + "]");
102 } 128 }
103 129
104 std::string upload_data; 130 std::string upload_data;
105 CHECK(request.SerializeToString(&upload_data)); 131 CHECK(request.SerializeToString(&upload_data));
106 132
107 url_fetcher_.reset( 133 url_fetcher_.reset(
108 net::URLFetcher::Create(GURL(kCheckinURL), net::URLFetcher::POST, this)); 134 net::URLFetcher::Create(GURL(kCheckinURL), net::URLFetcher::POST, this));
109 url_fetcher_->SetRequestContext(request_context_getter_); 135 url_fetcher_->SetRequestContext(request_context_getter_);
110 url_fetcher_->SetUploadData(kRequestContentType, upload_data); 136 url_fetcher_->SetUploadData(kRequestContentType, upload_data);
137 recorder_->RecordCheckinInitiated(request_info_.android_id);
111 url_fetcher_->Start(); 138 url_fetcher_->Start();
112 } 139 }
113 140
114 void CheckinRequest::RetryWithBackoff(bool update_backoff) { 141 void CheckinRequest::RetryWithBackoff(bool update_backoff) {
115 if (update_backoff) { 142 if (update_backoff) {
116 backoff_entry_.InformOfRequest(false); 143 backoff_entry_.InformOfRequest(false);
117 url_fetcher_.reset(); 144 url_fetcher_.reset();
118 } 145 }
119 146
120 if (backoff_entry_.ShouldRejectRequest()) { 147 if (backoff_entry_.ShouldRejectRequest()) {
121 DVLOG(1) << "Delay GCM checkin for: " 148 DVLOG(1) << "Delay GCM checkin for: "
122 << backoff_entry_.GetTimeUntilRelease().InMilliseconds() 149 << backoff_entry_.GetTimeUntilRelease().InMilliseconds()
123 << " milliseconds."; 150 << " milliseconds.";
151 recorder_->RecordCheckinDelayedDueToBackoff(
152 backoff_entry_.GetTimeUntilRelease().InMilliseconds());
124 base::MessageLoop::current()->PostDelayedTask( 153 base::MessageLoop::current()->PostDelayedTask(
125 FROM_HERE, 154 FROM_HERE,
126 base::Bind(&CheckinRequest::RetryWithBackoff, 155 base::Bind(&CheckinRequest::RetryWithBackoff,
127 weak_ptr_factory_.GetWeakPtr(), 156 weak_ptr_factory_.GetWeakPtr(),
128 false), 157 false),
129 backoff_entry_.GetTimeUntilRelease()); 158 backoff_entry_.GetTimeUntilRelease());
130 return; 159 return;
131 } 160 }
132 161
133 Start(); 162 Start();
134 } 163 }
135 164
136 void CheckinRequest::OnURLFetchComplete(const net::URLFetcher* source) { 165 void CheckinRequest::OnURLFetchComplete(const net::URLFetcher* source) {
137 std::string response_string; 166 std::string response_string;
138 checkin_proto::AndroidCheckinResponse response_proto; 167 checkin_proto::AndroidCheckinResponse response_proto;
139 if (!source->GetStatus().is_success()) { 168 if (!source->GetStatus().is_success()) {
140 LOG(ERROR) << "Failed to get checkin response. Fetcher failed. Retrying."; 169 LOG(ERROR) << "Failed to get checkin response. Fetcher failed. Retrying.";
141 RecordCheckinStatusToUMA(URL_FETCHING_FAILED); 170 RecordCheckinStatusToUMA(URL_FETCHING_FAILED);
171 recorder_->RecordCheckinFailure(
jianli 2014/05/01 00:22:35 Can this be merged with RecordCheckinStatusToUMA?
juyik 2014/05/01 01:03:35 Done.
172 GetCheckinRequestStatusString(URL_FETCHING_FAILED), true);
142 RetryWithBackoff(true); 173 RetryWithBackoff(true);
143 return; 174 return;
144 } 175 }
145 176
146 net::HttpStatusCode response_status = static_cast<net::HttpStatusCode>( 177 net::HttpStatusCode response_status = static_cast<net::HttpStatusCode>(
147 source->GetResponseCode()); 178 source->GetResponseCode());
148 if (response_status == net::HTTP_BAD_REQUEST || 179 if (response_status == net::HTTP_BAD_REQUEST ||
149 response_status == net::HTTP_UNAUTHORIZED) { 180 response_status == net::HTTP_UNAUTHORIZED) {
150 // BAD_REQUEST indicates that the request was malformed. 181 // BAD_REQUEST indicates that the request was malformed.
151 // UNAUTHORIZED indicates that security token didn't match the android id. 182 // UNAUTHORIZED indicates that security token didn't match the android id.
152 LOG(ERROR) << "No point retrying the checkin with status: " 183 LOG(ERROR) << "No point retrying the checkin with status: "
153 << response_status << ". Checkin failed."; 184 << response_status << ". Checkin failed.";
154 RecordCheckinStatusToUMA(response_status == net::HTTP_BAD_REQUEST ? 185 CheckinRequestStatus status = response_status == net::HTTP_BAD_REQUEST ?
155 HTTP_BAD_REQUEST : HTTP_UNAUTHORIZED); 186 HTTP_BAD_REQUEST : HTTP_UNAUTHORIZED;
187 RecordCheckinStatusToUMA(status);
188 recorder_->RecordCheckinFailure(
189 GetCheckinRequestStatusString(status), false);
156 callback_.Run(response_proto); 190 callback_.Run(response_proto);
157 return; 191 return;
158 } 192 }
159 193
160 if (response_status != net::HTTP_OK || 194 if (response_status != net::HTTP_OK ||
161 !source->GetResponseAsString(&response_string) || 195 !source->GetResponseAsString(&response_string) ||
162 !response_proto.ParseFromString(response_string)) { 196 !response_proto.ParseFromString(response_string)) {
163 LOG(ERROR) << "Failed to get checkin response. HTTP Status: " 197 LOG(ERROR) << "Failed to get checkin response. HTTP Status: "
164 << response_status << ". Retrying."; 198 << response_status << ". Retrying.";
165 RecordCheckinStatusToUMA(response_status != net::HTTP_OK ? 199 CheckinRequestStatus status = response_status != net::HTTP_OK ?
166 HTTP_NOT_OK : RESPONSE_PARSING_FAILED); 200 HTTP_NOT_OK : RESPONSE_PARSING_FAILED;
201 RecordCheckinStatusToUMA(status);
202 recorder_->RecordCheckinFailure(
203 GetCheckinRequestStatusString(status), true);
167 RetryWithBackoff(true); 204 RetryWithBackoff(true);
168 return; 205 return;
169 } 206 }
170 207
171 if (!response_proto.has_android_id() || 208 if (!response_proto.has_android_id() ||
172 !response_proto.has_security_token() || 209 !response_proto.has_security_token() ||
173 response_proto.android_id() == 0 || 210 response_proto.android_id() == 0 ||
174 response_proto.security_token() == 0) { 211 response_proto.security_token() == 0) {
175 LOG(ERROR) << "Android ID or security token is 0. Retrying."; 212 LOG(ERROR) << "Android ID or security token is 0. Retrying.";
176 RecordCheckinStatusToUMA(ZERO_ID_OR_TOKEN); 213 RecordCheckinStatusToUMA(ZERO_ID_OR_TOKEN);
214 recorder_->RecordCheckinFailure(
215 GetCheckinRequestStatusString(ZERO_ID_OR_TOKEN), true);
177 RetryWithBackoff(true); 216 RetryWithBackoff(true);
178 return; 217 return;
179 } 218 }
180 219
181 RecordCheckinStatusToUMA(SUCCESS); 220 RecordCheckinStatusToUMA(SUCCESS);
221 recorder_->RecordCheckinSuccess();
182 callback_.Run(response_proto); 222 callback_.Run(response_proto);
183 } 223 }
184 224
185 } // namespace gcm 225 } // namespace gcm
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698