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

Unified Diff: device/geolocation/network_location_request.cc

Issue 2192683003: Revert of Reland: Geolocation: move from content/browser to device/ (patchset #2 id:20001 of https:… (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2810
Patch Set: Created 4 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « device/geolocation/network_location_request.h ('k') | device/geolocation/wifi_data.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: device/geolocation/network_location_request.cc
diff --git a/device/geolocation/network_location_request.cc b/device/geolocation/network_location_request.cc
deleted file mode 100644
index cb6eaf62219776917470c8dbce5f454e74c59667..0000000000000000000000000000000000000000
--- a/device/geolocation/network_location_request.cc
+++ /dev/null
@@ -1,427 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "device/geolocation/network_location_request.h"
-
-#include <stdint.h>
-
-#include <limits>
-#include <set>
-#include <string>
-
-#include "base/json/json_reader.h"
-#include "base/json/json_writer.h"
-#include "base/metrics/histogram.h"
-#include "base/metrics/sparse_histogram.h"
-#include "base/strings/string_number_conversions.h"
-#include "base/strings/utf_string_conversions.h"
-#include "base/values.h"
-#include "device/geolocation/geoposition.h"
-#include "device/geolocation/location_arbitrator_impl.h"
-#include "google_apis/google_api_keys.h"
-#include "net/base/escape.h"
-#include "net/base/load_flags.h"
-#include "net/url_request/url_fetcher.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "net/url_request/url_request_status.h"
-
-namespace device {
-namespace {
-
-const char kAccessTokenString[] = "accessToken";
-const char kLocationString[] = "location";
-const char kLatitudeString[] = "lat";
-const char kLongitudeString[] = "lng";
-const char kAccuracyString[] = "accuracy";
-
-enum NetworkLocationRequestEvent {
- // NOTE: Do not renumber these as that would confuse interpretation of
- // previously logged data. When making changes, also update the enum list
- // in tools/metrics/histograms/histograms.xml to keep it in sync.
- NETWORK_LOCATION_REQUEST_EVENT_REQUEST_START = 0,
- NETWORK_LOCATION_REQUEST_EVENT_REQUEST_CANCEL = 1,
- NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_SUCCESS = 2,
- NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_NOT_OK = 3,
- NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_EMPTY = 4,
- NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_MALFORMED = 5,
- NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_INVALID_FIX = 6,
-
- // NOTE: Add entries only immediately above this line.
- NETWORK_LOCATION_REQUEST_EVENT_COUNT = 7
-};
-
-void RecordUmaEvent(NetworkLocationRequestEvent event) {
- UMA_HISTOGRAM_ENUMERATION("Geolocation.NetworkLocationRequest.Event",
- event, NETWORK_LOCATION_REQUEST_EVENT_COUNT);
-}
-
-void RecordUmaResponseCode(int code) {
- UMA_HISTOGRAM_SPARSE_SLOWLY("Geolocation.NetworkLocationRequest.ResponseCode",
- code);
-}
-
-void RecordUmaAccessPoints(int count) {
- const int min = 0;
- const int max = 20;
- const int buckets = 21;
- UMA_HISTOGRAM_CUSTOM_COUNTS("Geolocation.NetworkLocationRequest.AccessPoints",
- count, min, max, buckets);
-}
-
-// Local functions
-// Creates the request url to send to the server.
-GURL FormRequestURL(const GURL& url);
-
-void FormUploadData(const WifiData& wifi_data,
- const base::Time& wifi_timestamp,
- const base::string16& access_token,
- std::string* upload_data);
-
-// Attempts to extract a position from the response. Detects and indicates
-// various failure cases.
-void GetLocationFromResponse(bool http_post_result,
- int status_code,
- const std::string& response_body,
- const base::Time& wifi_timestamp,
- const GURL& server_url,
- Geoposition* position,
- base::string16* access_token);
-
-// Parses the server response body. Returns true if parsing was successful.
-// Sets |*position| to the parsed location if a valid fix was received,
-// otherwise leaves it unchanged.
-bool ParseServerResponse(const std::string& response_body,
- const base::Time& wifi_timestamp,
- Geoposition* position,
- base::string16* access_token);
-void AddWifiData(const WifiData& wifi_data,
- int age_milliseconds,
- base::DictionaryValue* request);
-} // namespace
-
-int NetworkLocationRequest::url_fetcher_id_for_tests = 0;
-
-NetworkLocationRequest::NetworkLocationRequest(
- const scoped_refptr<net::URLRequestContextGetter>& context,
- const GURL& url,
- LocationResponseCallback callback)
- : url_context_(context), location_response_callback_(callback), url_(url) {
-}
-
-NetworkLocationRequest::~NetworkLocationRequest() {
-}
-
-bool NetworkLocationRequest::MakeRequest(const base::string16& access_token,
- const WifiData& wifi_data,
- const base::Time& wifi_timestamp) {
- RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_REQUEST_START);
- RecordUmaAccessPoints(wifi_data.access_point_data.size());
- if (url_fetcher_ != NULL) {
- DVLOG(1) << "NetworkLocationRequest : Cancelling pending request";
- RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_REQUEST_CANCEL);
- url_fetcher_.reset();
- }
- wifi_data_ = wifi_data;
- wifi_timestamp_ = wifi_timestamp;
-
- GURL request_url = FormRequestURL(url_);
- url_fetcher_ = net::URLFetcher::Create(url_fetcher_id_for_tests, request_url,
- net::URLFetcher::POST, this);
- url_fetcher_->SetRequestContext(url_context_.get());
- std::string upload_data;
- FormUploadData(wifi_data, wifi_timestamp, access_token, &upload_data);
- url_fetcher_->SetUploadData("application/json", upload_data);
- url_fetcher_->SetLoadFlags(
- net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE |
- net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES |
- net::LOAD_DO_NOT_SEND_AUTH_DATA);
-
- request_start_time_ = base::TimeTicks::Now();
- url_fetcher_->Start();
- return true;
-}
-
-void NetworkLocationRequest::OnURLFetchComplete(
- const net::URLFetcher* source) {
- DCHECK_EQ(url_fetcher_.get(), source);
-
- net::URLRequestStatus status = source->GetStatus();
- int response_code = source->GetResponseCode();
- RecordUmaResponseCode(response_code);
-
- Geoposition position;
- base::string16 access_token;
- std::string data;
- source->GetResponseAsString(&data);
- GetLocationFromResponse(status.is_success(), response_code, data,
- wifi_timestamp_, source->GetURL(), &position,
- &access_token);
- const bool server_error =
- !status.is_success() || (response_code >= 500 && response_code < 600);
- url_fetcher_.reset();
-
- if (!server_error) {
- const base::TimeDelta request_time =
- base::TimeTicks::Now() - request_start_time_;
-
- UMA_HISTOGRAM_CUSTOM_TIMES(
- "Net.Wifi.LbsLatency",
- request_time,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromSeconds(10),
- 100);
- }
-
- DVLOG(1) << "NetworkLocationRequest::OnURLFetchComplete() : run callback.";
- location_response_callback_.Run(
- position, server_error, access_token, wifi_data_);
-}
-
-// Local functions.
-namespace {
-
-struct AccessPointLess {
- bool operator()(const AccessPointData* ap1,
- const AccessPointData* ap2) const {
- return ap2->radio_signal_strength < ap1->radio_signal_strength;
- }
-};
-
-GURL FormRequestURL(const GURL& url) {
- if (url == LocationArbitratorImpl::DefaultNetworkProviderURL()) {
- std::string api_key = google_apis::GetAPIKey();
- if (!api_key.empty()) {
- std::string query(url.query());
- if (!query.empty())
- query += "&";
- query += "key=" + net::EscapeQueryParamValue(api_key, true);
- GURL::Replacements replacements;
- replacements.SetQueryStr(query);
- return url.ReplaceComponents(replacements);
- }
- }
- return url;
-}
-
-void FormUploadData(const WifiData& wifi_data,
- const base::Time& wifi_timestamp,
- const base::string16& access_token,
- std::string* upload_data) {
- int age = std::numeric_limits<int32_t>::min(); // Invalid so AddInteger()
- // will ignore.
- if (!wifi_timestamp.is_null()) {
- // Convert absolute timestamps into a relative age.
- int64_t delta_ms = (base::Time::Now() - wifi_timestamp).InMilliseconds();
- if (delta_ms >= 0 && delta_ms < std::numeric_limits<int32_t>::max())
- age = static_cast<int>(delta_ms);
- }
-
- base::DictionaryValue request;
- AddWifiData(wifi_data, age, &request);
- if (!access_token.empty())
- request.SetString(kAccessTokenString, access_token);
- base::JSONWriter::Write(request, upload_data);
-}
-
-void AddString(const std::string& property_name, const std::string& value,
- base::DictionaryValue* dict) {
- DCHECK(dict);
- if (!value.empty())
- dict->SetString(property_name, value);
-}
-
-void AddInteger(const std::string& property_name, int value,
- base::DictionaryValue* dict) {
- DCHECK(dict);
- if (value != std::numeric_limits<int32_t>::min())
- dict->SetInteger(property_name, value);
-}
-
-void AddWifiData(const WifiData& wifi_data,
- int age_milliseconds,
- base::DictionaryValue* request) {
- DCHECK(request);
-
- if (wifi_data.access_point_data.empty())
- return;
-
- typedef std::multiset<const AccessPointData*, AccessPointLess> AccessPointSet;
- AccessPointSet access_points_by_signal_strength;
-
- for (const auto& ap_data : wifi_data.access_point_data)
- access_points_by_signal_strength.insert(&ap_data);
-
- base::ListValue* wifi_access_point_list = new base::ListValue();
- for (auto* ap_data : access_points_by_signal_strength) {
- base::DictionaryValue* wifi_dict = new base::DictionaryValue();
- AddString("macAddress", base::UTF16ToUTF8(ap_data->mac_address), wifi_dict);
- AddInteger("signalStrength", ap_data->radio_signal_strength, wifi_dict);
- AddInteger("age", age_milliseconds, wifi_dict);
- AddInteger("channel", ap_data->channel, wifi_dict);
- AddInteger("signalToNoiseRatio", ap_data->signal_to_noise, wifi_dict);
- wifi_access_point_list->Append(wifi_dict);
- }
- request->Set("wifiAccessPoints", wifi_access_point_list);
-}
-
-void FormatPositionError(const GURL& server_url,
- const std::string& message,
- Geoposition* position) {
- position->error_code = Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
- position->error_message = "Network location provider at '";
- position->error_message += server_url.GetOrigin().spec();
- position->error_message += "' : ";
- position->error_message += message;
- position->error_message += ".";
- VLOG(1) << "NetworkLocationRequest::GetLocationFromResponse() : "
- << position->error_message;
-}
-
-void GetLocationFromResponse(bool http_post_result,
- int status_code,
- const std::string& response_body,
- const base::Time& wifi_timestamp,
- const GURL& server_url,
- Geoposition* position,
- base::string16* access_token) {
- DCHECK(position);
- DCHECK(access_token);
-
- // HttpPost can fail for a number of reasons. Most likely this is because
- // we're offline, or there was no response.
- if (!http_post_result) {
- FormatPositionError(server_url, "No response received", position);
- RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_EMPTY);
- return;
- }
- if (status_code != 200) { // HTTP OK.
- std::string message = "Returned error code ";
- message += base::IntToString(status_code);
- FormatPositionError(server_url, message, position);
- RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_NOT_OK);
- return;
- }
- // We use the timestamp from the wifi data that was used to generate
- // this position fix.
- if (!ParseServerResponse(response_body, wifi_timestamp, position,
- access_token)) {
- // We failed to parse the repsonse.
- FormatPositionError(server_url, "Response was malformed", position);
- RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_MALFORMED);
- return;
- }
- // The response was successfully parsed, but it may not be a valid
- // position fix.
- if (!position->Validate()) {
- FormatPositionError(server_url,
- "Did not provide a good position fix", position);
- RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_INVALID_FIX);
- return;
- }
- RecordUmaEvent(NETWORK_LOCATION_REQUEST_EVENT_RESPONSE_SUCCESS);
-}
-
-// Numeric values without a decimal point have type integer and IsDouble() will
-// return false. This is convenience function for detecting integer or floating
-// point numeric values. Note that isIntegral() includes boolean values, which
-// is not what we want.
-bool GetAsDouble(const base::DictionaryValue& object,
- const std::string& property_name,
- double* out) {
- DCHECK(out);
- const base::Value* value = NULL;
- if (!object.Get(property_name, &value))
- return false;
- int value_as_int;
- DCHECK(value);
- if (value->GetAsInteger(&value_as_int)) {
- *out = value_as_int;
- return true;
- }
- return value->GetAsDouble(out);
-}
-
-bool ParseServerResponse(const std::string& response_body,
- const base::Time& wifi_timestamp,
- Geoposition* position,
- base::string16* access_token) {
- DCHECK(position);
- DCHECK(!position->Validate());
- DCHECK(position->error_code == Geoposition::ERROR_CODE_NONE);
- DCHECK(access_token);
- DCHECK(!wifi_timestamp.is_null());
-
- if (response_body.empty()) {
- LOG(WARNING) << "ParseServerResponse() : Response was empty.";
- return false;
- }
- DVLOG(1) << "ParseServerResponse() : Parsing response " << response_body;
-
- // Parse the response, ignoring comments.
- std::string error_msg;
- std::unique_ptr<base::Value> response_value =
- base::JSONReader::ReadAndReturnError(response_body, base::JSON_PARSE_RFC,
- NULL, &error_msg);
- if (response_value == NULL) {
- LOG(WARNING) << "ParseServerResponse() : JSONReader failed : "
- << error_msg;
- return false;
- }
-
- if (!response_value->IsType(base::Value::TYPE_DICTIONARY)) {
- VLOG(1) << "ParseServerResponse() : Unexpected response type "
- << response_value->GetType();
- return false;
- }
- const base::DictionaryValue* response_object =
- static_cast<base::DictionaryValue*>(response_value.get());
-
- // Get the access token, if any.
- response_object->GetString(kAccessTokenString, access_token);
-
- // Get the location
- const base::Value* location_value = NULL;
- if (!response_object->Get(kLocationString, &location_value)) {
- VLOG(1) << "ParseServerResponse() : Missing location attribute.";
- // GLS returns a response with no location property to represent
- // no fix available; return true to indicate successful parse.
- return true;
- }
- DCHECK(location_value);
-
- if (!location_value->IsType(base::Value::TYPE_DICTIONARY)) {
- if (!location_value->IsType(base::Value::TYPE_NULL)) {
- VLOG(1) << "ParseServerResponse() : Unexpected location type "
- << location_value->GetType();
- // If the network provider was unable to provide a position fix, it should
- // return a HTTP 200, with "location" : null. Otherwise it's an error.
- return false;
- }
- return true; // Successfully parsed response containing no fix.
- }
- const base::DictionaryValue* location_object =
- static_cast<const base::DictionaryValue*>(location_value);
-
- // latitude and longitude fields are always required.
- double latitude = 0;
- double longitude = 0;
- if (!GetAsDouble(*location_object, kLatitudeString, &latitude) ||
- !GetAsDouble(*location_object, kLongitudeString, &longitude)) {
- VLOG(1) << "ParseServerResponse() : location lacks lat and/or long.";
- return false;
- }
- // All error paths covered: now start actually modifying postion.
- position->latitude = latitude;
- position->longitude = longitude;
- position->timestamp = wifi_timestamp;
-
- // Other fields are optional.
- GetAsDouble(*response_object, kAccuracyString, &position->accuracy);
-
- return true;
-}
-
-} // namespace
-
-} // namespace device
« no previous file with comments | « device/geolocation/network_location_request.h ('k') | device/geolocation/wifi_data.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698