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

Unified Diff: chrome/browser/geolocation/network_location_request.cc

Issue 552250: Port the gears geolocation network provider to Chromium... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 11 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
Index: chrome/browser/geolocation/network_location_request.cc
===================================================================
--- chrome/browser/geolocation/network_location_request.cc (revision 37842)
+++ chrome/browser/geolocation/network_location_request.cc (working copy)
@@ -1,561 +1,404 @@
-// Copyright 2008, Google Inc.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// 1. Redistributions of source code must retain the above copyright notice,
-// this list of conditions and the following disclaimer.
-// 2. Redistributions in binary form must reproduce the above copyright notice,
-// this list of conditions and the following disclaimer in the documentation
-// and/or other materials provided with the distribution.
-// 3. Neither the name of Google Inc. nor the names of its contributors may be
-// used to endorse or promote products derived from this software without
-// specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
-// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
-// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
-// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
-// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
-// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
-// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Copyright (c) 2010 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.
-// TODO(joth): port to chromium
-#if 0
+#include "chrome/browser/geolocation/network_location_request.h"
-#include "gears/geolocation/network_location_request.h"
+#include "base/json/json_reader.h"
+#include "base/json/json_writer.h"
+#include "base/string_util.h"
+#include "base/values.h"
+#include "chrome/browser/geolocation/geoposition.h"
+#include "chrome/browser/net/url_request_context_getter.h"
+#include "net/url_request/url_request_status.h"
-#include "gears/blob/blob_utils.h"
-#include "gears/blob/buffer_blob.h"
-#include "gears/localserver/common/http_constants.h"
-#include "third_party/jsoncpp/reader.h"
-#include "third_party/jsoncpp/value.h"
-#include "third_party/jsoncpp/writer.h"
+namespace {
+const char* const kMimeApplicationJson = "application/json";
-static const char *kGearsNetworkLocationProtocolVersion = "1.1.0";
+// See http://code.google.com/apis/gears/geolocation_network_protocol.html
+const char* kGeoLocationNetworkProtocolVersion = "1.1.0";
-static const char *kAccessTokenString = "access_token";
-static const char *kLatitudeString = "latitude";
-static const char *kLongitudeString = "longitude";
-static const char *kAltitudeString = "altitude";
-static const char *kAccuracyString = "accuracy";
-static const char *kAltitudeAccuracyString = "altitude_accuracy";
-// Note that the corresponding JavaScript Position property is 'gearsAddress'.
-static const char *kAddressString = "address";
-static const char *kStreetNumberString = "street_number";
-static const char *kStreetString = "street";
-static const char *kPremisesString = "premises";
-static const char *kCityString = "city";
-static const char *kCountyString = "county";
-static const char *kRegionString = "region";
-static const char *kCountryString = "country";
-static const char *kCountryCodeString = "country_code";
-static const char *kPostalCodeString = "postal_code";
+const wchar_t* kAccessTokenString = L"access_token";
+const wchar_t* kLocationString = L"location";
+const wchar_t* kLatitudeString = L"latitude";
+const wchar_t* kLongitudeString = L"longitude";
+const wchar_t* kAltitudeString = L"altitude";
+const wchar_t* kAccuracyString = L"accuracy";
+const wchar_t* kAltitudeAccuracyString = L"altitude_accuracy";
// Local functions
-static const char16* RadioTypeToString(RadioType type);
+// Creates the request payload to send to the server.
+bool FormRequestBody(const string16& host_name,
+ const string16& access_token,
+ const RadioData& radio_data,
+ const WifiData& wifi_data,
+ std::string* data);
+// Parsers the server response.
+void GetLocationFromResponse(bool http_post_result,
+ int status_code,
+ const std::string& response_body,
+ int64 timestamp,
+ const GURL& server_url,
+ Position* position,
+ string16* access_token);
+
+const char* RadioTypeToString(RadioType type);
// Adds a string if it's valid to the JSON object.
-static void AddString(const std::string &property_name,
- const std::string16 &value,
- Json::Value *object);
+void AddString(const std::wstring& property_name,
+ const string16& value,
+ DictionaryValue* object);
// Adds an integer if it's valid to the JSON object.
-static void AddInteger(const std::string &property_name,
- const int &value,
- Json::Value *object);
-// Returns true if the value is a valid angle.
-static bool IsValidAngle(const double &value);
+void AddInteger(const std::wstring& property_name,
+ int value,
+ DictionaryValue* object);
// Parses the server response body. Returns true if parsing was successful.
-static bool ParseServerResponse(const std::string &response_body,
- int64 timestamp,
- bool is_reverse_geocode,
- Position *position,
- std::string16 *access_token);
-static void AddRadioData(const RadioData &radio_data, Json::Value *body_object);
-static void AddWifiData(const WifiData &wifi_data, Json::Value *body_object);
+bool ParseServerResponse(const std::string& response_body,
+ int64 timestamp,
+ Position* position,
+ string16* access_token);
+void AddRadioData(const RadioData& radio_data, DictionaryValue* body_object);
+void AddWifiData(const WifiData& wifi_data, DictionaryValue* body_object);
+} // namespace
-// static
-NetworkLocationRequest *NetworkLocationRequest::Create(
- BrowsingContext *browsing_context,
- const std::string16 &url,
- const std::string16 &host_name,
- ListenerInterface *listener) {
- scoped_ptr<NetworkLocationRequest> request(
- new NetworkLocationRequest(browsing_context, url, host_name, listener));
- assert(request.get());
- if (!request.get() || !request->Init() || !request->Start()) {
- return NULL;
- }
- return request.release();
+NetworkLocationRequest::NetworkLocationRequest(URLRequestContextGetter* context,
+ const GURL& url,
+ const string16& host_name,
+ ListenerInterface* listener)
+ : url_context_(context), timestamp_(kint64min), listener_(listener),
+ url_(url), host_name_(host_name) {
+// DCHECK(url_context_);
+ DCHECK(listener);
}
-NetworkLocationRequest::NetworkLocationRequest(
- BrowsingContext *browsing_context,
- const std::string16 &url,
- const std::string16 &host_name,
- ListenerInterface *listener)
- : AsyncTask(browsing_context),
- listener_(listener),
- url_(url),
- host_name_(host_name),
- is_shutting_down_(false) {
+NetworkLocationRequest::~NetworkLocationRequest() {
}
-bool NetworkLocationRequest::MakeRequest(const std::string16 &access_token,
- const RadioData &radio_data,
- const WifiData &wifi_data,
- bool request_address,
- const std::string16 &address_language,
- double latitude,
- double longitude,
+bool NetworkLocationRequest::MakeRequest(const string16& access_token,
+ const RadioData& radio_data,
+ const WifiData& wifi_data,
int64 timestamp) {
- is_reverse_geocode_ = request_address &&
- IsValidAngle(latitude) &&
- IsValidAngle(longitude);
+ if (url_fetcher_ != NULL) {
+ DLOG(INFO) << "NetworkLocationRequest : Cancelling pending request";
+ url_fetcher_.reset();
+ }
+ std::string post_body;
if (!FormRequestBody(host_name_, access_token, radio_data, wifi_data,
- request_address, address_language, latitude, longitude,
- is_reverse_geocode_, &post_body_)) {
+ &post_body)) {
return false;
}
timestamp_ = timestamp;
- thread_event_.Signal();
+ url_fetcher_.reset(URLFetcher::Create(
+ host_name_.size(), // Used for testing
+ url_, URLFetcher::POST, this));
+ url_fetcher_->set_upload_data(kMimeApplicationJson, post_body);
+ url_fetcher_->set_request_context(url_context_);
+ url_fetcher_->Start();
return true;
}
-// AsyncTask implementation.
-void NetworkLocationRequest::Run() {
- while (true) {
- thread_event_.Wait();
- if (is_shutting_down_) {
- break;
- }
- MakeRequestImpl();
- }
-}
+void NetworkLocationRequest::OnURLFetchComplete(const URLFetcher* source,
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data) {
+ DCHECK_EQ(url_fetcher_.get(), source);
+ DCHECK(url_.possibly_invalid_spec() == url.possibly_invalid_spec());
-void NetworkLocationRequest::MakeRequestImpl() {
- WebCacheDB::PayloadInfo payload;
- // TODO(andreip): remove this once WebCacheDB::PayloadInfo.data is a Blob.
- scoped_refptr<BlobInterface> payload_data;
- bool result = HttpPost(url_.c_str(),
- false, // Not capturing, so follow redirects
- NULL, // reason_header_value
- HttpConstants::kMimeApplicationJson, // Content-Type
- NULL, // mod_since_date
- NULL, // required_cookie
- true, // disable_browser_cookies
- post_body_.get(),
- &payload,
- &payload_data,
- NULL, // was_redirected
- NULL, // full_redirect_url
- NULL); // error_message
+ Position position;
+ string16 access_token;
+ GetLocationFromResponse(status.is_success(), response_code, data,
+ timestamp_, url, &position, &access_token);
+ const bool server_error =
+ !status.is_success() || (response_code >= 500 && response_code < 600);
+ url_fetcher_.reset();
- MutexLock lock(&is_processing_response_mutex_);
- // is_aborted_ may be true even if HttpPost succeeded.
- if (is_aborted_) {
- LOG(("NetworkLocationRequest::Run() : HttpPost request was cancelled.\n"));
- return;
- }
+ DCHECK(listener_);
+ DLOG(INFO) << "NetworkLocationRequest::Run() : "
+ "Calling listener with position.\n";
+ listener_->LocationResponseAvailable(position, server_error, access_token);
+}
- if (listener_) {
- Position position;
- std::string response_body;
- if (result) {
- // If HttpPost succeeded, payload_data is guaranteed to be non-NULL.
- assert(payload_data.get());
- if (!payload_data->Length() ||
- !BlobToString(payload_data.get(), &response_body)) {
- LOG(("NetworkLocationRequest::Run() : Failed to get response body.\n"));
- }
- }
- std::string16 access_token;
- GetLocationFromResponse(result, payload.status_code, response_body,
- timestamp_, url_, is_reverse_geocode_,
- &position, &access_token);
+// Local functions.
+namespace {
- LOG(("NetworkLocationRequest::Run() : Calling listener with position.\n"));
- bool server_error =
- !result || (payload.status_code >= 500 && payload.status_code < 600);
- listener_->LocationResponseAvailable(position, server_error, access_token);
- }
-}
+bool FormRequestBody(const string16& host_name,
+ const string16& access_token,
+ const RadioData& radio_data,
+ const WifiData& wifi_data,
+ std::string* data) {
+ DCHECK(data);
-// static
-bool NetworkLocationRequest::FormRequestBody(
- const std::string16 &host_name,
- const std::string16 &access_token,
- const RadioData &radio_data,
- const WifiData &wifi_data,
- bool request_address,
- std::string16 address_language,
- double latitude,
- double longitude,
- bool is_reverse_geocode,
- scoped_refptr<BlobInterface> *blob) {
- assert(blob);
- Json::Value body_object;
- assert(body_object.isObject());
+ DictionaryValue body_object;
// Version and host are required.
if (host_name.empty()) {
return false;
}
- body_object["version"] = Json::Value(kGearsNetworkLocationProtocolVersion);
- AddString("host", host_name, &body_object);
+ body_object.SetString(L"version", kGeoLocationNetworkProtocolVersion);
+ AddString(L"host", host_name, &body_object);
- AddString("access_token", access_token, &body_object);
+ AddString(L"access_token", access_token, &body_object);
- body_object["request_address"] = request_address;
- AddString("address_language", address_language, &body_object);
+ body_object.SetBoolean(L"request_address", false);
- if (is_reverse_geocode) {
- assert(request_address);
- assert(IsValidAngle(latitude) && IsValidAngle(longitude));
- Json::Value location;
- location["latitude"] = Json::Value(latitude);
- location["longitude"] = Json::Value(longitude);
- body_object["location"] = location;
- } else {
- AddRadioData(radio_data, &body_object);
- AddWifiData(wifi_data, &body_object);
- }
+ AddRadioData(radio_data, &body_object);
+ AddWifiData(wifi_data, &body_object);
- Json::FastWriter writer;
+ // TODO(joth): Do we need to mess with locales?
// We always use the platform independent 'C' locale when writing the JSON
// request, irrespective of the browser's locale. This avoids the need for
// the network location provider to determine the locale of the request and
// parse the JSON accordingly.
-#ifdef OS_WINCE
- // WinCE does not support setlocale.
-#else
- char *current_locale = setlocale(LC_NUMERIC, "C");
-#endif
- std::string body_string = writer.write(body_object);
-#ifdef OS_WINCE
- // WinCE does not support setlocale.
-#else
- setlocale(LC_NUMERIC, current_locale);
-#endif
- LOG(("NetworkLocationRequest::FormRequestBody(): Formed body %s.\n",
- body_string.c_str()));
+// char* current_locale = setlocale(LC_NUMERIC, "C");
- blob->reset(new BufferBlob(body_string.c_str(), body_string.size()));
+ base::JSONWriter::Write(&body_object, false, data);
+
+// setlocale(LC_NUMERIC, current_locale);
+
+ DLOG(INFO) << "NetworkLocationRequest::FormRequestBody(): Formed body "
+ << data << ".\n";
return true;
}
-// static
-void NetworkLocationRequest::GetLocationFromResponse(
- bool http_post_result,
- int status_code,
- const std::string &response_body,
- int64 timestamp,
- const std::string16 &server_url,
- bool is_reverse_geocode,
- Position *position,
- std::string16 *access_token) {
- assert(position);
- assert(access_token);
+void FormatPositionError(const GURL& server_url,
+ const std::wstring& message,
+ Position* position) {
+ position->error_code = Position::ERROR_CODE_POSITION_UNAVAILABLE;
+ position->error_message = L"Network location provider at '";
+ position->error_message += ASCIIToWide(server_url.possibly_invalid_spec());
+ position->error_message += L"' : ";
+ position->error_message += message;
+ position->error_message += L".";
+ LOG(INFO) << "NetworkLocationRequest::GetLocationFromResponse() : "
+ << position->error_message;
+}
+void GetLocationFromResponse(bool http_post_result,
+ int status_code,
+ const std::string& response_body,
+ int64 timestamp,
+ const GURL& server_url,
+ Position* position,
+ 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) {
- LOG(("NetworkLocationRequest::GetLocationFromResponse() : HttpPost request "
- "failed.\n"));
- position->error_code = Position::ERROR_CODE_POSITION_UNAVAILABLE;
- position->error_message = STRING16(L"No response from network provider "
- L"at ");
- position->error_message += server_url.c_str();
- position->error_message += STRING16(L".");
- } else if (status_code == HttpConstants::HTTP_OK) {
- // We use the timestamp from the device data that was used to generate
- // this position fix.
- if (ParseServerResponse(response_body, timestamp, is_reverse_geocode,
- position, access_token)) {
- // The response was successfully parsed, but it may not be a valid
- // position fix.
- if (!position->IsGoodFix()) {
- position->error_code = Position::ERROR_CODE_POSITION_UNAVAILABLE;
- position->error_message = STRING16(L"Network provider at ");
- position->error_message += server_url.c_str();
- position->error_message += STRING16(L" did not provide a good position "
- L"fix.");
- }
- } else {
- // We failed to parse the repsonse.
- LOG(("NetworkLocationRequest::GetLocationFromResponse() : Response "
- "malformed.\n"));
- position->error_code = Position::ERROR_CODE_POSITION_UNAVAILABLE;
- position->error_message = STRING16(L"Response from network provider at ");
- position->error_message += server_url.c_str();
- position->error_message += STRING16(L" was malformed.");
- }
- } else {
+ FormatPositionError(server_url, L"No response received", position);
+ return;
+ }
+ if (status_code != 200) { // XXX is '200' in a constant? Can't see it
// The response was bad.
- LOG(("NetworkLocationRequest::GetLocationFromResponse() : HttpPost "
- "response was bad.\n"));
- position->error_code = Position::ERROR_CODE_POSITION_UNAVAILABLE;
- position->error_message = STRING16(L"Network provider at ");
- position->error_message += server_url.c_str();
- position->error_message += STRING16(L" returned error code ");
- position->error_message += IntegerToString16(status_code);
- position->error_message += STRING16(L".");
+ std::wstring message = L"Returned error code ";
+ message += IntToWString(status_code);
+ FormatPositionError(server_url, message, position);
+ return;
}
+ // We use the timestamp from the device data that was used to generate
+ // this position fix.
+ if (!ParseServerResponse(response_body, timestamp, position, access_token)) {
+ // We failed to parse the repsonse.
+ FormatPositionError(server_url, L"Response was malformed", position);
+ return;
+ }
+ // The response was successfully parsed, but it may not be a valid
+ // position fix.
+ if (!position->IsValidFix()) {
+ FormatPositionError(server_url,
+ L"Did not provide a good position fix", position);
+ return;
+ }
}
-void NetworkLocationRequest::StopThreadAndDelete() {
- // The FF implementation of AsyncTask::Abort() delivers a message to the UI
- // thread to cancel the request. So if we call this method on the UI thread,
- // we must return to the OS before the call to Abort() will take effect. In
- // particular, we can't call Abort() then block here waiting for HttpPost to
- // return.
- is_shutting_down_ = true;
- thread_event_.Signal();
- is_processing_response_mutex_.Lock();
- Abort();
- is_processing_response_mutex_.Unlock();
- DeleteWhenDone();
-}
-
-// Local functions.
-
-static const char16* RadioTypeToString(RadioType type) {
+const char* RadioTypeToString(RadioType type) {
switch (type) {
case RADIO_TYPE_UNKNOWN:
- return STRING16(L"unknown");
+ break;
case RADIO_TYPE_GSM:
- return STRING16(L"gsm");
+ return "gsm";
case RADIO_TYPE_CDMA:
- return STRING16(L"cdma");
+ return "cdma";
case RADIO_TYPE_WCDMA:
- return STRING16(L"wcdma");
+ return "wcdma";
default:
- assert(false);
+ LOG(DFATAL) << "Bad RadioType";
}
- return NULL;
+ return "unknown";
}
-static void AddString(const std::string &property_name,
- const std::string16 &value,
- Json::Value *object) {
- assert(object);
- assert(object->isObject());
+void AddString(const std::wstring& property_name,
+ const string16& value,
+ DictionaryValue* object) {
+ DCHECK(object);
if (!value.empty()) {
- std::string value_utf8;
- if (String16ToUTF8(value.c_str(), value.size(), &value_utf8)) {
- (*object)[property_name] = Json::Value(value_utf8);
- }
+ object->SetStringFromUTF16(property_name, value);
}
}
-static void AddInteger(const std::string &property_name,
- const int &value,
- Json::Value *object) {
- assert(object);
- assert(object->isObject());
+void AddInteger(const std::wstring& property_name,
+ int value,
+ DictionaryValue* object) {
+ DCHECK(object);
if (kint32min != value) {
- (*object)[property_name] = Json::Value(value);
+ object->SetInteger(property_name, value);
}
}
-static bool IsValidAngle(const double &value) {
- return value >= -180.0 && value <= 180.0;
-}
-
// 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.
-static bool IsDoubleOrInt(const Json::Value &object,
- const std::string &property_name) {
- return object[property_name].isDouble() || object[property_name].isInt();
-}
-
-// The JsValue::asXXX() methods return zero if a property isn't specified. For
-// our purposes, zero is a valid value, so we have to test for existence.
-
-// Gets a double if it's present.
-static bool GetAsDouble(const Json::Value &object,
- const std::string &property_name,
- double *out) {
- assert(out);
- if (!IsDoubleOrInt(object, property_name)) {
+bool GetAsDouble(const DictionaryValue& object,
+ const std::wstring& property_name,
+ double* out) {
+ DCHECK(out);
+ 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;
}
- *out = object[property_name].asDouble();
- return true;
+ return value->GetAsReal(out);
}
-// Gets a string if it's present.
-static bool GetAsString(const Json::Value &object,
- const std::string &property_name,
- std::string16 *out) {
- assert(out);
- if (!object[property_name].isString()) {
- return false;
- }
- std::string out_utf8 = object[property_name].asString();
- return UTF8ToString16(out_utf8.c_str(), out_utf8.size(), out);
-}
+bool ParseServerResponse(const std::string& response_body,
+ int64 timestamp,
+ Position* position,
+ string16* access_token) {
+ DCHECK(position);
+ DCHECK(access_token);
+ DCHECK(timestamp != kint64min);
-static bool ParseServerResponse(const std::string &response_body,
- int64 timestamp,
- bool is_reverse_geocode,
- Position *position,
- std::string16 *access_token) {
- assert(position);
- assert(access_token);
-
if (response_body.empty()) {
- LOG(("ParseServerResponse() : Response was empty.\n"));
+ LOG(WARNING) << "ParseServerResponse() : Response was empty.\n";
return false;
}
- LOG(("ParseServerResponse() : Parsing response %s.\n",
- response_body.c_str()));
+ DLOG(INFO) << "ParseServerResponse() : Parsing response "
+ << response_body << ".\n";
- // Parse the response, ignoring comments. The JSON reposne from the network
+ // Parse the response, ignoring comments.
+ // TODO(joth): Gears version stated: The JSON reponse from the network
// location provider should always use the 'C' locale.
- Json::Reader reader;
- Json::Value response_object;
-#ifdef OS_WINCE
- // WinCE does not support setlocale.
-#else
- char *current_locale = setlocale(LC_NUMERIC, "C");
-#endif
- bool res = reader.parse(response_body, response_object, false);
-#ifdef OS_WINCE
- // WinCE does not support setlocale.
-#else
- setlocale(LC_NUMERIC, current_locale);
-#endif
- if (!res) {
- LOG(("ParseServerResponse() : Failed to parse response : %s.\n",
- reader.getFormatedErrorMessages().c_str()));
+ // Chromium JSON parser works in UTF8 so hopefully we can ignore setlocale?
+
+// char* current_locale = setlocale(LC_NUMERIC, "C");
+ std::string error_msg;
+ scoped_ptr<Value> response_value(base::JSONReader::ReadAndReturnError(
+ response_body, false, &error_msg));
+
+// setlocale(LC_NUMERIC, current_locale);
+
+ if (response_value == NULL) {
+ LOG(WARNING) << "ParseServerResponse() : JSONReader failed : "
+ << error_msg << ".\n";
return false;
}
- if (!response_object.isObject()) {
- LOG(("ParseServerResponse() : Unexpected response type: %d.\n",
- response_object.type()));
+ if (!response_value->IsType(Value::TYPE_DICTIONARY)) {
+ LOG(INFO) << "ParseServerResponse() : Unexpected resopnse type "
+ << response_value->GetType() << ".\n";
return false;
}
+ const DictionaryValue* response_object =
+ static_cast<DictionaryValue*>(response_value.get());
- // Get the access token.
- GetAsString(response_object, kAccessTokenString, access_token);
+ // Get the access token, if any.
+ response_object->GetStringAsUTF16(kAccessTokenString, access_token);
// Get the location
- Json::Value location = response_object["location"];
-
- // If the network provider was unable to provide a position fix, it should
- // return a 200 with location == null.
- if (location.type() == Json::nullValue) {
- LOG(("ParseServerResponse() : Location is null.\n"));
- return true;
+ DictionaryValue* location_object;
+ if (!response_object->GetDictionary(kLocationString, &location_object)) {
+ Value* value = NULL;
+ // If the network provider was unable to provide a position fix, it should
+ // return a 200 with location == null. Otherwise it's an error.
+ return response_object->Get(kLocationString, &value)
+ && value && value->IsType(Value::TYPE_NULL);
}
+ DCHECK(location_object);
- // If location is not null, it must be an object.
- if (!location.isObject()) {
- return false;
- }
-
// latitude and longitude fields are always required.
- if (!GetAsDouble(location, kLatitudeString, &position->latitude) ||
- !GetAsDouble(location, kLongitudeString, &position->longitude)) {
+ double latitude, longitude;
+ if (!GetAsDouble(*location_object, kLatitudeString, &latitude) ||
+ !GetAsDouble(*location_object, kLongitudeString, &longitude)) {
return false;
}
+ // All error paths covered: now start actually modifying postion.
+ position->latitude = latitude;
+ position->longitude = longitude;
+ position->timestamp = timestamp;
- // If it's not a reverse geocode request, the accuracy field is also required.
- if (is_reverse_geocode) {
- position->accuracy = 0.0;
- } else {
- if (!GetAsDouble(location, kAccuracyString, &position->accuracy)) {
- return false;
- }
- }
-
// Other fields are optional.
- GetAsDouble(location, kAltitudeString, &position->altitude);
- GetAsDouble(location, kAltitudeAccuracyString, &position->altitude_accuracy);
- Json::Value address = location[kAddressString];
- if (address.isObject()) {
- GetAsString(address, kStreetNumberString, &position->address.street_number);
- GetAsString(address, kStreetString, &position->address.street);
- GetAsString(address, kPremisesString, &position->address.premises);
- GetAsString(address, kCityString, &position->address.city);
- GetAsString(address, kCountyString, &position->address.county);
- GetAsString(address, kRegionString, &position->address.region);
- GetAsString(address, kCountryString, &position->address.country);
- GetAsString(address, kCountryCodeString, &position->address.country_code);
- GetAsString(address, kPostalCodeString, &position->address.postal_code);
- }
+ GetAsDouble(*location_object, kAccuracyString, &position->accuracy);
+ GetAsDouble(*location_object, kAltitudeString, &position->altitude);
+ GetAsDouble(*location_object, kAltitudeAccuracyString,
+ &position->altitude_accuracy);
- position->timestamp = timestamp;
return true;
}
-static void AddRadioData(const RadioData &radio_data,
- Json::Value *body_object) {
- assert(body_object);
+void AddRadioData(const RadioData& radio_data, DictionaryValue* body_object) {
+ DCHECK(body_object);
- AddInteger("home_mobile_country_code", radio_data.home_mobile_country_code,
+ AddInteger(L"home_mobile_country_code", radio_data.home_mobile_country_code,
body_object);
- AddInteger("home_mobile_network_code", radio_data.home_mobile_network_code,
+ AddInteger(L"home_mobile_network_code", radio_data.home_mobile_network_code,
body_object);
- AddString("radio_type", RadioTypeToString(radio_data.radio_type),
+ AddString(L"radio_type",
+ ASCIIToUTF16(RadioTypeToString(radio_data.radio_type)),
body_object);
- AddString("carrier", radio_data.carrier, body_object);
+ AddString(L"carrier", radio_data.carrier, body_object);
- Json::Value cell_towers;
- assert(cell_towers.isArray());
- int num_cell_towers = static_cast<int>(radio_data.cell_data.size());
+ const int num_cell_towers = static_cast<int>(radio_data.cell_data.size());
+ if (num_cell_towers == 0) {
+ return;
+ }
+ ListValue* cell_towers = new ListValue;
for (int i = 0; i < num_cell_towers; ++i) {
- Json::Value cell_tower;
- assert(cell_tower.isObject());
- AddInteger("cell_id", radio_data.cell_data[i].cell_id, &cell_tower);
- AddInteger("location_area_code", radio_data.cell_data[i].location_area_code,
- &cell_tower);
- AddInteger("mobile_country_code",
- radio_data.cell_data[i].mobile_country_code, &cell_tower);
- AddInteger("mobile_network_code",
- radio_data.cell_data[i].mobile_network_code, &cell_tower);
- AddInteger("age", radio_data.cell_data[i].age, &cell_tower);
- AddInteger("signal_strength", radio_data.cell_data[i].radio_signal_strength,
- &cell_tower);
- AddInteger("timing_advance", radio_data.cell_data[i].timing_advance,
- &cell_tower);
- cell_towers[i] = cell_tower;
+ DictionaryValue* cell_tower = new DictionaryValue;
+ AddInteger(L"cell_id", radio_data.cell_data[i].cell_id, cell_tower);
+ AddInteger(L"location_area_code",
+ radio_data.cell_data[i].location_area_code, cell_tower);
+ AddInteger(L"mobile_country_code",
+ radio_data.cell_data[i].mobile_country_code, cell_tower);
+ AddInteger(L"mobile_network_code",
+ radio_data.cell_data[i].mobile_network_code, cell_tower);
+ AddInteger(L"age", radio_data.cell_data[i].age, cell_tower);
+ AddInteger(L"signal_strength",
+ radio_data.cell_data[i].radio_signal_strength, cell_tower);
+ AddInteger(L"timing_advance", radio_data.cell_data[i].timing_advance,
+ cell_tower);
+ cell_towers->Append(cell_tower);
}
- if (num_cell_towers > 0) {
- (*body_object)["cell_towers"] = cell_towers;
- }
+ body_object->Set(L"cell_towers", cell_towers);
}
-static void AddWifiData(const WifiData &wifi_data, Json::Value *body_object) {
- assert(body_object);
+void AddWifiData(const WifiData& wifi_data, DictionaryValue* body_object) {
+ DCHECK(body_object);
if (wifi_data.access_point_data.empty()) {
return;
}
- Json::Value wifi_towers;
- assert(wifi_towers.isArray());
+ ListValue* wifi_towers = new ListValue;
for (WifiData::AccessPointDataSet::const_iterator iter =
wifi_data.access_point_data.begin();
iter != wifi_data.access_point_data.end();
iter++) {
- Json::Value wifi_tower;
- assert(wifi_tower.isObject());
- AddString("mac_address", iter->mac_address, &wifi_tower);
- AddInteger("signal_strength", iter->radio_signal_strength, &wifi_tower);
- AddInteger("age", iter->age, &wifi_tower);
- AddInteger("channel", iter->channel, &wifi_tower);
- AddInteger("signal_to_noise", iter->signal_to_noise, &wifi_tower);
- AddString("ssid", iter->ssid, &wifi_tower);
- wifi_towers.append(wifi_tower);
+ DictionaryValue* wifi_tower = new DictionaryValue;
+ AddString(L"mac_address", iter->mac_address, wifi_tower);
+ AddInteger(L"signal_strength", iter->radio_signal_strength, wifi_tower);
+ AddInteger(L"age", iter->age, wifi_tower);
+ AddInteger(L"channel", iter->channel, wifi_tower);
+ AddInteger(L"signal_to_noise", iter->signal_to_noise, wifi_tower);
+ AddString(L"ssid", iter->ssid, wifi_tower);
+ wifi_towers->Append(wifi_tower);
}
- (*body_object)["wifi_towers"] = wifi_towers;
+ body_object->Set(L"wifi_towers", wifi_towers);
}
-
-#endif // if 0
+} // namespace
« no previous file with comments | « chrome/browser/geolocation/network_location_request.h ('k') | chrome/browser/geolocation/wifi_data_provider_unittest_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698