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

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: Addressing jian's comments. 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
43 void RecordCheckinStatusToUMA(CheckinRequestStatus status) { 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
67 // Record checkin failure status to both stats recorder and to UMA.
jianli 2014/05/01 23:02:37 nit: please update comment
juyik 2014/05/02 00:41:54 Done.
68 void RecordCheckinStatusAndReportUMA(CheckinRequestStatus status,
69 GCMStatsRecorder* recorder,
70 bool will_retry) {
44 UMA_HISTOGRAM_ENUMERATION("GCM.CheckinRequestStatus", status, STATUS_COUNT); 71 UMA_HISTOGRAM_ENUMERATION("GCM.CheckinRequestStatus", status, STATUS_COUNT);
72 if (status == SUCCESS)
73 recorder->RecordCheckinSuccess();
74 else {
75 recorder->RecordCheckinFailure(GetCheckinRequestStatusString(status),
76 will_retry);
77 }
45 } 78 }
46 79
47 } // namespace 80 } // namespace
48 81
49 CheckinRequest::RequestInfo::RequestInfo( 82 CheckinRequest::RequestInfo::RequestInfo(
50 uint64 android_id, 83 uint64 android_id,
51 uint64 security_token, 84 uint64 security_token,
52 const std::string& settings_digest, 85 const std::string& settings_digest,
53 const std::vector<std::string>& account_ids, 86 const std::vector<std::string>& account_ids,
54 const checkin_proto::ChromeBuildProto& chrome_build_proto) 87 const checkin_proto::ChromeBuildProto& chrome_build_proto)
55 : android_id(android_id), 88 : android_id(android_id),
56 security_token(security_token), 89 security_token(security_token),
57 settings_digest(settings_digest), 90 settings_digest(settings_digest),
58 account_ids(account_ids), 91 account_ids(account_ids),
59 chrome_build_proto(chrome_build_proto) { 92 chrome_build_proto(chrome_build_proto) {
60 } 93 }
61 94
62 CheckinRequest::RequestInfo::~RequestInfo() {} 95 CheckinRequest::RequestInfo::~RequestInfo() {}
63 96
64 CheckinRequest::CheckinRequest( 97 CheckinRequest::CheckinRequest(
65 const RequestInfo& request_info, 98 const RequestInfo& request_info,
66 const net::BackoffEntry::Policy& backoff_policy, 99 const net::BackoffEntry::Policy& backoff_policy,
67 const CheckinRequestCallback& callback, 100 const CheckinRequestCallback& callback,
68 net::URLRequestContextGetter* request_context_getter) 101 net::URLRequestContextGetter* request_context_getter,
102 GCMStatsRecorder* recorder)
69 : request_context_getter_(request_context_getter), 103 : request_context_getter_(request_context_getter),
70 callback_(callback), 104 callback_(callback),
71 backoff_entry_(&backoff_policy), 105 backoff_entry_(&backoff_policy),
72 request_info_(request_info), 106 request_info_(request_info),
107 recorder_(recorder),
73 weak_ptr_factory_(this) { 108 weak_ptr_factory_(this) {
74 } 109 }
75 110
76 CheckinRequest::~CheckinRequest() {} 111 CheckinRequest::~CheckinRequest() {}
77 112
78 void CheckinRequest::Start() { 113 void CheckinRequest::Start() {
79 DCHECK(!url_fetcher_.get()); 114 DCHECK(!url_fetcher_.get());
80 115
81 checkin_proto::AndroidCheckinRequest request; 116 checkin_proto::AndroidCheckinRequest request;
82 request.set_id(request_info_.android_id); 117 request.set_id(request_info_.android_id);
(...skipping 18 matching lines...) Expand all
101 request.add_account_cookie("[" + *iter + "]"); 136 request.add_account_cookie("[" + *iter + "]");
102 } 137 }
103 138
104 std::string upload_data; 139 std::string upload_data;
105 CHECK(request.SerializeToString(&upload_data)); 140 CHECK(request.SerializeToString(&upload_data));
106 141
107 url_fetcher_.reset( 142 url_fetcher_.reset(
108 net::URLFetcher::Create(GURL(kCheckinURL), net::URLFetcher::POST, this)); 143 net::URLFetcher::Create(GURL(kCheckinURL), net::URLFetcher::POST, this));
109 url_fetcher_->SetRequestContext(request_context_getter_); 144 url_fetcher_->SetRequestContext(request_context_getter_);
110 url_fetcher_->SetUploadData(kRequestContentType, upload_data); 145 url_fetcher_->SetUploadData(kRequestContentType, upload_data);
146 recorder_->RecordCheckinInitiated(request_info_.android_id);
111 url_fetcher_->Start(); 147 url_fetcher_->Start();
112 } 148 }
113 149
114 void CheckinRequest::RetryWithBackoff(bool update_backoff) { 150 void CheckinRequest::RetryWithBackoff(bool update_backoff) {
115 if (update_backoff) { 151 if (update_backoff) {
116 backoff_entry_.InformOfRequest(false); 152 backoff_entry_.InformOfRequest(false);
117 url_fetcher_.reset(); 153 url_fetcher_.reset();
118 } 154 }
119 155
120 if (backoff_entry_.ShouldRejectRequest()) { 156 if (backoff_entry_.ShouldRejectRequest()) {
121 DVLOG(1) << "Delay GCM checkin for: " 157 DVLOG(1) << "Delay GCM checkin for: "
122 << backoff_entry_.GetTimeUntilRelease().InMilliseconds() 158 << backoff_entry_.GetTimeUntilRelease().InMilliseconds()
123 << " milliseconds."; 159 << " milliseconds.";
160 recorder_->RecordCheckinDelayedDueToBackoff(
161 backoff_entry_.GetTimeUntilRelease().InMilliseconds());
124 base::MessageLoop::current()->PostDelayedTask( 162 base::MessageLoop::current()->PostDelayedTask(
125 FROM_HERE, 163 FROM_HERE,
126 base::Bind(&CheckinRequest::RetryWithBackoff, 164 base::Bind(&CheckinRequest::RetryWithBackoff,
127 weak_ptr_factory_.GetWeakPtr(), 165 weak_ptr_factory_.GetWeakPtr(),
128 false), 166 false),
129 backoff_entry_.GetTimeUntilRelease()); 167 backoff_entry_.GetTimeUntilRelease());
130 return; 168 return;
131 } 169 }
132 170
133 Start(); 171 Start();
134 } 172 }
135 173
136 void CheckinRequest::OnURLFetchComplete(const net::URLFetcher* source) { 174 void CheckinRequest::OnURLFetchComplete(const net::URLFetcher* source) {
137 std::string response_string; 175 std::string response_string;
138 checkin_proto::AndroidCheckinResponse response_proto; 176 checkin_proto::AndroidCheckinResponse response_proto;
139 if (!source->GetStatus().is_success()) { 177 if (!source->GetStatus().is_success()) {
140 LOG(ERROR) << "Failed to get checkin response. Fetcher failed. Retrying."; 178 LOG(ERROR) << "Failed to get checkin response. Fetcher failed. Retrying.";
141 RecordCheckinStatusToUMA(URL_FETCHING_FAILED); 179 RecordCheckinStatusAndReportUMA(URL_FETCHING_FAILED, recorder_, true);
142 RetryWithBackoff(true); 180 RetryWithBackoff(true);
143 return; 181 return;
144 } 182 }
145 183
146 net::HttpStatusCode response_status = static_cast<net::HttpStatusCode>( 184 net::HttpStatusCode response_status = static_cast<net::HttpStatusCode>(
147 source->GetResponseCode()); 185 source->GetResponseCode());
148 if (response_status == net::HTTP_BAD_REQUEST || 186 if (response_status == net::HTTP_BAD_REQUEST ||
149 response_status == net::HTTP_UNAUTHORIZED) { 187 response_status == net::HTTP_UNAUTHORIZED) {
150 // BAD_REQUEST indicates that the request was malformed. 188 // BAD_REQUEST indicates that the request was malformed.
151 // UNAUTHORIZED indicates that security token didn't match the android id. 189 // UNAUTHORIZED indicates that security token didn't match the android id.
152 LOG(ERROR) << "No point retrying the checkin with status: " 190 LOG(ERROR) << "No point retrying the checkin with status: "
153 << response_status << ". Checkin failed."; 191 << response_status << ". Checkin failed.";
154 RecordCheckinStatusToUMA(response_status == net::HTTP_BAD_REQUEST ? 192 CheckinRequestStatus status = response_status == net::HTTP_BAD_REQUEST ?
155 HTTP_BAD_REQUEST : HTTP_UNAUTHORIZED); 193 HTTP_BAD_REQUEST : HTTP_UNAUTHORIZED;
194 RecordCheckinStatusAndReportUMA(status, recorder_, false);
156 callback_.Run(response_proto); 195 callback_.Run(response_proto);
157 return; 196 return;
158 } 197 }
159 198
160 if (response_status != net::HTTP_OK || 199 if (response_status != net::HTTP_OK ||
161 !source->GetResponseAsString(&response_string) || 200 !source->GetResponseAsString(&response_string) ||
162 !response_proto.ParseFromString(response_string)) { 201 !response_proto.ParseFromString(response_string)) {
163 LOG(ERROR) << "Failed to get checkin response. HTTP Status: " 202 LOG(ERROR) << "Failed to get checkin response. HTTP Status: "
164 << response_status << ". Retrying."; 203 << response_status << ". Retrying.";
165 RecordCheckinStatusToUMA(response_status != net::HTTP_OK ? 204 CheckinRequestStatus status = response_status != net::HTTP_OK ?
166 HTTP_NOT_OK : RESPONSE_PARSING_FAILED); 205 HTTP_NOT_OK : RESPONSE_PARSING_FAILED;
206 RecordCheckinStatusAndReportUMA(status, recorder_, true);
167 RetryWithBackoff(true); 207 RetryWithBackoff(true);
168 return; 208 return;
169 } 209 }
170 210
171 if (!response_proto.has_android_id() || 211 if (!response_proto.has_android_id() ||
172 !response_proto.has_security_token() || 212 !response_proto.has_security_token() ||
173 response_proto.android_id() == 0 || 213 response_proto.android_id() == 0 ||
174 response_proto.security_token() == 0) { 214 response_proto.security_token() == 0) {
175 LOG(ERROR) << "Android ID or security token is 0. Retrying."; 215 LOG(ERROR) << "Android ID or security token is 0. Retrying.";
176 RecordCheckinStatusToUMA(ZERO_ID_OR_TOKEN); 216 RecordCheckinStatusAndReportUMA(ZERO_ID_OR_TOKEN, recorder_, true);
177 RetryWithBackoff(true); 217 RetryWithBackoff(true);
178 return; 218 return;
179 } 219 }
180 220
181 RecordCheckinStatusToUMA(SUCCESS); 221 RecordCheckinStatusAndReportUMA(SUCCESS, recorder_, false);
182 callback_.Run(response_proto); 222 callback_.Run(response_proto);
183 } 223 }
184 224
185 } // namespace gcm 225 } // namespace gcm
OLDNEW
« no previous file with comments | « google_apis/gcm/engine/checkin_request.h ('k') | google_apis/gcm/engine/checkin_request_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698