| Index: content/browser/geolocation/network_location_request.cc
|
| ===================================================================
|
| --- content/browser/geolocation/network_location_request.cc (revision 162123)
|
| +++ content/browser/geolocation/network_location_request.cc (working copy)
|
| @@ -12,7 +12,9 @@
|
| #include "base/string_number_conversions.h"
|
| #include "base/utf_string_conversions.h"
|
| #include "base/values.h"
|
| +#include "content/browser/geolocation/location_arbitrator.h"
|
| #include "content/public/common/geoposition.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"
|
| @@ -23,7 +25,7 @@
|
|
|
| const size_t kMaxRequestLength = 2048;
|
|
|
| -const char kAccessTokenString[] = "access_token";
|
| +const char kAccessTokenString[] = "accessToken";
|
| const char kLocationString[] = "location";
|
| const char kLatitudeString[] = "lat";
|
| const char kLongitudeString[] = "lng";
|
| @@ -33,10 +35,12 @@
|
|
|
| // Local functions
|
| // Creates the request url to send to the server.
|
| -GURL FormRequestURL(const std::string& url,
|
| +GURL FormRequestURL(const GURL& url);
|
| +
|
| +void FormUploadData(const WifiData& wifi_data,
|
| + const base::Time& timestamp,
|
| const string16& access_token,
|
| - const WifiData& wifi_data,
|
| - const base::Time& timestamp);
|
| + std::string* upload_data);
|
|
|
| // Parsers the server response.
|
| void GetLocationFromResponse(bool http_post_result,
|
| @@ -56,7 +60,7 @@
|
| string16* access_token);
|
| void AddWifiData(const WifiData& wifi_data,
|
| int age_milliseconds,
|
| - std::vector<std::string>* params);
|
| + base::DictionaryValue* request);
|
| } // namespace
|
|
|
| int NetworkLocationRequest::url_fetcher_id_for_tests = 0;
|
| @@ -83,11 +87,13 @@
|
| wifi_data_ = wifi_data;
|
| timestamp_ = timestamp;
|
|
|
| - GURL request_url = FormRequestURL(url_.spec(), access_token,
|
| - wifi_data, timestamp_);
|
| + GURL request_url = FormRequestURL(url_);
|
| url_fetcher_.reset(net::URLFetcher::Create(
|
| - url_fetcher_id_for_tests, request_url, net::URLFetcher::GET, this));
|
| + url_fetcher_id_for_tests, request_url, net::URLFetcher::POST, this));
|
| url_fetcher_->SetRequestContext(url_context_);
|
| + std::string upload_data;
|
| + FormUploadData(wifi_data, 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 |
|
| @@ -135,10 +141,26 @@
|
| }
|
| };
|
|
|
| -GURL FormRequestURL(const std::string& url,
|
| +GURL FormRequestURL(const GURL& url) {
|
| + if (url == GeolocationArbitrator::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& timestamp,
|
| const string16& access_token,
|
| - const WifiData& wifi_data,
|
| - const base::Time& timestamp) {
|
| + std::string* upload_data) {
|
| int age = kint32min; // Invalid so AddInteger() will ignore.
|
| if (!timestamp.is_null()) {
|
| // Convert absolute timestamps into a relative age.
|
| @@ -147,55 +169,31 @@
|
| age = static_cast<int>(delta_ms);
|
| }
|
|
|
| - std::vector<std::string> params;
|
| -#if defined(GOOGLE_CHROME_BUILD)
|
| - params.push_back("browser=googlechrome");
|
| -#else
|
| - params.push_back("browser=chromium");
|
| -#endif
|
| -
|
| - params.push_back("sensor=true");
|
| + base::DictionaryValue request;
|
| + AddWifiData(wifi_data, age, &request);
|
| if (!access_token.empty())
|
| - params.push_back("token=" + UTF16ToUTF8(access_token));
|
| - AddWifiData(wifi_data, age, ¶ms);
|
| -
|
| - std::string request_string = url + '?' + JoinString(params, '&');
|
| - if (request_string.length() > kMaxRequestLength) {
|
| - size_t last_param_pos =
|
| - request_string.find_last_of('&', kMaxRequestLength);
|
| - CHECK_NE(std::string::npos, last_param_pos);
|
| - request_string.erase(last_param_pos);
|
| - }
|
| -
|
| - return GURL(request_string);
|
| + request.SetString(kAccessTokenString, access_token);
|
| + base::JSONWriter::Write(&request, upload_data);
|
| }
|
|
|
| void AddString(const std::string& property_name, const std::string& value,
|
| - std::string* wifi_params) {
|
| - DCHECK(wifi_params);
|
| - if (!value.empty()) {
|
| - if (!wifi_params->empty())
|
| - *wifi_params += '|';
|
| - *wifi_params += property_name;
|
| - *wifi_params += value;
|
| - }
|
| + base::DictionaryValue* dict) {
|
| + DCHECK(dict);
|
| + if (!value.empty())
|
| + dict->SetString(property_name, value);
|
| }
|
|
|
| void AddInteger(const std::string& property_name, int value,
|
| - std::string* wifi_params) {
|
| - DCHECK(wifi_params);
|
| - if (value != kint32min) {
|
| - if (!wifi_params->empty())
|
| - *wifi_params += '|';
|
| - *wifi_params += property_name;
|
| - *wifi_params += base::IntToString(value);
|
| - }
|
| + base::DictionaryValue* dict) {
|
| + DCHECK(dict);
|
| + if (value != kint32min)
|
| + dict->SetInteger(property_name, value);
|
| }
|
|
|
| void AddWifiData(const WifiData& wifi_data,
|
| int age_milliseconds,
|
| - std::vector<std::string>* params) {
|
| - DCHECK(params);
|
| + base::DictionaryValue* request) {
|
| + DCHECK(request);
|
|
|
| if (wifi_data.access_point_data.empty())
|
| return;
|
| @@ -210,27 +208,20 @@
|
| access_points_by_signal_strength.insert(&(*iter));
|
| }
|
|
|
| + base::ListValue* wifi_access_point_list = new base::ListValue();
|
| for (AccessPointSet::iterator iter =
|
| access_points_by_signal_strength.begin();
|
| iter != access_points_by_signal_strength.end();
|
| ++iter) {
|
| - std::string wifi_params;
|
| - AddString("mac:", UTF16ToUTF8((*iter)->mac_address), &wifi_params);
|
| - AddInteger("ss:", (*iter)->radio_signal_strength, &wifi_params);
|
| - AddInteger("age:", age_milliseconds, &wifi_params);
|
| - AddInteger("chan:", (*iter)->channel, &wifi_params);
|
| - AddInteger("snr:", (*iter)->signal_to_noise, &wifi_params);
|
| - std::string ssid = UTF16ToUTF8((*iter)->ssid);
|
| - // Backslash characters in the ssid need backslash-escaping to avoid
|
| - // escaping a following wifi parameter separator.
|
| - ReplaceSubstringsAfterOffset(&ssid, 0, "\\", "\\\\");
|
| - // Pipe characters in the ssid need backslash-escaping to avoid being
|
| - // interpreted as the wifi parameter separator.
|
| - ReplaceSubstringsAfterOffset(&ssid, 0, "|", "\\|");
|
| - AddString("ssid:", ssid, &wifi_params);
|
| - params->push_back(
|
| - "wifi=" + net::EscapeQueryParamValue(wifi_params, false));
|
| + base::DictionaryValue* wifi_dict = new base::DictionaryValue();
|
| + AddString("macAddress", UTF16ToUTF8((*iter)->mac_address), wifi_dict);
|
| + AddInteger("signalStrength", (*iter)->radio_signal_strength, wifi_dict);
|
| + AddInteger("age", age_milliseconds, wifi_dict);
|
| + AddInteger("channel", (*iter)->channel, wifi_dict);
|
| + AddInteger("signalToNoiseRatio", (*iter)->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,
|
| @@ -239,7 +230,7 @@
|
| position->error_code =
|
| content::Geoposition::ERROR_CODE_POSITION_UNAVAILABLE;
|
| position->error_message = "Network location provider at '";
|
| - position->error_message += server_url.possibly_invalid_spec();
|
| + position->error_message += server_url.GetOrigin().spec();
|
| position->error_message += "' : ";
|
| position->error_message += message;
|
| position->error_message += ".";
|
| @@ -289,7 +280,7 @@
|
| // 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 DictionaryValue& object,
|
| +bool GetAsDouble(const base::DictionaryValue& object,
|
| const std::string& property_name,
|
| double* out) {
|
| DCHECK(out);
|
| @@ -336,39 +327,9 @@
|
| << response_value->GetType();
|
| return false;
|
| }
|
| - const DictionaryValue* response_object =
|
| - static_cast<DictionaryValue*>(response_value.get());
|
| + const base::DictionaryValue* response_object =
|
| + static_cast<base::DictionaryValue*>(response_value.get());
|
|
|
| - // Check the status code.
|
| - const Value* status_value = NULL;
|
| - if (!response_object->Get(kStatusString, &status_value)) {
|
| - VLOG(1) << "ParseServerResponse() : Missing status attribute.";
|
| - // The status attribute is required.
|
| - return false;
|
| - }
|
| - DCHECK(status_value);
|
| -
|
| - if (!status_value->IsType(Value::TYPE_STRING)) {
|
| - VLOG(1) << "ParseServerResponse() : Unexpected status type "
|
| - << status_value->GetType();
|
| - // The status attribute is required to be a string.
|
| - return false;
|
| - }
|
| - const StringValue* status_object =
|
| - static_cast<const StringValue*>(status_value);
|
| -
|
| - std::string status;
|
| - if (!status_object->GetAsString(&status)) {
|
| - VLOG(1) << "ParseServerResponse() : Error parsing the status value.";
|
| - return false;
|
| - }
|
| -
|
| - if (status != kStatusOKString) {
|
| - VLOG(1) << "ParseServerResponse() : Request failed with status "
|
| - << status;
|
| - return false;
|
| - }
|
| -
|
| // Get the access token, if any.
|
| response_object->GetString(kAccessTokenString, access_token);
|
|
|
| @@ -392,8 +353,8 @@
|
| }
|
| return true; // Successfully parsed response containing no fix.
|
| }
|
| - const DictionaryValue* location_object =
|
| - static_cast<const DictionaryValue*>(location_value);
|
| + const base::DictionaryValue* location_object =
|
| + static_cast<const base::DictionaryValue*>(location_value);
|
|
|
| // latitude and longitude fields are always required.
|
| double latitude, longitude;
|
| @@ -414,3 +375,4 @@
|
| }
|
|
|
| } // namespace
|
| +
|
|
|