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

Side by Side Diff: chromeos/geolocation/simple_geolocation_request.cc

Issue 2624843003: Add support for cellular geolocation (Closed)
Patch Set: Change verbiage, simplify network functions Created 3 years, 10 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 "chromeos/geolocation/simple_geolocation_request.h" 5 #include "chromeos/geolocation/simple_geolocation_request.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <string> 10 #include <string>
(...skipping 23 matching lines...) Expand all
34 UMA_HISTOGRAM_CUSTOM_TIMES(name, \ 34 UMA_HISTOGRAM_CUSTOM_TIMES(name, \
35 sample, \ 35 sample, \
36 base::TimeDelta::FromMilliseconds(10), \ 36 base::TimeDelta::FromMilliseconds(10), \
37 base::TimeDelta::FromMinutes(2), \ 37 base::TimeDelta::FromMinutes(2), \
38 50) 38 50)
39 39
40 namespace chromeos { 40 namespace chromeos {
41 41
42 namespace { 42 namespace {
43 43
44 // The full request text. (no parameters are supported by now) 44 // The full request text. (no parameters are supported by now)
Alexander Alekseev 2017/02/08 22:43:55 nit: Change this comment to something like: "This
can Skylar cook 2017/02/09 19:44:30 Done.
45 const char kSimpleGeolocationRequestBody[] = "{\"considerIp\": \"true\"}"; 45 constexpr char kSimpleGeolocationRequestBody[] = "{\"considerIp\": \"true\"}";
46 46
47 // Request data 47 // Geolocation request field keys:
48 const char kConsiderIp[] = "considerIp"; 48 // Top-level request data fields.
49 const char kWifiAccessPoints[] = "wifiAccessPoints"; 49 constexpr char kConsiderIp[] = "considerIp";
50 constexpr char kWifiAccessPoints[] = "wifiAccessPoints";
51 constexpr char kCellTowers[] = "cellTowers";
52 // Shared Wifi and Cell Tower objects.
53 constexpr char kAge[] = "age";
54 constexpr char kSignalStrength[] = "signalStrength";
55 // WiFi access point objects.
56 constexpr char kMacAddress[] = "macAddress";
57 constexpr char kChannel[] = "channel";
58 constexpr char kSignalToNoiseRatio[] = "signalToNoiseRatio";
59 // Cell tower objects.
60 constexpr char kCellId[] = "cellId";
61 constexpr char kLocationAreaCode[] = "locationAreaCode";
62 constexpr char kMobileCountryCode[] = "mobileCountryCode";
63 constexpr char kMobileNetworkCode[] = "mobileNetworkCode";
50 64
51 // WiFi access point objects. 65 // Geolocation response field keys:
52 const char kMacAddress[] = "macAddress"; 66 constexpr char kLocationString[] = "location";
53 const char kSignalStrength[] = "signalStrength"; 67 constexpr char kLatString[] = "lat";
54 const char kAge[] = "age"; 68 constexpr char kLngString[] = "lng";
55 const char kChannel[] = "channel"; 69 constexpr char kAccuracyString[] = "accuracy";
56 const char kSignalToNoiseRatio[] = "signalToNoiseRatio";
57 70
58 // Response data.
59 const char kLocationString[] = "location";
60 const char kLatString[] = "lat";
61 const char kLngString[] = "lng";
62 const char kAccuracyString[] = "accuracy";
63 // Error object and its contents. 71 // Error object and its contents.
64 const char kErrorString[] = "error"; 72 constexpr char kErrorString[] = "error";
65 // "errors" array in "erorr" object is ignored. 73 // "errors" array in "erorr" object is ignored.
66 const char kCodeString[] = "code"; 74 constexpr char kCodeString[] = "code";
67 const char kMessageString[] = "message"; 75 constexpr char kMessageString[] = "message";
68 76
69 // We are using "sparse" histograms for the number of retry attempts, 77 // We are using "sparse" histograms for the number of retry attempts,
70 // so we need to explicitly limit maximum value (in case something goes wrong). 78 // so we need to explicitly limit maximum value (in case something goes wrong).
71 const size_t kMaxRetriesValueInHistograms = 20; 79 const size_t kMaxRetriesValueInHistograms = 20;
72 80
73 // Sleep between geolocation request retry on HTTP error. 81 // Sleep between geolocation request retry on HTTP error.
74 const unsigned int kResolveGeolocationRetrySleepOnServerErrorSeconds = 5; 82 const unsigned int kResolveGeolocationRetrySleepOnServerErrorSeconds = 5;
75 83
76 // Sleep between geolocation request retry on bad server response. 84 // Sleep between geolocation request retry on bad server response.
77 const unsigned int kResolveGeolocationRetrySleepBadResponseSeconds = 10; 85 const unsigned int kResolveGeolocationRetrySleepBadResponseSeconds = 10;
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
284 RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_NOT_OK); 292 RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_NOT_OK);
285 return false; 293 return false;
286 } 294 }
287 295
288 return ParseServerResponse(server_url, response_body, position); 296 return ParseServerResponse(server_url, response_body, position);
289 } 297 }
290 298
291 void ReportUmaHasWiFiAccessPoints(bool value) { 299 void ReportUmaHasWiFiAccessPoints(bool value) {
292 UMA_HISTOGRAM_BOOLEAN("SimpleGeolocation.Request.HasWiFiAccessPoints", value); 300 UMA_HISTOGRAM_BOOLEAN("SimpleGeolocation.Request.HasWiFiAccessPoints", value);
293 } 301 }
302 void ReportUmaHasCellTowers(bool value) {
303 UMA_HISTOGRAM_BOOLEAN("SimpleGeolocation.Request.HasCellTowers", value);
304 }
305
306 // Helpers to reformat data into dictionaries for conversion to request JSON
307 std::unique_ptr<base::DictionaryValue> CreateAccessPointDictionary(
308 WifiAccessPoint access_point) {
309 auto access_point_dictionary = base::MakeUnique<base::DictionaryValue>();
310
311 access_point_dictionary->SetStringWithoutPathExpansion(
312 kMacAddress, access_point.mac_address);
313 access_point_dictionary->SetIntegerWithoutPathExpansion(
314 kSignalStrength, access_point.signal_strength);
315 if (!access_point.timestamp.is_null()) {
316 access_point_dictionary->SetStringWithoutPathExpansion(
317 kAge,
318 base::Int64ToString(
319 (base::Time::Now() - access_point.timestamp).InMilliseconds()));
320 }
321
322 access_point_dictionary->SetIntegerWithoutPathExpansion(kChannel,
323 access_point.channel);
324 access_point_dictionary->SetIntegerWithoutPathExpansion(
325 kSignalToNoiseRatio, access_point.signal_to_noise);
326
327 return access_point_dictionary;
328 }
329
330 std::unique_ptr<base::DictionaryValue> CreateCellTowerDictionary(
331 CellTower cell_tower) {
332 auto cell_tower_dictionary = base::MakeUnique<base::DictionaryValue>();
333 cell_tower_dictionary->SetStringWithoutPathExpansion(kCellId, cell_tower.ci);
334 cell_tower_dictionary->SetStringWithoutPathExpansion(kLocationAreaCode,
335 cell_tower.lac);
336 cell_tower_dictionary->SetStringWithoutPathExpansion(kMobileCountryCode,
337 cell_tower.mcc);
338 cell_tower_dictionary->SetStringWithoutPathExpansion(kMobileNetworkCode,
339 cell_tower.mnc);
340
341 if (!cell_tower.timestamp.is_null()) {
342 cell_tower_dictionary->SetStringWithoutPathExpansion(
343 kAge, base::Int64ToString(
344 (base::Time::Now() - cell_tower.timestamp).InMilliseconds()));
345 }
346 return cell_tower_dictionary;
347 }
294 348
295 } // namespace 349 } // namespace
296 350
297 SimpleGeolocationRequest::SimpleGeolocationRequest( 351 SimpleGeolocationRequest::SimpleGeolocationRequest(
298 net::URLRequestContextGetter* url_context_getter, 352 net::URLRequestContextGetter* url_context_getter,
299 const GURL& service_url, 353 const GURL& service_url,
300 base::TimeDelta timeout, 354 base::TimeDelta timeout,
301 std::unique_ptr<WifiAccessPointVector> wifi_data) 355 std::unique_ptr<WifiAccessPointVector> wifi_data,
356 std::unique_ptr<CellTowerVector> cell_tower_data)
302 : url_context_getter_(url_context_getter), 357 : url_context_getter_(url_context_getter),
303 service_url_(service_url), 358 service_url_(service_url),
304 retry_sleep_on_server_error_(base::TimeDelta::FromSeconds( 359 retry_sleep_on_server_error_(base::TimeDelta::FromSeconds(
305 kResolveGeolocationRetrySleepOnServerErrorSeconds)), 360 kResolveGeolocationRetrySleepOnServerErrorSeconds)),
306 retry_sleep_on_bad_response_(base::TimeDelta::FromSeconds( 361 retry_sleep_on_bad_response_(base::TimeDelta::FromSeconds(
307 kResolveGeolocationRetrySleepBadResponseSeconds)), 362 kResolveGeolocationRetrySleepBadResponseSeconds)),
308 timeout_(timeout), 363 timeout_(timeout),
309 retries_(0), 364 retries_(0),
310 wifi_data_(wifi_data.release()) {} 365 wifi_data_(wifi_data.release()),
366 cell_tower_data_(cell_tower_data.release()) {}
311 367
312 SimpleGeolocationRequest::~SimpleGeolocationRequest() { 368 SimpleGeolocationRequest::~SimpleGeolocationRequest() {
313 DCHECK(thread_checker_.CalledOnValidThread()); 369 DCHECK(thread_checker_.CalledOnValidThread());
314 370
315 // If callback is not empty, request is cancelled. 371 // If callback is not empty, request is cancelled.
316 if (!callback_.is_null()) { 372 if (!callback_.is_null()) {
317 RecordUmaResponseTime(base::Time::Now() - request_started_at_, false); 373 RecordUmaResponseTime(base::Time::Now() - request_started_at_, false);
318 RecordUmaResult(SIMPLE_GEOLOCATION_REQUEST_RESULT_CANCELLED, retries_); 374 RecordUmaResult(SIMPLE_GEOLOCATION_REQUEST_RESULT_CANCELLED, retries_);
319 } 375 }
320 376
321 if (g_test_request_hook) 377 if (g_test_request_hook)
322 g_test_request_hook->OnRequestCreated(this); 378 g_test_request_hook->OnRequestCreated(this);
323 } 379 }
324 380
325 std::string SimpleGeolocationRequest::FormatRequestBody() const { 381 std::string SimpleGeolocationRequest::FormatRequestBody() const {
326 if (!wifi_data_) { 382 if (!wifi_data_)
327 ReportUmaHasWiFiAccessPoints(false); 383 ReportUmaHasWiFiAccessPoints(false);
384
385 if (!cell_tower_data_)
386 ReportUmaHasCellTowers(false);
387
388 if (!cell_tower_data_ && !wifi_data_)
328 return std::string(kSimpleGeolocationRequestBody); 389 return std::string(kSimpleGeolocationRequestBody);
329 }
330 390
331 std::unique_ptr<base::DictionaryValue> request(new base::DictionaryValue); 391 std::unique_ptr<base::DictionaryValue> request(new base::DictionaryValue);
332 request->SetBooleanWithoutPathExpansion(kConsiderIp, true); 392 request->SetBooleanWithoutPathExpansion(kConsiderIp, true);
333 393
334 base::ListValue* wifi_access_points(new base::ListValue); 394 if (wifi_data_) {
335 request->SetWithoutPathExpansion(kWifiAccessPoints, wifi_access_points); 395 auto wifi_access_points = base::MakeUnique<base::ListValue>();
396 for (const WifiAccessPoint& access_point : *wifi_data_) {
397 wifi_access_points->Append(CreateAccessPointDictionary(access_point));
398 }
399 request->SetWithoutPathExpansion(kWifiAccessPoints,
400 std::move(wifi_access_points));
401 }
336 402
337 for (const WifiAccessPoint& access_point : *wifi_data_) { 403 if (cell_tower_data_) {
338 auto access_point_dictionary = base::MakeUnique<base::DictionaryValue>(); 404 auto cell_towers = base::MakeUnique<base::ListValue>();
405 for (const CellTower& cell_tower : *cell_tower_data_) {
406 cell_towers->Append(CreateCellTowerDictionary(cell_tower));
407 }
408 request->SetWithoutPathExpansion(kCellTowers, std::move(cell_towers));
409 }
339 410
340 access_point_dictionary->SetStringWithoutPathExpansion(
341 kMacAddress, access_point.mac_address);
342 access_point_dictionary->SetIntegerWithoutPathExpansion(
343 kSignalStrength, access_point.signal_strength);
344 if (!access_point.timestamp.is_null()) {
345 access_point_dictionary->SetStringWithoutPathExpansion(
346 kAge,
347 base::Int64ToString(
348 (base::Time::Now() - access_point.timestamp).InMilliseconds()));
349 }
350
351 access_point_dictionary->SetIntegerWithoutPathExpansion(
352 kChannel, access_point.channel);
353 access_point_dictionary->SetIntegerWithoutPathExpansion(
354 kSignalToNoiseRatio, access_point.signal_to_noise);
355
356 wifi_access_points->Append(std::move(access_point_dictionary));
357 }
358 std::string result; 411 std::string result;
359 if (!base::JSONWriter::Write(*request, &result)) { 412 if (!base::JSONWriter::Write(*request, &result)) {
360 ReportUmaHasWiFiAccessPoints(false); 413 // If there's no data for a network type, we will have already reported
414 // false above
415 if (wifi_data_)
416 ReportUmaHasWiFiAccessPoints(false);
417 if (cell_tower_data_)
418 ReportUmaHasCellTowers(false);
419
361 return std::string(kSimpleGeolocationRequestBody); 420 return std::string(kSimpleGeolocationRequestBody);
362 } 421 }
363 ReportUmaHasWiFiAccessPoints(wifi_data_->size()); 422
423 if (wifi_data_)
424 ReportUmaHasWiFiAccessPoints(wifi_data_->size());
425 if (cell_tower_data_)
426 ReportUmaHasCellTowers(cell_tower_data_->size());
364 427
365 return result; 428 return result;
366 } 429 }
367 430
368 void SimpleGeolocationRequest::StartRequest() { 431 void SimpleGeolocationRequest::StartRequest() {
369 DCHECK(thread_checker_.CalledOnValidThread()); 432 DCHECK(thread_checker_.CalledOnValidThread());
370 RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_REQUEST_START); 433 RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_REQUEST_START);
371 ++retries_; 434 ++retries_;
372 435
373 const std::string request_body = FormatRequestBody(); 436 const std::string request_body = FormatRequestBody();
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 ? SIMPLE_GEOLOCATION_REQUEST_RESULT_SERVER_ERROR 537 ? SIMPLE_GEOLOCATION_REQUEST_RESULT_SERVER_ERROR
475 : SIMPLE_GEOLOCATION_REQUEST_RESULT_FAILURE); 538 : SIMPLE_GEOLOCATION_REQUEST_RESULT_FAILURE);
476 RecordUmaResult(result, retries_); 539 RecordUmaResult(result, retries_);
477 position_.status = Geoposition::STATUS_TIMEOUT; 540 position_.status = Geoposition::STATUS_TIMEOUT;
478 const base::TimeDelta elapsed = base::Time::Now() - request_started_at_; 541 const base::TimeDelta elapsed = base::Time::Now() - request_started_at_;
479 ReplyAndDestroySelf(elapsed, true /* server_error */); 542 ReplyAndDestroySelf(elapsed, true /* server_error */);
480 // "this" is already destroyed here. 543 // "this" is already destroyed here.
481 } 544 }
482 545
483 } // namespace chromeos 546 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698