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

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

Issue 2624843003: Add support for cellular geolocation (Closed)
Patch Set: Remove GetCellTowers, fix indicator flag logic 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 24 matching lines...) Expand all
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)
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 }
294 305
295 } // namespace 306 } // namespace
296 307
297 SimpleGeolocationRequest::SimpleGeolocationRequest( 308 SimpleGeolocationRequest::SimpleGeolocationRequest(
298 net::URLRequestContextGetter* url_context_getter, 309 net::URLRequestContextGetter* url_context_getter,
299 const GURL& service_url, 310 const GURL& service_url,
300 base::TimeDelta timeout, 311 base::TimeDelta timeout,
301 std::unique_ptr<WifiAccessPointVector> wifi_data) 312 std::unique_ptr<WifiAccessPointVector> wifi_data,
313 std::unique_ptr<CellTowerVector> cell_tower_data)
302 : url_context_getter_(url_context_getter), 314 : url_context_getter_(url_context_getter),
303 service_url_(service_url), 315 service_url_(service_url),
304 retry_sleep_on_server_error_(base::TimeDelta::FromSeconds( 316 retry_sleep_on_server_error_(base::TimeDelta::FromSeconds(
305 kResolveGeolocationRetrySleepOnServerErrorSeconds)), 317 kResolveGeolocationRetrySleepOnServerErrorSeconds)),
306 retry_sleep_on_bad_response_(base::TimeDelta::FromSeconds( 318 retry_sleep_on_bad_response_(base::TimeDelta::FromSeconds(
307 kResolveGeolocationRetrySleepBadResponseSeconds)), 319 kResolveGeolocationRetrySleepBadResponseSeconds)),
308 timeout_(timeout), 320 timeout_(timeout),
309 retries_(0), 321 retries_(0),
310 wifi_data_(wifi_data.release()) {} 322 wifi_data_(wifi_data.release()),
323 cell_tower_data_(cell_tower_data.release()) {}
311 324
312 SimpleGeolocationRequest::~SimpleGeolocationRequest() { 325 SimpleGeolocationRequest::~SimpleGeolocationRequest() {
313 DCHECK(thread_checker_.CalledOnValidThread()); 326 DCHECK(thread_checker_.CalledOnValidThread());
314 327
315 // If callback is not empty, request is cancelled. 328 // If callback is not empty, request is cancelled.
316 if (!callback_.is_null()) { 329 if (!callback_.is_null()) {
317 RecordUmaResponseTime(base::Time::Now() - request_started_at_, false); 330 RecordUmaResponseTime(base::Time::Now() - request_started_at_, false);
318 RecordUmaResult(SIMPLE_GEOLOCATION_REQUEST_RESULT_CANCELLED, retries_); 331 RecordUmaResult(SIMPLE_GEOLOCATION_REQUEST_RESULT_CANCELLED, retries_);
319 } 332 }
320 333
321 if (g_test_request_hook) 334 if (g_test_request_hook)
322 g_test_request_hook->OnRequestCreated(this); 335 g_test_request_hook->OnRequestCreated(this);
323 } 336 }
324 337
325 std::string SimpleGeolocationRequest::FormatRequestBody() const { 338 std::string SimpleGeolocationRequest::FormatRequestBody() const {
326 if (!wifi_data_) { 339 if (!wifi_data_)
327 ReportUmaHasWiFiAccessPoints(false); 340 ReportUmaHasWiFiAccessPoints(false);
341
342 if (!cell_tower_data_)
343 ReportUmaHasCellTowers(false);
344
345 if (!cell_tower_data_ && !wifi_data_)
328 return std::string(kSimpleGeolocationRequestBody); 346 return std::string(kSimpleGeolocationRequestBody);
329 }
330 347
331 std::unique_ptr<base::DictionaryValue> request(new base::DictionaryValue); 348 std::unique_ptr<base::DictionaryValue> request(new base::DictionaryValue);
332 request->SetBooleanWithoutPathExpansion(kConsiderIp, true); 349 request->SetBooleanWithoutPathExpansion(kConsiderIp, true);
333 350
334 base::ListValue* wifi_access_points(new base::ListValue); 351 if (wifi_data_) {
335 request->SetWithoutPathExpansion(kWifiAccessPoints, wifi_access_points); 352 auto wifi_access_points = base::MakeUnique<base::ListValue>();
353 for (const WifiAccessPoint& access_point : *wifi_data_) {
354 wifi_access_points->Append(CreateAccessPointDictionary(access_point));
355 }
356 request->SetWithoutPathExpansion(kWifiAccessPoints,
357 std::move(wifi_access_points));
358 }
336 359
337 for (const WifiAccessPoint& access_point : *wifi_data_) { 360 if (cell_tower_data_) {
338 auto access_point_dictionary = base::MakeUnique<base::DictionaryValue>(); 361 auto cell_towers = base::MakeUnique<base::ListValue>();
362 for (const CellTower& cell_tower : *cell_tower_data_) {
363 cell_towers->Append(CreateCellTowerDictionary(cell_tower));
364 }
365 request->SetWithoutPathExpansion(kCellTowers, std::move(cell_towers));
366 }
339 367
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; 368 std::string result;
359 if (!base::JSONWriter::Write(*request, &result)) { 369 if (!base::JSONWriter::Write(*request, &result)) {
360 ReportUmaHasWiFiAccessPoints(false); 370 // If there's no data for a network type, we will have already reported
371 // false above
372 if (wifi_data_)
373 ReportUmaHasWiFiAccessPoints(false);
374 if (cell_tower_data_)
375 ReportUmaHasCellTowers(false);
376
361 return std::string(kSimpleGeolocationRequestBody); 377 return std::string(kSimpleGeolocationRequestBody);
362 } 378 }
363 ReportUmaHasWiFiAccessPoints(wifi_data_->size()); 379
380 if (wifi_data_)
381 ReportUmaHasWiFiAccessPoints(wifi_data_->size());
382 if (cell_tower_data_)
383 ReportUmaHasCellTowers(cell_tower_data_->size());
364 384
365 return result; 385 return result;
366 } 386 }
367 387
388 std::unique_ptr<base::DictionaryValue>
389 SimpleGeolocationRequest::CreateAccessPointDictionary(
390 WifiAccessPoint access_point) const {
391 auto access_point_dictionary = base::MakeUnique<base::DictionaryValue>();
392
393 access_point_dictionary->SetStringWithoutPathExpansion(
394 kMacAddress, access_point.mac_address);
395 access_point_dictionary->SetIntegerWithoutPathExpansion(
396 kSignalStrength, access_point.signal_strength);
397 if (!access_point.timestamp.is_null()) {
398 access_point_dictionary->SetStringWithoutPathExpansion(
399 kAge,
400 base::Int64ToString(
401 (base::Time::Now() - access_point.timestamp).InMilliseconds()));
402 }
403
404 access_point_dictionary->SetIntegerWithoutPathExpansion(kChannel,
405 access_point.channel);
406 access_point_dictionary->SetIntegerWithoutPathExpansion(
407 kSignalToNoiseRatio, access_point.signal_to_noise);
408
409 return access_point_dictionary;
410 }
stevenjb 2017/02/07 23:54:29 This doesn't appear to need to be a member functio
can Skylar cook 2017/02/08 21:15:49 Done.
411
412 std::unique_ptr<base::DictionaryValue>
413 SimpleGeolocationRequest::CreateCellTowerDictionary(
414 CellTower cell_tower) const {
415 auto cell_tower_dictionary = base::MakeUnique<base::DictionaryValue>();
416 cell_tower_dictionary->SetStringWithoutPathExpansion(kCellId, cell_tower.ci);
417 cell_tower_dictionary->SetStringWithoutPathExpansion(kLocationAreaCode,
418 cell_tower.lac);
419 cell_tower_dictionary->SetStringWithoutPathExpansion(kMobileCountryCode,
420 cell_tower.mcc);
421 cell_tower_dictionary->SetStringWithoutPathExpansion(kMobileNetworkCode,
422 cell_tower.mnc);
423
424 if (!cell_tower.timestamp.is_null()) {
425 cell_tower_dictionary->SetStringWithoutPathExpansion(
426 kAge, base::Int64ToString(
427 (base::Time::Now() - cell_tower.timestamp).InMilliseconds()));
428 }
429 return cell_tower_dictionary;
430 }
stevenjb 2017/02/07 23:54:29 Ditto.
can Skylar cook 2017/02/08 21:15:49 Done.
431
368 void SimpleGeolocationRequest::StartRequest() { 432 void SimpleGeolocationRequest::StartRequest() {
369 DCHECK(thread_checker_.CalledOnValidThread()); 433 DCHECK(thread_checker_.CalledOnValidThread());
370 RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_REQUEST_START); 434 RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_REQUEST_START);
371 ++retries_; 435 ++retries_;
372 436
373 const std::string request_body = FormatRequestBody(); 437 const std::string request_body = FormatRequestBody();
374 VLOG(1) << "SimpleGeolocationRequest::StartRequest(): request body:\n" 438 VLOG(1) << "SimpleGeolocationRequest::StartRequest(): request body:\n"
375 << request_body; 439 << request_body;
376 440
377 url_fetcher_ = 441 url_fetcher_ =
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
474 ? SIMPLE_GEOLOCATION_REQUEST_RESULT_SERVER_ERROR 538 ? SIMPLE_GEOLOCATION_REQUEST_RESULT_SERVER_ERROR
475 : SIMPLE_GEOLOCATION_REQUEST_RESULT_FAILURE); 539 : SIMPLE_GEOLOCATION_REQUEST_RESULT_FAILURE);
476 RecordUmaResult(result, retries_); 540 RecordUmaResult(result, retries_);
477 position_.status = Geoposition::STATUS_TIMEOUT; 541 position_.status = Geoposition::STATUS_TIMEOUT;
478 const base::TimeDelta elapsed = base::Time::Now() - request_started_at_; 542 const base::TimeDelta elapsed = base::Time::Now() - request_started_at_;
479 ReplyAndDestroySelf(elapsed, true /* server_error */); 543 ReplyAndDestroySelf(elapsed, true /* server_error */);
480 // "this" is already destroyed here. 544 // "this" is already destroyed here.
481 } 545 }
482 546
483 } // namespace chromeos 547 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698