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

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: resolve conflicts. 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 15
15 namespace gcm { 16 namespace gcm {
16 17
17 namespace { 18 namespace {
18 const char kRequestContentType[] = "application/x-protobuf"; 19 const char kRequestContentType[] = "application/x-protobuf";
19 const int kRequestVersionValue = 2; 20 const int kRequestVersionValue = 2;
20 const int kDefaultUserSerialNumber = 0; 21 const int kDefaultUserSerialNumber = 0;
21 22
22 // This enum is also used in an UMA histogram (GCMCheckinRequestStatus 23 // This enum is also used in an UMA histogram (GCMCheckinRequestStatus
23 // enum defined in tools/metrics/histograms/histogram.xml). Hence the entries 24 // enum defined in tools/metrics/histograms/histogram.xml). Hence the entries
24 // here shouldn't be deleted or re-ordered and new ones should be added to 25 // here shouldn't be deleted or re-ordered and new ones should be added to
25 // the end. 26 // the end, and update the GetCheckinRequestStatusString(...) below.
26 enum CheckinRequestStatus { 27 enum CheckinRequestStatus {
27 SUCCESS, // Checkin completed successfully. 28 SUCCESS, // Checkin completed successfully.
28 URL_FETCHING_FAILED, // URL fetching failed. 29 URL_FETCHING_FAILED, // URL fetching failed.
29 HTTP_BAD_REQUEST, // The request was malformed. 30 HTTP_BAD_REQUEST, // The request was malformed.
30 HTTP_UNAUTHORIZED, // The security token didn't match the android id. 31 HTTP_UNAUTHORIZED, // The security token didn't match the android id.
31 HTTP_NOT_OK, // HTTP status was not OK. 32 HTTP_NOT_OK, // HTTP status was not OK.
32 RESPONSE_PARSING_FAILED, // Check in response parsing failed. 33 RESPONSE_PARSING_FAILED, // Check in response parsing failed.
33 ZERO_ID_OR_TOKEN, // Either returned android id or security token 34 ZERO_ID_OR_TOKEN, // Either returned android id or security token
34 // was zero. 35 // was zero.
35 // NOTE: always keep this entry at the end. Add new status types only 36 // NOTE: always keep this entry at the end. Add new status types only
36 // immediately above this line. Make sure to update the corresponding 37 // immediately above this line. Make sure to update the corresponding
37 // histogram enum accordingly. 38 // histogram enum accordingly.
38 STATUS_COUNT 39 STATUS_COUNT
39 }; 40 };
40 41
41 void RecordCheckinStatusToUMA(CheckinRequestStatus status) { 42 // Returns string representation of enum CheckinRequestStatus.
43 std::string GetCheckinRequestStatusString(CheckinRequestStatus status) {
44 switch (status) {
45 case SUCCESS:
46 return "SUCCESS";
47 case URL_FETCHING_FAILED:
48 return "URL_FETCHING_FAILED";
49 case HTTP_BAD_REQUEST:
50 return "HTTP_BAD_REQUEST";
51 case HTTP_UNAUTHORIZED:
52 return "HTTP_UNAUTHORIZED";
53 case HTTP_NOT_OK:
54 return "HTTP_NOT_OK";
55 case RESPONSE_PARSING_FAILED:
56 return "RESPONSE_PARSING_FAILED";
57 case ZERO_ID_OR_TOKEN:
58 return "ZERO_ID_OR_TOKEN";
59 default:
60 NOTREACHED();
61 return "UNKNOWN_STATUS";
62 }
63 }
64
65 // Records checkin status to both stats recorder and reports to UMA.
66 void RecordCheckinStatusAndReportUMA(CheckinRequestStatus status,
67 GCMStatsRecorder* recorder,
68 bool will_retry) {
42 UMA_HISTOGRAM_ENUMERATION("GCM.CheckinRequestStatus", status, STATUS_COUNT); 69 UMA_HISTOGRAM_ENUMERATION("GCM.CheckinRequestStatus", status, STATUS_COUNT);
70 if (status == SUCCESS)
71 recorder->RecordCheckinSuccess();
72 else {
73 recorder->RecordCheckinFailure(GetCheckinRequestStatusString(status),
74 will_retry);
75 }
43 } 76 }
44 77
45 } // namespace 78 } // namespace
46 79
47 CheckinRequest::RequestInfo::RequestInfo( 80 CheckinRequest::RequestInfo::RequestInfo(
48 uint64 android_id, 81 uint64 android_id,
49 uint64 security_token, 82 uint64 security_token,
50 const std::string& settings_digest, 83 const std::string& settings_digest,
51 const std::vector<std::string>& account_ids, 84 const std::vector<std::string>& account_ids,
52 const checkin_proto::ChromeBuildProto& chrome_build_proto) 85 const checkin_proto::ChromeBuildProto& chrome_build_proto)
53 : android_id(android_id), 86 : android_id(android_id),
54 security_token(security_token), 87 security_token(security_token),
55 settings_digest(settings_digest), 88 settings_digest(settings_digest),
56 account_ids(account_ids), 89 account_ids(account_ids),
57 chrome_build_proto(chrome_build_proto) { 90 chrome_build_proto(chrome_build_proto) {
58 } 91 }
59 92
60 CheckinRequest::RequestInfo::~RequestInfo() {} 93 CheckinRequest::RequestInfo::~RequestInfo() {}
61 94
62 CheckinRequest::CheckinRequest( 95 CheckinRequest::CheckinRequest(
63 const GURL& checkin_url, 96 const GURL& checkin_url,
64 const RequestInfo& request_info, 97 const RequestInfo& request_info,
65 const net::BackoffEntry::Policy& backoff_policy, 98 const net::BackoffEntry::Policy& backoff_policy,
66 const CheckinRequestCallback& callback, 99 const CheckinRequestCallback& callback,
67 net::URLRequestContextGetter* request_context_getter) 100 net::URLRequestContextGetter* request_context_getter,
101 GCMStatsRecorder* recorder)
68 : request_context_getter_(request_context_getter), 102 : request_context_getter_(request_context_getter),
69 callback_(callback), 103 callback_(callback),
70 backoff_entry_(&backoff_policy), 104 backoff_entry_(&backoff_policy),
71 checkin_url_(checkin_url), 105 checkin_url_(checkin_url),
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(checkin_url_, net::URLFetcher::POST, this)); 143 net::URLFetcher::Create(checkin_url_, 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