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

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