Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 // TODO(skylarc): kill these and use dbus-constants instead? |
|
Alexander Alekseev
2017/02/06 23:24:53
I think that dbus-constants could be used for DBUS
can Skylar cook
2017/02/07 21:32:39
Good point -- they're technically *not* dbus const
stevenjb
2017/02/07 21:39:38
I agree that dbus-constants should be used for key
| |
| 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 | |
| 53 // Shared Wifi and Cell Tower objects | |
| 54 constexpr char kAge[] = "age"; | |
| 55 constexpr char kSignalStrength[] = "signalStrength"; | |
| 50 | 56 |
| 51 // WiFi access point objects. | 57 // WiFi access point objects. |
| 52 const char kMacAddress[] = "macAddress"; | 58 constexpr char kMacAddress[] = "macAddress"; |
| 53 const char kSignalStrength[] = "signalStrength"; | 59 constexpr char kChannel[] = "channel"; |
| 54 const char kAge[] = "age"; | 60 constexpr char kSignalToNoiseRatio[] = "signalToNoiseRatio"; |
| 55 const char kChannel[] = "channel"; | 61 |
| 56 const char kSignalToNoiseRatio[] = "signalToNoiseRatio"; | 62 // Cell tower objects |
| 63 constexpr char kCellId[] = "cellId"; | |
| 64 constexpr char kLocationAreaCode[] = "locationAreaCode"; | |
| 65 constexpr char kMobileCountryCode[] = "mobileCountryCode"; | |
| 66 constexpr char kMobileNetworkCode[] = "mobileNetworkCode"; | |
| 57 | 67 |
| 58 // Response data. | 68 // Response data. |
| 59 const char kLocationString[] = "location"; | 69 constexpr char kLocationString[] = "location"; |
| 60 const char kLatString[] = "lat"; | 70 constexpr char kLatString[] = "lat"; |
| 61 const char kLngString[] = "lng"; | 71 constexpr char kLngString[] = "lng"; |
| 62 const char kAccuracyString[] = "accuracy"; | 72 constexpr char kAccuracyString[] = "accuracy"; |
| 63 // Error object and its contents. | 73 // Error object and its contents. |
| 64 const char kErrorString[] = "error"; | 74 constexpr char kErrorString[] = "error"; |
| 65 // "errors" array in "erorr" object is ignored. | 75 // "errors" array in "erorr" object is ignored. |
| 66 const char kCodeString[] = "code"; | 76 constexpr char kCodeString[] = "code"; |
| 67 const char kMessageString[] = "message"; | 77 constexpr char kMessageString[] = "message"; |
| 68 | 78 |
| 69 // We are using "sparse" histograms for the number of retry attempts, | 79 // 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). | 80 // so we need to explicitly limit maximum value (in case something goes wrong). |
| 71 const size_t kMaxRetriesValueInHistograms = 20; | 81 const size_t kMaxRetriesValueInHistograms = 20; |
| 72 | 82 |
| 73 // Sleep between geolocation request retry on HTTP error. | 83 // Sleep between geolocation request retry on HTTP error. |
| 74 const unsigned int kResolveGeolocationRetrySleepOnServerErrorSeconds = 5; | 84 const unsigned int kResolveGeolocationRetrySleepOnServerErrorSeconds = 5; |
| 75 | 85 |
| 76 // Sleep between geolocation request retry on bad server response. | 86 // Sleep between geolocation request retry on bad server response. |
| 77 const unsigned int kResolveGeolocationRetrySleepBadResponseSeconds = 10; | 87 const unsigned int kResolveGeolocationRetrySleepBadResponseSeconds = 10; |
| (...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 284 RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_NOT_OK); | 294 RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_RESPONSE_NOT_OK); |
| 285 return false; | 295 return false; |
| 286 } | 296 } |
| 287 | 297 |
| 288 return ParseServerResponse(server_url, response_body, position); | 298 return ParseServerResponse(server_url, response_body, position); |
| 289 } | 299 } |
| 290 | 300 |
| 291 void ReportUmaHasWiFiAccessPoints(bool value) { | 301 void ReportUmaHasWiFiAccessPoints(bool value) { |
| 292 UMA_HISTOGRAM_BOOLEAN("SimpleGeolocation.Request.HasWiFiAccessPoints", value); | 302 UMA_HISTOGRAM_BOOLEAN("SimpleGeolocation.Request.HasWiFiAccessPoints", value); |
| 293 } | 303 } |
| 304 void ReportUmaHasCellTowers(bool value) { | |
| 305 UMA_HISTOGRAM_BOOLEAN("SimpleGeolocation.Request.HasCellTowers", value); | |
| 306 } | |
| 294 | 307 |
| 295 } // namespace | 308 } // namespace |
| 296 | 309 |
| 297 SimpleGeolocationRequest::SimpleGeolocationRequest( | 310 SimpleGeolocationRequest::SimpleGeolocationRequest( |
| 298 net::URLRequestContextGetter* url_context_getter, | 311 net::URLRequestContextGetter* url_context_getter, |
| 299 const GURL& service_url, | 312 const GURL& service_url, |
| 300 base::TimeDelta timeout, | 313 base::TimeDelta timeout, |
| 301 std::unique_ptr<WifiAccessPointVector> wifi_data) | 314 std::unique_ptr<WifiAccessPointVector> wifi_data, |
| 315 std::unique_ptr<CellTowerVector> cell_tower_data) | |
| 302 : url_context_getter_(url_context_getter), | 316 : url_context_getter_(url_context_getter), |
| 303 service_url_(service_url), | 317 service_url_(service_url), |
| 304 retry_sleep_on_server_error_(base::TimeDelta::FromSeconds( | 318 retry_sleep_on_server_error_(base::TimeDelta::FromSeconds( |
| 305 kResolveGeolocationRetrySleepOnServerErrorSeconds)), | 319 kResolveGeolocationRetrySleepOnServerErrorSeconds)), |
| 306 retry_sleep_on_bad_response_(base::TimeDelta::FromSeconds( | 320 retry_sleep_on_bad_response_(base::TimeDelta::FromSeconds( |
| 307 kResolveGeolocationRetrySleepBadResponseSeconds)), | 321 kResolveGeolocationRetrySleepBadResponseSeconds)), |
| 308 timeout_(timeout), | 322 timeout_(timeout), |
| 309 retries_(0), | 323 retries_(0), |
| 310 wifi_data_(wifi_data.release()) {} | 324 wifi_data_(wifi_data.release()), |
| 325 cell_tower_data_(cell_tower_data.release()) {} | |
| 311 | 326 |
| 312 SimpleGeolocationRequest::~SimpleGeolocationRequest() { | 327 SimpleGeolocationRequest::~SimpleGeolocationRequest() { |
| 313 DCHECK(thread_checker_.CalledOnValidThread()); | 328 DCHECK(thread_checker_.CalledOnValidThread()); |
| 314 | 329 |
| 315 // If callback is not empty, request is cancelled. | 330 // If callback is not empty, request is cancelled. |
| 316 if (!callback_.is_null()) { | 331 if (!callback_.is_null()) { |
| 317 RecordUmaResponseTime(base::Time::Now() - request_started_at_, false); | 332 RecordUmaResponseTime(base::Time::Now() - request_started_at_, false); |
| 318 RecordUmaResult(SIMPLE_GEOLOCATION_REQUEST_RESULT_CANCELLED, retries_); | 333 RecordUmaResult(SIMPLE_GEOLOCATION_REQUEST_RESULT_CANCELLED, retries_); |
| 319 } | 334 } |
| 320 | 335 |
| 321 if (g_test_request_hook) | 336 if (g_test_request_hook) |
| 322 g_test_request_hook->OnRequestCreated(this); | 337 g_test_request_hook->OnRequestCreated(this); |
| 323 } | 338 } |
| 324 | 339 |
| 325 std::string SimpleGeolocationRequest::FormatRequestBody() const { | 340 std::string SimpleGeolocationRequest::FormatRequestBody() const { |
| 326 if (!wifi_data_) { | 341 if (!wifi_data_) |
| 327 ReportUmaHasWiFiAccessPoints(false); | 342 ReportUmaHasWiFiAccessPoints(false); |
| 343 | |
| 344 if (!cell_tower_data_) | |
| 345 ReportUmaHasCellTowers(false); | |
| 346 | |
| 347 if (!cell_tower_data_ && !wifi_data_) | |
| 328 return std::string(kSimpleGeolocationRequestBody); | 348 return std::string(kSimpleGeolocationRequestBody); |
| 329 } | |
| 330 | 349 |
| 331 std::unique_ptr<base::DictionaryValue> request(new base::DictionaryValue); | 350 std::unique_ptr<base::DictionaryValue> request(new base::DictionaryValue); |
| 332 request->SetBooleanWithoutPathExpansion(kConsiderIp, true); | 351 request->SetBooleanWithoutPathExpansion(kConsiderIp, true); |
| 333 | 352 |
| 334 base::ListValue* wifi_access_points(new base::ListValue); | 353 if (wifi_data_) { |
| 335 request->SetWithoutPathExpansion(kWifiAccessPoints, wifi_access_points); | 354 auto wifi_access_points = base::MakeUnique<base::ListValue>(); |
| 355 for (const WifiAccessPoint& access_point : *wifi_data_) { | |
| 356 wifi_access_points->Append(CreateAccessPointDictionary(access_point)); | |
| 357 } | |
| 358 request->SetWithoutPathExpansion(kWifiAccessPoints, | |
| 359 std::move(wifi_access_points)); | |
| 360 } | |
| 336 | 361 |
| 337 for (const WifiAccessPoint& access_point : *wifi_data_) { | 362 if (cell_tower_data_) { |
| 338 auto access_point_dictionary = base::MakeUnique<base::DictionaryValue>(); | 363 auto cell_towers = base::MakeUnique<base::ListValue>(); |
| 364 for (const CellTower& cell_tower : *cell_tower_data_) { | |
| 365 cell_towers->Append(CreateCellTowerDictionary(cell_tower)); | |
| 366 } | |
| 367 request->SetWithoutPathExpansion(kCellTowers, std::move(cell_towers)); | |
| 368 } | |
| 339 | 369 |
| 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; | 370 std::string result; |
| 359 if (!base::JSONWriter::Write(*request, &result)) { | 371 if (!base::JSONWriter::Write(*request, &result)) { |
| 360 ReportUmaHasWiFiAccessPoints(false); | 372 // If there's no data for a network type, we will have already reported |
| 373 // false above | |
| 374 if (wifi_data_) | |
| 375 ReportUmaHasWiFiAccessPoints(false); | |
| 376 if (cell_tower_data_) | |
| 377 ReportUmaHasCellTowers(false); | |
| 378 | |
| 361 return std::string(kSimpleGeolocationRequestBody); | 379 return std::string(kSimpleGeolocationRequestBody); |
| 362 } | 380 } |
| 363 ReportUmaHasWiFiAccessPoints(wifi_data_->size()); | 381 |
| 382 if (wifi_data_) | |
| 383 ReportUmaHasWiFiAccessPoints(wifi_data_->size()); | |
| 384 if (cell_tower_data_) | |
| 385 ReportUmaHasCellTowers(cell_tower_data_->size()); | |
| 364 | 386 |
| 365 return result; | 387 return result; |
| 366 } | 388 } |
| 367 | 389 |
| 390 std::unique_ptr<base::DictionaryValue> | |
| 391 SimpleGeolocationRequest::CreateAccessPointDictionary( | |
| 392 WifiAccessPoint access_point) const { | |
| 393 auto access_point_dictionary = base::MakeUnique<base::DictionaryValue>(); | |
| 394 | |
| 395 access_point_dictionary->SetStringWithoutPathExpansion( | |
| 396 kMacAddress, access_point.mac_address); | |
| 397 access_point_dictionary->SetIntegerWithoutPathExpansion( | |
| 398 kSignalStrength, access_point.signal_strength); | |
| 399 if (!access_point.timestamp.is_null()) { | |
| 400 access_point_dictionary->SetStringWithoutPathExpansion( | |
| 401 kAge, | |
| 402 base::Int64ToString( | |
| 403 (base::Time::Now() - access_point.timestamp).InMilliseconds())); | |
| 404 } | |
| 405 | |
| 406 access_point_dictionary->SetIntegerWithoutPathExpansion(kChannel, | |
| 407 access_point.channel); | |
| 408 access_point_dictionary->SetIntegerWithoutPathExpansion( | |
| 409 kSignalToNoiseRatio, access_point.signal_to_noise); | |
| 410 | |
| 411 return access_point_dictionary; | |
| 412 } | |
| 413 | |
| 414 std::unique_ptr<base::DictionaryValue> | |
| 415 SimpleGeolocationRequest::CreateCellTowerDictionary( | |
| 416 CellTower cell_tower) const { | |
| 417 auto cell_tower_dictionary = base::MakeUnique<base::DictionaryValue>(); | |
| 418 cell_tower_dictionary->SetStringWithoutPathExpansion(kCellId, cell_tower.ci); | |
| 419 cell_tower_dictionary->SetStringWithoutPathExpansion(kLocationAreaCode, | |
| 420 cell_tower.lac); | |
| 421 cell_tower_dictionary->SetStringWithoutPathExpansion(kMobileCountryCode, | |
| 422 cell_tower.mcc); | |
| 423 cell_tower_dictionary->SetStringWithoutPathExpansion(kMobileNetworkCode, | |
| 424 cell_tower.mnc); | |
| 425 | |
| 426 if (!cell_tower.timestamp.is_null()) { | |
| 427 cell_tower_dictionary->SetStringWithoutPathExpansion( | |
| 428 kAge, base::Int64ToString( | |
| 429 (base::Time::Now() - cell_tower.timestamp).InMilliseconds())); | |
| 430 } | |
| 431 return cell_tower_dictionary; | |
| 432 } | |
| 433 | |
| 368 void SimpleGeolocationRequest::StartRequest() { | 434 void SimpleGeolocationRequest::StartRequest() { |
| 369 DCHECK(thread_checker_.CalledOnValidThread()); | 435 DCHECK(thread_checker_.CalledOnValidThread()); |
| 370 RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_REQUEST_START); | 436 RecordUmaEvent(SIMPLE_GEOLOCATION_REQUEST_EVENT_REQUEST_START); |
| 371 ++retries_; | 437 ++retries_; |
| 372 | 438 |
| 373 const std::string request_body = FormatRequestBody(); | 439 const std::string request_body = FormatRequestBody(); |
| 374 VLOG(1) << "SimpleGeolocationRequest::StartRequest(): request body:\n" | 440 VLOG(1) << "SimpleGeolocationRequest::StartRequest(): request body:\n" |
| 375 << request_body; | 441 << request_body; |
| 376 | 442 |
| 377 url_fetcher_ = | 443 url_fetcher_ = |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 474 ? SIMPLE_GEOLOCATION_REQUEST_RESULT_SERVER_ERROR | 540 ? SIMPLE_GEOLOCATION_REQUEST_RESULT_SERVER_ERROR |
| 475 : SIMPLE_GEOLOCATION_REQUEST_RESULT_FAILURE); | 541 : SIMPLE_GEOLOCATION_REQUEST_RESULT_FAILURE); |
| 476 RecordUmaResult(result, retries_); | 542 RecordUmaResult(result, retries_); |
| 477 position_.status = Geoposition::STATUS_TIMEOUT; | 543 position_.status = Geoposition::STATUS_TIMEOUT; |
| 478 const base::TimeDelta elapsed = base::Time::Now() - request_started_at_; | 544 const base::TimeDelta elapsed = base::Time::Now() - request_started_at_; |
| 479 ReplyAndDestroySelf(elapsed, true /* server_error */); | 545 ReplyAndDestroySelf(elapsed, true /* server_error */); |
| 480 // "this" is already destroyed here. | 546 // "this" is already destroyed here. |
| 481 } | 547 } |
| 482 | 548 |
| 483 } // namespace chromeos | 549 } // namespace chromeos |
| OLD | NEW |