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

Side by Side Diff: content/browser/geolocation/network_location_request.cc

Issue 25262003: Geolocation: add UMA histograms for events and response codes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 7 years, 2 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
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/browser/geolocation/network_location_request.h" 5 #include "content/browser/geolocation/network_location_request.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 9
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
11 #include "base/json/json_writer.h" 11 #include "base/json/json_writer.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/metrics/sparse_histogram.h"
13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
14 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
15 #include "base/values.h" 16 #include "base/values.h"
16 #include "content/browser/geolocation/location_arbitrator_impl.h" 17 #include "content/browser/geolocation/location_arbitrator_impl.h"
17 #include "content/public/common/geoposition.h" 18 #include "content/public/common/geoposition.h"
18 #include "google_apis/google_api_keys.h" 19 #include "google_apis/google_api_keys.h"
19 #include "net/base/escape.h" 20 #include "net/base/escape.h"
20 #include "net/base/load_flags.h" 21 #include "net/base/load_flags.h"
21 #include "net/url_request/url_fetcher.h" 22 #include "net/url_request/url_fetcher.h"
22 #include "net/url_request/url_request_context_getter.h" 23 #include "net/url_request/url_request_context_getter.h"
23 #include "net/url_request/url_request_status.h" 24 #include "net/url_request/url_request_status.h"
24 25
25 namespace content { 26 namespace content {
26 namespace { 27 namespace {
27 28
28 const char kAccessTokenString[] = "accessToken"; 29 const char kAccessTokenString[] = "accessToken";
29 const char kLocationString[] = "location"; 30 const char kLocationString[] = "location";
30 const char kLatitudeString[] = "lat"; 31 const char kLatitudeString[] = "lat";
31 const char kLongitudeString[] = "lng"; 32 const char kLongitudeString[] = "lng";
32 const char kAccuracyString[] = "accuracy"; 33 const char kAccuracyString[] = "accuracy";
33 34
35 enum NetworkLocationRequestEvent {
36 // NOTE: Do not renumber these as that would confuse interpretation of
37 // previously logged data. When making changes, also update the enum list
38 // in tools/metrics/histograms/histograms.xml to keep it in sync.
39 NETWORK_LOCATION_REQUEST_EVENT_REQUEST_START = 0,
40 NETWORK_LOCATION_REQUEST_EVENT_REQUEST_CANCEL = 1,
41 NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_SUCCESS = 2,
42 NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_NOT_OK = 3,
43 NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_EMPTY = 4,
44 NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_MALFORMED = 5,
45 NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_INVALID_FIX = 6,
46
47 // NOTE: Add entries only immediately above this line.
48 NETWORK_LOCATION_REQUEST_EVENT_COUNT = 7
49 };
50
51 void RecordUmaEvent(NetworkLocationRequestEvent event) {
52 UMA_HISTOGRAM_ENUMERATION("Geolocation.NetworkLocationRequest.Event",
53 event, NETWORK_LOCATION_REQUEST_EVENT_COUNT);
54 }
55
56 void RecordUmaResponseCode(int code) {
57 UMA_HISTOGRAM_SPARSE_SLOWLY("Geolocation.NetworkLocationRequest.ResponseCode",
58 code);
59 }
60
34 // Local functions 61 // Local functions
35 // Creates the request url to send to the server. 62 // Creates the request url to send to the server.
36 GURL FormRequestURL(const GURL& url); 63 GURL FormRequestURL(const GURL& url);
37 64
38 void FormUploadData(const WifiData& wifi_data, 65 void FormUploadData(const WifiData& wifi_data,
39 const base::Time& timestamp, 66 const base::Time& timestamp,
40 const string16& access_token, 67 const string16& access_token,
41 std::string* upload_data); 68 std::string* upload_data);
42 69
43 // Parsers the server response. 70 // Attempts to extract a position from the response. Detects and indicates
71 // various failure cases.
44 void GetLocationFromResponse(bool http_post_result, 72 void GetLocationFromResponse(bool http_post_result,
45 int status_code, 73 int status_code,
46 const std::string& response_body, 74 const std::string& response_body,
47 const base::Time& timestamp, 75 const base::Time& timestamp,
48 const GURL& server_url, 76 const GURL& server_url,
49 Geoposition* position, 77 Geoposition* position,
50 string16* access_token); 78 string16* access_token);
51 79
52 // Parses the server response body. Returns true if parsing was successful. 80 // Parses the server response body. Returns true if parsing was successful.
53 // Sets |*position| to the parsed location if a valid fix was received, 81 // Sets |*position| to the parsed location if a valid fix was received,
(...skipping 17 matching lines...) Expand all
71 callback_(callback), 99 callback_(callback),
72 url_(url) { 100 url_(url) {
73 } 101 }
74 102
75 NetworkLocationRequest::~NetworkLocationRequest() { 103 NetworkLocationRequest::~NetworkLocationRequest() {
76 } 104 }
77 105
78 bool NetworkLocationRequest::MakeRequest(const string16& access_token, 106 bool NetworkLocationRequest::MakeRequest(const string16& access_token,
79 const WifiData& wifi_data, 107 const WifiData& wifi_data,
80 const base::Time& timestamp) { 108 const base::Time& timestamp) {
109 RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_REQUEST_START);
81 if (url_fetcher_ != NULL) { 110 if (url_fetcher_ != NULL) {
82 DVLOG(1) << "NetworkLocationRequest : Cancelling pending request"; 111 DVLOG(1) << "NetworkLocationRequest : Cancelling pending request";
112 RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_REQUEST_CANCEL);
83 url_fetcher_.reset(); 113 url_fetcher_.reset();
84 } 114 }
85 wifi_data_ = wifi_data; 115 wifi_data_ = wifi_data;
86 timestamp_ = timestamp; 116 timestamp_ = timestamp;
87 117
88 GURL request_url = FormRequestURL(url_); 118 GURL request_url = FormRequestURL(url_);
89 url_fetcher_.reset(net::URLFetcher::Create( 119 url_fetcher_.reset(net::URLFetcher::Create(
90 url_fetcher_id_for_tests, request_url, net::URLFetcher::POST, this)); 120 url_fetcher_id_for_tests, request_url, net::URLFetcher::POST, this));
91 url_fetcher_->SetRequestContext(url_context_.get()); 121 url_fetcher_->SetRequestContext(url_context_.get());
92 std::string upload_data; 122 std::string upload_data;
93 FormUploadData(wifi_data, timestamp, access_token, &upload_data); 123 FormUploadData(wifi_data, timestamp, access_token, &upload_data);
94 url_fetcher_->SetUploadData("application/json", upload_data); 124 url_fetcher_->SetUploadData("application/json", upload_data);
95 url_fetcher_->SetLoadFlags( 125 url_fetcher_->SetLoadFlags(
96 net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE | 126 net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
97 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES | 127 net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES |
98 net::LOAD_DO_NOT_SEND_AUTH_DATA); 128 net::LOAD_DO_NOT_SEND_AUTH_DATA);
99 129
100 start_time_ = base::TimeTicks::Now(); 130 start_time_ = base::TimeTicks::Now();
101 url_fetcher_->Start(); 131 url_fetcher_->Start();
102 return true; 132 return true;
103 } 133 }
104 134
105 void NetworkLocationRequest::OnURLFetchComplete( 135 void NetworkLocationRequest::OnURLFetchComplete(
106 const net::URLFetcher* source) { 136 const net::URLFetcher* source) {
107 DCHECK_EQ(url_fetcher_.get(), source); 137 DCHECK_EQ(url_fetcher_.get(), source);
108 138
109 net::URLRequestStatus status = source->GetStatus(); 139 net::URLRequestStatus status = source->GetStatus();
110 int response_code = source->GetResponseCode(); 140 int response_code = source->GetResponseCode();
141 RecordUmaResponseCode(response_code);
111 142
112 Geoposition position; 143 Geoposition position;
113 string16 access_token; 144 string16 access_token;
114 std::string data; 145 std::string data;
115 source->GetResponseAsString(&data); 146 source->GetResponseAsString(&data);
116 GetLocationFromResponse(status.is_success(), 147 GetLocationFromResponse(status.is_success(),
117 response_code, 148 response_code,
118 data, 149 data,
119 timestamp_, 150 timestamp_,
120 source->GetURL(), 151 source->GetURL(),
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
252 const GURL& server_url, 283 const GURL& server_url,
253 Geoposition* position, 284 Geoposition* position,
254 string16* access_token) { 285 string16* access_token) {
255 DCHECK(position); 286 DCHECK(position);
256 DCHECK(access_token); 287 DCHECK(access_token);
257 288
258 // HttpPost can fail for a number of reasons. Most likely this is because 289 // HttpPost can fail for a number of reasons. Most likely this is because
259 // we're offline, or there was no response. 290 // we're offline, or there was no response.
260 if (!http_post_result) { 291 if (!http_post_result) {
261 FormatPositionError(server_url, "No response received", position); 292 FormatPositionError(server_url, "No response received", position);
293 RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_EMPTY);
262 return; 294 return;
263 } 295 }
264 if (status_code != 200) { // HTTP OK. 296 if (status_code != 200) { // HTTP OK.
265 std::string message = "Returned error code "; 297 std::string message = "Returned error code ";
266 message += base::IntToString(status_code); 298 message += base::IntToString(status_code);
267 FormatPositionError(server_url, message, position); 299 FormatPositionError(server_url, message, position);
300 RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_NOT_OK);
268 return; 301 return;
269 } 302 }
270 // We use the timestamp from the wifi data that was used to generate 303 // We use the timestamp from the wifi data that was used to generate
271 // this position fix. 304 // this position fix.
272 if (!ParseServerResponse(response_body, timestamp, position, access_token)) { 305 if (!ParseServerResponse(response_body, timestamp, position, access_token)) {
273 // We failed to parse the repsonse. 306 // We failed to parse the repsonse.
274 FormatPositionError(server_url, "Response was malformed", position); 307 FormatPositionError(server_url, "Response was malformed", position);
308 RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_MALFORMED);
275 return; 309 return;
276 } 310 }
277 // The response was successfully parsed, but it may not be a valid 311 // The response was successfully parsed, but it may not be a valid
278 // position fix. 312 // position fix.
279 if (!position->Validate()) { 313 if (!position->Validate()) {
280 FormatPositionError(server_url, 314 FormatPositionError(server_url,
281 "Did not provide a good position fix", position); 315 "Did not provide a good position fix", position);
316 RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_INVALID_FIX);
282 return; 317 return;
283 } 318 }
319 RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_SUCCESS);
284 } 320 }
285 321
286 // Numeric values without a decimal point have type integer and IsDouble() will 322 // Numeric values without a decimal point have type integer and IsDouble() will
287 // return false. This is convenience function for detecting integer or floating 323 // return false. This is convenience function for detecting integer or floating
288 // point numeric values. Note that isIntegral() includes boolean values, which 324 // point numeric values. Note that isIntegral() includes boolean values, which
289 // is not what we want. 325 // is not what we want.
290 bool GetAsDouble(const base::DictionaryValue& object, 326 bool GetAsDouble(const base::DictionaryValue& object,
291 const std::string& property_name, 327 const std::string& property_name,
292 double* out) { 328 double* out) {
293 DCHECK(out); 329 DCHECK(out);
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 413
378 // Other fields are optional. 414 // Other fields are optional.
379 GetAsDouble(*response_object, kAccuracyString, &position->accuracy); 415 GetAsDouble(*response_object, kAccuracyString, &position->accuracy);
380 416
381 return true; 417 return true;
382 } 418 }
383 419
384 } // namespace 420 } // namespace
385 421
386 } // namespace content 422 } // namespace content
OLDNEW
« no previous file with comments | « no previous file | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698