summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-02 18:28:08 +0000
committerjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-02-02 18:28:08 +0000
commit9732c032ed9b6664149f03472475d31844a1c8ba (patch)
treea19ee04741c6fe7f5fd0d2f84bd7bd335db9009b /chrome
parent393b7525cea33eb4030758181a01d6f9c9b7ae82 (diff)
downloadchromium_src-9732c032ed9b6664149f03472475d31844a1c8ba.zip
chromium_src-9732c032ed9b6664149f03472475d31844a1c8ba.tar.gz
chromium_src-9732c032ed9b6664149f03472475d31844a1c8ba.tar.bz2
Port the gears geolocation network provider to Chromium
BUG=http://crbug.com/11246 TEST=See http://codereview.chromium.org/556106 Review URL: http://codereview.chromium.org/552250 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@37850 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/geolocation/backoff_manager.cc83
-rw-r--r--chrome/browser/geolocation/backoff_manager.h63
-rw-r--r--chrome/browser/geolocation/device_data_provider.h32
-rw-r--r--chrome/browser/geolocation/geoposition.cc55
-rw-r--r--chrome/browser/geolocation/geoposition.h60
-rw-r--r--chrome/browser/geolocation/location_provider.cc105
-rw-r--r--chrome/browser/geolocation/location_provider.h151
-rw-r--r--chrome/browser/geolocation/location_provider_pool.cc101
-rw-r--r--chrome/browser/geolocation/location_provider_pool.h61
-rw-r--r--chrome/browser/geolocation/network_location_provider.cc547
-rw-r--r--chrome/browser/geolocation/network_location_provider.h157
-rw-r--r--chrome/browser/geolocation/network_location_request.cc741
-rw-r--r--chrome/browser/geolocation/network_location_request.h180
-rw-r--r--chrome/browser/geolocation/wifi_data_provider_unittest_win.cc7
-rw-r--r--chrome/browser/geolocation/wifi_data_provider_win.cc61
-rwxr-xr-xchrome/chrome_browser.gypi10
16 files changed, 923 insertions, 1491 deletions
diff --git a/chrome/browser/geolocation/backoff_manager.cc b/chrome/browser/geolocation/backoff_manager.cc
deleted file mode 100644
index bbdae739..0000000
--- a/chrome/browser/geolocation/backoff_manager.cc
+++ /dev/null
@@ -1,83 +0,0 @@
-// 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.
-
-// TODO(joth): port to chromium
-#if 0
-
-#include "gears/geolocation/backoff_manager.h"
-
-#include <assert.h>
-
-// The baseline minimum period between network requests.
-static const int kBaselineMinimumRequestInterval = 1000 * 5; // 5 seconds
-// The upper limit of the minimum period between network requests.
-static const int kMinimumRequestIntervalLimit = 1000 * 60 * 60 * 3; // 3 hours
-
-
-// static
-BackoffManager::ServerMap BackoffManager::servers_;
-
-// static
-Mutex BackoffManager::servers_mutex_;
-
-// static
-void BackoffManager::ReportRequest(const std::string16 &url) {
- MutexLock lock(&servers_mutex_);
- ServerMap::iterator iter = servers_.find(url);
- if (iter != servers_.end()) {
- iter->second.first = GetCurrentTimeMillis();
- } else {
- servers_[url] = std::make_pair(GetCurrentTimeMillis(),
- kBaselineMinimumRequestInterval);
- }
-}
-
-// static
-int64 BackoffManager::ReportResponse(const std::string16 &url,
- bool server_error) {
- // Use exponential back-off on server error.
- MutexLock lock(&servers_mutex_);
- ServerMap::iterator iter = servers_.find(url);
- assert(iter != servers_.end());
- int64 *interval = &iter->second.second;
- if (server_error) {
- if (*interval < kMinimumRequestIntervalLimit) {
- // Increase interval by between 90% and 110%.
- srand(static_cast<unsigned int>(GetCurrentTimeMillis()));
- double increment_proportion = 0.9 + 0.2 * rand() / RAND_MAX;
- int64 increment = static_cast<int64>(*interval * increment_proportion);
- if (increment > kMinimumRequestIntervalLimit - *interval) {
- *interval = kMinimumRequestIntervalLimit;
- } else {
- *interval += increment;
- }
- }
- } else {
- *interval = kBaselineMinimumRequestInterval;
- }
- return iter->second.first + *interval;
-}
-
-#endif // if 0
diff --git a/chrome/browser/geolocation/backoff_manager.h b/chrome/browser/geolocation/backoff_manager.h
deleted file mode 100644
index 395d0e9..0000000
--- a/chrome/browser/geolocation/backoff_manager.h
+++ /dev/null
@@ -1,63 +0,0 @@
-// 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.
-//
-// The BackoffManager class is used to implement exponential back-off for
-// network requests in case of sever errors. Users report to the BackoffManager
-// class when they make a request to or receive a response from a given url. The
-// BackoffManager class provides the earliest time at which subsequent requests
-// should be made.
-
-#ifndef GEARS_GEOLOCATION_BACKOFF_MANAGER_H__
-#define GEARS_GEOLOCATION_BACKOFF_MANAGER_H__
-
-// TODO(joth): port to chromium
-#if 0
-
-#include "gears/base/common/common.h"
-#include "gears/base/common/mutex.h"
-#include "gears/base/common/stopwatch.h" // For GetCurrentTimeMillis
-#include <map>
-
-class BackoffManager {
- public:
- static void ReportRequest(const std::string16 &url);
- static int64 ReportResponse(const std::string16 &url, bool server_error);
-
- private:
- // A map from server URL to a pair of integers representing the last request
- // time and the current minimum interval between requests, both in
- // milliseconds.
- typedef std::map<std::string16, std::pair<int64, int64> > ServerMap;
- static ServerMap servers_;
-
- // The mutex used to protect the map.
- static Mutex servers_mutex_;
-
- DISALLOW_EVIL_CONSTRUCTORS(BackoffManager);
-};
-
-#endif // if 0
-
-#endif // GEARS_GEOLOCATION_BACKOFF_MANAGER_H__
diff --git a/chrome/browser/geolocation/device_data_provider.h b/chrome/browser/geolocation/device_data_provider.h
index cef140c..9463636 100644
--- a/chrome/browser/geolocation/device_data_provider.h
+++ b/chrome/browser/geolocation/device_data_provider.h
@@ -124,7 +124,7 @@ struct AccessPointData {
age(kint32min),
channel(kint32min),
signal_to_noise(kint32min) {}
-
+ // MAC address, formatted as per MacAddressAsString16.
string16 mac_address;
int radio_signal_strength; // Measured in dBm
int age; // Milliseconds since this access point was detected
@@ -145,10 +145,17 @@ struct AccessPointDataLess : public std::less<AccessPointData> {
// All data for wifi.
struct WifiData {
// Determines whether a new set of WiFi data differs significantly from this.
- bool DiffersSignificantly(const WifiData &other) const {
- // At least 5 or 50% of access points added or removed is significant.
- static const size_t kMinChangedAccessPoints = 5;
-
+ bool DiffersSignificantly(const WifiData& other) const {
+ // More than 4 or 50% of access points added or removed is significant.
+ static const size_t kMinChangedAccessPoints = 4;
+ const size_t min_ap_count =
+ std::min(access_point_data.size(), other.access_point_data.size());
+ const size_t max_ap_count =
+ std::max(access_point_data.size(), other.access_point_data.size());
+ const size_t difference_threadhold = std::min(kMinChangedAccessPoints,
+ min_ap_count / 2);
+ if (max_ap_count > min_ap_count + difference_threadhold)
+ return true;
// Compute size of interesction of old and new sets.
size_t num_common = 0;
for (AccessPointDataSet::const_iterator iter = access_point_data.begin();
@@ -159,15 +166,10 @@ struct WifiData {
++num_common;
}
}
- assert(num_common <= access_point_data.size());
- assert(num_common <= other.access_point_data.size());
+ DCHECK(num_common <= min_ap_count);
// Test how many have changed.
- size_t added_or_removed = std::max(
- other.access_point_data.size() - num_common,
- access_point_data.size() - num_common);
- return added_or_removed >=
- std::min(kMinChangedAccessPoints, access_point_data.size() / 2);
+ return max_ap_count > num_common + difference_threadhold;
}
// Store access points as a set, sorted by MAC address. This allows quick
@@ -291,7 +293,7 @@ class DeviceDataProvider {
if (!instance_) {
instance_ = new DeviceDataProvider();
}
- assert(instance_);
+ DCHECK(instance_);
instance_->Ref();
instance_->AddListener(listener);
return instance_;
@@ -322,11 +324,11 @@ class DeviceDataProvider {
// Private constructor and destructor, callers access singleton through
// Register and Unregister.
DeviceDataProvider() : count_(0) {
- assert(factory_function_);
+ DCHECK(factory_function_);
impl_.reset((*factory_function_)());
impl_->SetContainer(this);
bool started = impl_->StartDataProvider();
- assert(started);
+ DCHECK(started);
}
virtual ~DeviceDataProvider() {}
diff --git a/chrome/browser/geolocation/geoposition.cc b/chrome/browser/geolocation/geoposition.cc
new file mode 100644
index 0000000..8618431
--- /dev/null
+++ b/chrome/browser/geolocation/geoposition.cc
@@ -0,0 +1,55 @@
+// 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.
+
+#include "chrome/browser/geolocation/geoposition.h"
+
+namespace {
+// Sentinel values to mark invalid data. (WebKit carries companion is_valid
+// bools for this purpose; we may eventually follow that approach, but
+// sentinels worked OK in the gears code this is based on.)
+const double kBadLatLng = 200;
+// Lowest point on land is at approximately -400 metres.
+const int kBadAltitude = -1000;
+const int kBadAccuracy = -1; // Accuracy must be non-negative.
+const int64 kBadTimestamp = kint64min;
+}
+
+Position::Position()
+ : latitude(kBadLatLng),
+ longitude(kBadLatLng),
+ altitude(kBadAltitude),
+ accuracy(kBadAccuracy),
+ altitude_accuracy(kBadAccuracy),
+ timestamp(kBadTimestamp),
+ error_code(ERROR_CODE_NONE) {
+}
+
+bool Position::is_valid_latlong() const {
+ return latitude >= -90.0 && latitude <= 90.0 &&
+ longitude >= -180.0 && longitude <= 180.0;
+}
+
+bool Position::is_valid_altitude() const {
+ return altitude > kBadAltitude;
+}
+
+bool Position::is_valid_accuracy() const {
+ return accuracy >= 0.0;
+}
+
+bool Position::is_valid_altitude_accuracy() const {
+ return altitude_accuracy >= 0.0;
+}
+
+bool Position::is_valid_timestamp() const {
+ return timestamp != kBadTimestamp;
+}
+
+bool Position::IsValidFix() const {
+ return is_valid_latlong() && is_valid_accuracy() && is_valid_timestamp();
+}
+
+bool Position::IsInitialized() const {
+ return error_code != ERROR_CODE_NONE || IsValidFix();
+}
diff --git a/chrome/browser/geolocation/geoposition.h b/chrome/browser/geolocation/geoposition.h
new file mode 100644
index 0000000..31e5d55
--- /dev/null
+++ b/chrome/browser/geolocation/geoposition.h
@@ -0,0 +1,60 @@
+// 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.
+
+// This file declares the Position structure, which is used to represent a
+// position fix. Originally derived from
+// http://gears.googlecode.com/svn/trunk/gears/geolocation/geolocation.h
+
+#ifndef CHROME_BROWSER_GEOLOCATION_GEOPOSITION_H_
+#define CHROME_BROWSER_GEOLOCATION_GEOPOSITION_H_
+
+#include "base/string16.h"
+
+// The internal representation of a position. Some properties use different
+// types when passed to JavaScript.
+struct Position {
+ public:
+ // Error codes for returning to JavaScript. These values are defined by the
+ // W3C spec. Note that Gears does not use all of these codes, but we need
+ // values for all of them to allow us to provide the constants on the error
+ // object.
+ enum ErrorCode {
+ ERROR_CODE_NONE = -1, // Gears addition
+ ERROR_CODE_UNKNOWN_ERROR = 0, // Not used by Gears
+ ERROR_CODE_PERMISSION_DENIED = 1, // Not used by Gears - Geolocation
+ // methods throw an exception if
+ // permission has not been granted.
+ ERROR_CODE_POSITION_UNAVAILABLE = 2,
+ ERROR_CODE_TIMEOUT = 3,
+ };
+
+ Position();
+
+ bool is_valid_latlong() const;
+ bool is_valid_altitude() const;
+ bool is_valid_accuracy() const;
+ bool is_valid_altitude_accuracy() const;
+ bool is_valid_timestamp() const;
+
+ // A valid fix has a valid latitude, longitude, accuracy and timestamp.
+ bool IsValidFix() const;
+
+ // A position is considered initialized if it has either a valid fix or
+ // an error code other than NONE.
+ bool IsInitialized() const;
+
+ // These properties correspond to the JavaScript Position object.
+ double latitude; // In degrees
+ double longitude; // In degrees
+ double altitude; // In metres
+ double accuracy; // In metres
+ double altitude_accuracy; // In metres
+ int64 timestamp; // Milliseconds since 1st Jan 1970
+
+ // These properties are returned to JavaScript as a PositionError object.
+ ErrorCode error_code;
+ std::wstring error_message; // Human-readable error message
+};
+
+#endif // CHROME_BROWSER_GEOLOCATION_GEOPOSITION_H_
diff --git a/chrome/browser/geolocation/location_provider.cc b/chrome/browser/geolocation/location_provider.cc
index 71bf33a..34d1084 100644
--- a/chrome/browser/geolocation/location_provider.cc
+++ b/chrome/browser/geolocation/location_provider.cc
@@ -1,73 +1,54 @@
-// 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.
+
// This file implements a mock location provider and the factory functions for
// creating various types of location provider.
-// TODO(joth): port to chromium
-#if 0
-
-#include "gears/geolocation/location_provider.h"
+#include "chrome/browser/geolocation/location_provider.h"
#include <assert.h>
-#include "gears/base/common/scoped_refptr.h" // For RefCount
-void LocationProviderBase::RegisterListener(ListenerInterface *listener,
- bool request_address) {
- assert(listener);
- MutexLock lock(&listeners_mutex_);
+LocationProviderBase::LocationProviderBase()
+ : client_loop_(MessageLoop::current()) {
+}
+
+LocationProviderBase::~LocationProviderBase() {
+ DCHECK_EQ(client_loop_, MessageLoop::current());
+}
+
+void LocationProviderBase::RegisterListener(ListenerInterface* listener) {
+ DCHECK(listener);
+ if (RunInClientThread(FROM_HERE,
+ &LocationProviderBase::RegisterListener, listener))
+ return;
ListenerMap::iterator iter = listeners_.find(listener);
if (iter == listeners_.end()) {
std::pair<ListenerMap::iterator, bool> result =
- listeners_.insert(
- std::make_pair(listener,
- std::make_pair(request_address, new RefCount())));
- assert(result.second);
+ listeners_.insert(std::make_pair(listener, 0));
+ DCHECK(result.second);
iter = result.first;
}
- RefCount *count = iter->second.second;
- assert(count);
- count->Ref();
+ ++iter->second;
}
void LocationProviderBase::UnregisterListener(ListenerInterface *listener) {
- assert(listener);
- MutexLock lock(&listeners_mutex_);
+ DCHECK(listener);
+ if (RunInClientThread(FROM_HERE,
+ &LocationProviderBase::UnregisterListener, listener))
+ return;
ListenerMap::iterator iter = listeners_.find(listener);
if (iter != listeners_.end()) {
- RefCount *count = iter->second.second;
- assert(count);
- if (count->Unref()) {
- delete count;
+ if (--iter->second == 0) {
listeners_.erase(iter);
}
}
}
void LocationProviderBase::UpdateListeners() {
- MutexLock lock(&listeners_mutex_);
+ // Currently we required location provider implementations to make
+ // notifications from the client thread. This could be relaxed if needed.
+ CheckRunningInClientLoop();
for (ListenerMap::const_iterator iter = listeners_.begin();
iter != listeners_.end();
++iter) {
@@ -76,7 +57,9 @@ void LocationProviderBase::UpdateListeners() {
}
void LocationProviderBase::InformListenersOfMovement() {
- MutexLock lock(&listeners_mutex_);
+ // Currently we required location provider implementations to make
+ // notifications from the client thread. This could be relaxed if needed.
+ CheckRunningInClientLoop();
for (ListenerMap::const_iterator iter = listeners_.begin();
iter != listeners_.end();
++iter) {
@@ -84,27 +67,11 @@ void LocationProviderBase::InformListenersOfMovement() {
}
}
-LocationProviderBase::ListenerMap *LocationProviderBase::GetListeners() {
- return &listeners_;
+void LocationProviderBase::CheckRunningInClientLoop() {
+ DCHECK_EQ(MessageLoop::current(), client_loop());
}
-Mutex *LocationProviderBase::GetListenersMutex() {
- return &listeners_mutex_;
-}
-
-// Win32, Linux and OSX do not have a GPS location provider.
-#if (defined(WIN32) && !defined(OS_WINCE)) || \
- defined(LINUX) || \
- defined(OS_MACOSX)
-
-LocationProviderBase *NewGpsLocationProvider(
- BrowsingContext *browsing_context,
- const std::string16 &reverse_geocode_url,
- const std::string16 &host_name,
- const std::string16 &address_language) {
+// Currently no platforms have a GPS location provider.
+LocationProviderBase* NewGpsLocationProvider() {
return NULL;
}
-
-#endif
-
-#endif // if 0
diff --git a/chrome/browser/geolocation/location_provider.h b/chrome/browser/geolocation/location_provider.h
index 5383dd8..762ccb1 100644
--- a/chrome/browser/geolocation/location_provider.h
+++ b/chrome/browser/geolocation/location_provider.h
@@ -1,28 +1,7 @@
-// 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.
+
// A location provider provides position information from a particular source
// (GPS, network etc). The GearsGeolocation object uses a set of location
// providers to obtain a position fix.
@@ -31,95 +10,135 @@
// Primarily, this class declares interface methods to be implemented by derived
// classes.
-#ifndef GEARS_GEOLOCATION_LOCATION_PROVIDER_H__
-#define GEARS_GEOLOCATION_LOCATION_PROVIDER_H__
-
-// TODO(joth): port to chromium
-#if 0
+#ifndef CHROME_BROWSER_GEOLOCATION_LOCATION_PROVIDER_H_
+#define CHROME_BROWSER_GEOLOCATION_LOCATION_PROVIDER_H_
#include <map>
-#include "gears/base/common/base_class.h"
-#include "gears/base/common/mutex.h"
-#include "gears/base/common/string16.h"
+#include "base/lock.h"
+#include "base/message_loop.h"
+#include "base/ref_counted.h"
+#include "base/string16.h"
+#include "base/task.h"
+class GURL;
struct Position;
-class RefCount;
+class URLRequestContextGetter;
// The base class used by all location providers.
-class LocationProviderBase {
+class LocationProviderBase
+ : public base::RefCountedThreadSafe<LocationProviderBase> {
public:
+ // Provides storage for the access token used in the network request.
+ // Normally the client (i.e. geolocation controller) implements this, but
+ // also allows mocking for testing.
+ class AccessTokenStore {
+ public:
+ virtual bool SetAccessToken(const GURL& url,
+ const string16& access_token) = 0;
+ virtual bool GetAccessToken(const GURL& url, string16* access_token) = 0;
+
+ protected:
+ virtual ~AccessTokenStore() {}
+ };
+
+ // Clients of the location provider must implement this interface. All call-
+ // backs to this interface will happen in the context of the thread on which
+ // the location provider was created.
class ListenerInterface {
public:
// Used to inform listener that a new position fix is available or that a
// fatal error has occurred. Providers should call this for new listeners
// as soon as a position is available.
- virtual bool LocationUpdateAvailable(LocationProviderBase *provider) = 0;
+ virtual bool LocationUpdateAvailable(LocationProviderBase* provider) = 0;
// Used to inform listener that movement has been detected. If obtaining the
// position succeeds, this will be followed by a call to
// LocationUpdateAvailable. Some providers may not be able to detect
// movement before a new fix is obtained, so will never call this method.
// Note that this is not called in response to registration of a new
// listener.
- virtual bool MovementDetected(LocationProviderBase *provider) = 0;
+ virtual bool MovementDetected(LocationProviderBase* provider) = 0;
+
+ protected:
virtual ~ListenerInterface() {}
};
- virtual ~LocationProviderBase() {}
-
+ // TODO(joth): Make register / unregister non-virtual.
// Registers a listener, which will be called back on
// ListenerInterface::LocationUpdateAvailable as soon as a position is
// available and again whenever a new position is available. Ref counts the
// listener to handle multiple calls to this method.
- virtual void RegisterListener(ListenerInterface *listener,
- bool request_address);
+ virtual void RegisterListener(ListenerInterface* listener);
// Unregisters a listener. Unrefs the listener to handle multiple calls to
// this method. Once the ref count reaches zero, the listener is removed and
// once this method returns, no further calls to
// ListenerInterface::LocationUpdateAvailable will be made for this listener.
// It may block if a callback is in progress.
- virtual void UnregisterListener(ListenerInterface *listener);
+ virtual void UnregisterListener(ListenerInterface* listener);
// Interface methods
+ // Returns false if the provider failed to start.
+ virtual bool StartProvider() = 0;
// Gets the current best position estimate.
- virtual void GetPosition(Position *position) = 0;
+ virtual void GetPosition(Position* position) = 0;
// Provides a hint to the provider that new location data is needed as soon
// as possible. Default implementation does nothing.
virtual void UpdatePosition() {}
- // Accessor methods.
- typedef std::pair<bool, RefCount*> ListenerPair;
- typedef std::map<ListenerInterface*, ListenerPair> ListenerMap;
- ListenerMap *GetListeners();
- Mutex *GetListenersMutex();
-
protected:
+ // Instances should only be destroyed via the thread safe ref count; derived
+ // classes should not have a public destructor.
+ friend class base::RefCountedThreadSafe<LocationProviderBase>;
+ LocationProviderBase();
+ virtual ~LocationProviderBase();
+
// Inform listeners that a new position or error is available, using
// LocationUpdateAvailable.
virtual void UpdateListeners();
// Inform listeners that movement has been detected, using MovementDetected.
virtual void InformListenersOfMovement();
+ MessageLoop* client_loop() { return client_loop_; }
+ void CheckRunningInClientLoop();
+
private:
+ // Utility methods to delegate method calls into the client thread
+ template <class Method>
+ bool RunInClientThread(const tracked_objects::Location& from_here,
+ Method method) {
+ if (MessageLoop::current() == client_loop_) {
+ return false;
+ }
+ client_loop_->PostTask(from_here, NewRunnableMethod(this, method));
+ return true;
+ }
+ template <class Method, class A>
+ bool RunInClientThread(const tracked_objects::Location& from_here,
+ Method method, const A& a) {
+ if (MessageLoop::current() == client_loop_) {
+ return false;
+ }
+ client_loop_->PostTask(from_here, NewRunnableMethod(this, method, a));
+ return true;
+ }
+
// The listeners registered to this provider. For each listener, we store a
- // ref count and whether it requires an address.
+ // ref count.
+ typedef std::map<ListenerInterface*, int> ListenerMap;
ListenerMap listeners_;
- Mutex listeners_mutex_;
+
+ // Reference to the client's message loop, all callbacks and access to
+ // the listeners_ member should happen in this context.
+ MessageLoop* client_loop_;
};
// Factory functions for the various types of location provider to abstract over
// the platform-dependent implementations.
-LocationProviderBase *NewMockLocationProvider();
-LocationProviderBase *NewGpsLocationProvider(
- BrowsingContext *browsing_context,
- const std::string16 &reverse_geocode_url,
- const std::string16 &host_name,
- const std::string16 &address_language);
-LocationProviderBase *NewNetworkLocationProvider(
- BrowsingContext *browsing_context,
- const std::string16 &url,
- const std::string16 &host_name,
- const std::string16 &language);
-
-#endif // if 0
-
-#endif // GEARS_GEOLOCATION_LOCATION_PROVIDER_H__
+LocationProviderBase* NewMockLocationProvider();
+LocationProviderBase* NewGpsLocationProvider();
+LocationProviderBase* NewNetworkLocationProvider(
+ LocationProviderBase::AccessTokenStore* access_token_store,
+ URLRequestContextGetter* context,
+ const GURL& url,
+ const string16& host_name);
+
+#endif // CHROME_BROWSER_GEOLOCATION_LOCATION_PROVIDER_H_
diff --git a/chrome/browser/geolocation/location_provider_pool.cc b/chrome/browser/geolocation/location_provider_pool.cc
index 32d6f92..8ca57ba 100644
--- a/chrome/browser/geolocation/location_provider_pool.cc
+++ b/chrome/browser/geolocation/location_provider_pool.cc
@@ -1,27 +1,6 @@
-// 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
@@ -35,10 +14,10 @@ static const char16 *kGpsString = STRING16(L"GPS");
static const char16 *kNetworkString = STRING16(L"NETWORK");
// Local functions
-static std::string16 MakeKey(const std::string16 &type,
- const std::string16 &url,
- const std::string16 &host,
- const std::string16 &language);
+static string16 MakeKey(const string16& type,
+ const string16& url,
+ const string16& host,
+ const string16& language);
// static member variables
LocationProviderPool LocationProviderPool::instance_;
@@ -52,7 +31,7 @@ LocationProviderPool::~LocationProviderPool() {
// The lack of unload monitoring on IE Mobile on WinCE means that we may leak
// providers.
#else
- assert(providers_.empty());
+ DCHECK(providers_.empty());
#endif // BROWSER_IEMOBILE
}
@@ -61,17 +40,17 @@ LocationProviderPool *LocationProviderPool::GetInstance() {
return &instance_;
}
-LocationProviderBase *LocationProviderPool::Register(
- BrowsingContext *browsing_context,
- const std::string16 &type,
- const std::string16 &url,
- const std::string16 &host,
+LocationProviderBase* LocationProviderPool::Register(
+ BrowsingContext* browsing_context,
+ const string16& type,
+ const string16& url,
+ const string16& host,
bool request_address,
- const std::string16 &language,
- LocationProviderBase::ListenerInterface *listener) {
- assert(listener);
+ const string16& language,
+ LocationProviderBase::ListenerInterface* listener) {
+ DCHECK(listener);
MutexLock lock(&providers_mutex_);
- std::string16 key = MakeKey(type, url, host, language);
+ string16 key = MakeKey(type, url, host, language);
ProviderMap::iterator iter = providers_.find(key);
if (iter == providers_.end()) {
LocationProviderBase *provider = NewProvider(browsing_context, type, url,
@@ -83,32 +62,32 @@ LocationProviderBase *LocationProviderPool::Register(
providers_.insert(
std::make_pair(key,
std::make_pair(provider, new RefCount())));
- assert(result.second);
+ DCHECK(result.second);
iter = result.first;
}
LocationProviderBase *provider = iter->second.first;
- assert(provider);
+ DCHECK(provider);
provider->RegisterListener(listener, request_address);
- RefCount *count = iter->second.second;
- assert(count);
+ RefCount* count = iter->second.second;
+ DCHECK(count);
count->Ref();
return provider;
}
bool LocationProviderPool::Unregister(
- LocationProviderBase *provider,
- LocationProviderBase::ListenerInterface *listener) {
- assert(provider);
- assert(listener);
+ LocationProviderBase* provider,
+ LocationProviderBase::ListenerInterface* listener) {
+ DCHECK(provider);
+ DCHECK(listener);
MutexLock lock(&providers_mutex_);
for (ProviderMap::iterator iter = providers_.begin();
iter != providers_.end();
++iter) {
- LocationProviderBase *current_provider = iter->second.first;
+ LocationProviderBase* current_provider = iter->second.first;
if (current_provider == provider) {
current_provider->UnregisterListener(listener);
RefCount *count = iter->second.second;
- assert(count);
+ DCHECK(count);
if (count->Unref()) {
delete current_provider;
delete count;
@@ -125,12 +104,12 @@ void LocationProviderPool::UseMockLocationProvider(
use_mock_location_provider_ = use_mock_location_provider;
}
-LocationProviderBase *LocationProviderPool::NewProvider(
- BrowsingContext *browsing_context,
- const std::string16 &type,
- const std::string16 &url,
- const std::string16 &host,
- const std::string16 &language) {
+LocationProviderBase* LocationProviderPool::NewProvider(
+ BrowsingContext* browsing_context,
+ const string16& type,
+ const string16& url,
+ const string16& host,
+ const string16& language) {
if (type == kMockString) {
// use_mock_location_provider_ can only be set to true in a build that uses
// USING_CCTESTS.
@@ -148,22 +127,22 @@ LocationProviderBase *LocationProviderPool::NewProvider(
} else if (type == kNetworkString) {
return NewNetworkLocationProvider(browsing_context, url, host, language);
}
- assert(false);
+ DCHECK(false);
return NULL;
}
// Local function
-static std::string16 MakeKey(const std::string16 &type,
- const std::string16 &url,
- const std::string16 &host,
- const std::string16 &language) {
+static string16 MakeKey(const string16& type,
+ const string16& url,
+ const string16& host,
+ const string16& language) {
// Network requests are made from a specific host and use a specific language.
// Therefore we must key network and GPS providers on server URL, host and
// language.
if (type == kMockString) {
return type;
} else if (type == kGpsString || type == kNetworkString) {
- std::string16 key = type;
+ string16 key = type;
if (!url.empty()) {
key += STRING16(L" url=") + url;
}
@@ -175,7 +154,7 @@ static std::string16 MakeKey(const std::string16 &type,
}
return key;
}
- assert(false);
+ DCHECK(false);
return STRING16(L"");
}
diff --git a/chrome/browser/geolocation/location_provider_pool.h b/chrome/browser/geolocation/location_provider_pool.h
index c15e54f..4ba09d5 100644
--- a/chrome/browser/geolocation/location_provider_pool.h
+++ b/chrome/browser/geolocation/location_provider_pool.h
@@ -1,30 +1,9 @@
-// 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.
-#ifndef GEARS_GEOLOCATION_LOCATION_PROVIDER_POOL_H__
-#define GEARS_GEOLOCATION_LOCATION_PROVIDER_POOL_H__
+#ifndef CHROME_BROWSER_GEOLOCATION_LOCATION_PROVIDER_POOL_H_
+#define CHROME_BROWSER_GEOLOCATION_LOCATION_PROVIDER_POOL_H_
// TODO(joth): port to chromium
#if 0
@@ -46,36 +25,36 @@ class LocationProviderPool {
// Registers a listener with a given type of location provider. Creates the
// provider if the pool does not alrerady contain an instance of that
// provider. Returns the provider, or NULL if it cannot be created.
- LocationProviderBase *Register(
- BrowsingContext *browsing_context,
- const std::string16 &type,
- const std::string16 &url,
- const std::string16 &host,
+ LocationProviderBase* Register(
+ BrowsingContext* browsing_context,
+ const string16& type,
+ const string16& url,
+ const string16& host,
bool request_address,
- const std::string16 &language,
+ const string16& language,
LocationProviderBase::ListenerInterface *listener);
// Unregister a listener from a given location provider. Deletes the provider
// if there are no remaining listeners registered with it. Return value
// indicates whether the provider was found in the pool.
- bool Unregister(LocationProviderBase *provider,
- LocationProviderBase::ListenerInterface *listener);
+ bool Unregister(LocationProviderBase* provider,
+ LocationProviderBase::ListenerInterface* listener);
// Configures the pool to return a mock location provider for the type "MOCK".
// This method is used only by the Gears test object.
void UseMockLocationProvider(bool use_mock_location_provider);
- LocationProviderBase *NewProvider(BrowsingContext *browsing_context,
- const std::string16 &type,
- const std::string16 &url,
- const std::string16 &host,
- const std::string16 &language);
+ LocationProviderBase *NewProvider(BrowsingContext* browsing_context,
+ const string16& type,
+ const string16& url,
+ const string16& host,
+ const string16& language);
private:
static LocationProviderPool instance_;
typedef std::pair<LocationProviderBase*, RefCount*> ProviderPair;
- typedef std::map<std::string16, ProviderPair> ProviderMap;
+ typedef std::map<string16, ProviderPair> ProviderMap;
ProviderMap providers_;
Mutex providers_mutex_;
@@ -86,4 +65,4 @@ class LocationProviderPool {
#endif // if 0
-#endif // GEARS_GEOLOCATION_LOCATION_PROVIDER_POOL_H__
+#endif // CHROME_BROWSER_GEOLOCATION_LOCATION_PROVIDER_POOL_H_
diff --git a/chrome/browser/geolocation/network_location_provider.cc b/chrome/browser/geolocation/network_location_provider.cc
index df4c8cb..948207d 100644
--- a/chrome/browser/geolocation/network_location_provider.cc
+++ b/chrome/browser/geolocation/network_location_provider.cc
@@ -1,77 +1,56 @@
-// 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.
-
-// TODO(joth): port to chromium
-#if 0
-
-#include "gears/geolocation/network_location_provider.h"
-
-#include "gears/base/common/base_class.h"
-#include "gears/base/common/stopwatch.h" // For GetCurrentTimeMillis
-#include "gears/geolocation/access_token_manager.h"
-#include "gears/geolocation/backoff_manager.h"
+// 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.
+#include "chrome/browser/geolocation/network_location_provider.h"
+
+#include "base/time.h"
+
+namespace {
// The maximum period of time we'll wait for a complete set of device data
// before sending the request.
-static const int kDataCompleteWaitPeriod = 1000 * 2; // 2 seconds
+const int kDataCompleteWaitPeriod = 1000 * 2; // 2 seconds
// The maximum size of the cache of positions for previously requested device
// data.
-static const size_t kMaximumCacheSize = 10;
+const size_t kMaximumCacheSize = 10;
+// TODO(joth): Share, or remove usage by porting callers to Time et al.
+int64 GetCurrentTimeMillis() {
+ return static_cast<int64>(base::Time::Now().ToDoubleT() * 1000);
+}
+} // namespace
// The PositionCache handles caching and retrieving a position returned by a
// network location provider. It is not thread safe. It's methods are called on
// multiple threads by NetworkLocationProvider, but the timing is such that
// thread safety is not required.
-class PositionCache {
+class NetworkLocationProvider::PositionCache {
public:
// Caches the current position response for the current set of cell ID and
// WiFi data. Returns true on success, false otherwise.
- bool CachePosition(const RadioData &radio_data,
- const WifiData &wifi_data,
- const Position &position) {
+ bool CachePosition(const RadioData& radio_data,
+ const WifiData& wifi_data,
+ const Position& position) {
// Check that we can generate a valid key for the device data.
- std::string16 key;
+ string16 key;
if (!MakeKey(radio_data, wifi_data, &key)) {
return false;
}
// If the cache is full, remove the oldest entry.
if (cache_.size() == kMaximumCacheSize) {
- assert(cache_times_.size() == kMaximumCacheSize);
+ DCHECK(cache_times_.size() == kMaximumCacheSize);
CacheTimesMap::iterator oldest_entry = cache_times_.begin();
- assert(oldest_entry != cache_times_.end());
+ DCHECK(oldest_entry != cache_times_.end());
cache_.erase(oldest_entry->second);
cache_times_.erase(oldest_entry);
}
// Insert the position into the cache.
std::pair<CacheMap::iterator, bool> result =
cache_.insert(std::make_pair(key, position));
- assert(result.second);
+ DCHECK(result.second);
cache_times_[position.timestamp] = result.first;
- assert(cache_.size() == cache_times_.size());
+ DCHECK(cache_.size() == cache_times_.size());
return true;
}
@@ -79,7 +58,7 @@ class PositionCache {
// WiFi data. Returns the cached position if available, NULL otherwise.
const Position *FindPosition(const RadioData &radio_data,
const WifiData &wifi_data) {
- std::string16 key;
+ string16 key;
if (!MakeKey(radio_data, wifi_data, &key)) {
return NULL;
}
@@ -90,419 +69,225 @@ class PositionCache {
// Makes the key for the map of cached positions, using a set of
// device data. Returns true if a good key was generated, false otherwise.
static bool MakeKey(const RadioData& /*radio_data*/,
- const WifiData &wifi_data,
- std::string16 *key) {
+ const WifiData& wifi_data,
+ string16* key) {
// Currently we use only the WiFi data, and base the key only on the MAC
// addresses.
// TODO(steveblock): Make use of radio_data.
+ DCHECK(key);
key->clear();
+ key->reserve(wifi_data.access_point_data.size() * 19);
+ const string16 separator(ASCIIToUTF16("|"));
for (WifiData::AccessPointDataSet::const_iterator iter =
wifi_data.access_point_data.begin();
iter != wifi_data.access_point_data.begin();
iter++) {
- key->append(STRING16(L"|") + iter->mac_address + STRING16(L"|"));
+ *key += separator;
+ *key += iter->mac_address;
+ *key += separator;
}
// If the key is the empty string, return false, as we don't want to cache a
// position for such a set of device data.
return !key->empty();
}
-private:
+ private:
// The cache of positions. This is stored using two maps. One map is keyed on
// a string that represents a set of device data, the other is keyed on the
// timestamp of the position.
- typedef std::map<std::string16, Position> CacheMap;
+ typedef std::map<string16, Position> CacheMap;
CacheMap cache_;
typedef std::map<int64, CacheMap::iterator> CacheTimesMap;
CacheTimesMap cache_times_;
};
-
// NetworkLocationProvider factory function
-LocationProviderBase *NewNetworkLocationProvider(
- BrowsingContext *browsing_context,
- const std::string16 &url,
- const std::string16 &host_name,
- const std::string16 &language) {
- return new NetworkLocationProvider(browsing_context, url, host_name,
- language);
+LocationProviderBase* NewNetworkLocationProvider(
+ LocationProviderBase::AccessTokenStore* access_token_store,
+ URLRequestContextGetter* context,
+ const GURL& url,
+ const string16& host_name) {
+ return new NetworkLocationProvider(access_token_store, context,
+ url, host_name);
}
-
// NetworkLocationProvider
NetworkLocationProvider::NetworkLocationProvider(
- BrowsingContext *browsing_context,
- const std::string16 &url,
- const std::string16 &host_name,
- const std::string16 &language)
- : request_(NULL),
- url_(url),
- host_name_(host_name),
- request_address_(false),
- request_address_from_last_request_(false),
- address_language_(language),
- is_shutting_down_(false),
+ AccessTokenStore* access_token_store,
+ URLRequestContextGetter* url_context_getter,
+ const GURL& url,
+ const string16& host_name)
+ : access_token_store_(access_token_store),
+ radio_data_provider_(NULL),
+ wifi_data_provider_(NULL),
+ is_radio_data_complete_(false),
+ is_wifi_data_complete_(false),
+ device_data_updated_timestamp_(kint64min),
is_new_data_available_(false),
- is_new_listener_waiting_(false),
- browsing_context_(browsing_context) {
- // TODO(steveblock): Consider allowing multiple values for "address_language"
- // in the network protocol to allow better sharing of network location
- // providers.
-
- // Get the device data providers. The first call to Register will create the
- // provider and it will be deleted by ref counting.
- radio_data_provider_ = RadioDataProvider::Register(this);
- wifi_data_provider_ = WifiDataProvider::Register(this);
-
- AccessTokenManager::GetInstance()->Register(url_);
-
+ ALLOW_THIS_IN_INITIALIZER_LIST(delayed_start_task_(this)) {
// Create the position cache.
position_cache_.reset(new PositionCache());
- // Start the worker thread
- if (!Start()) {
- // This should never happen.
- LOG(("Could not start the NLR"));
- assert(false);
- }
+ request_.reset(new NetworkLocationRequest(url_context_getter, url,
+ host_name, this));
}
NetworkLocationProvider::~NetworkLocationProvider() {
- // Shut down the worker thread
- is_shutting_down_ = true;
- thread_notification_event_.Signal();
- Join();
-
- // Must keep the request around until our worker thread has stopped.
- if (request_) {
- request_->StopThreadAndDelete();
- request_ = NULL;
- }
-
- radio_data_provider_->Unregister(this);
- wifi_data_provider_->Unregister(this);
-
- AccessTokenManager::GetInstance()->Unregister();
-}
-
-void NetworkLocationProvider::RegisterListener(
- LocationProviderBase::ListenerInterface *listener,
- bool request_address) {
- // Determine whether this listener requires an address when the last request
- // does not.
- bool new_listener_requires_address =
- !request_address_from_last_request_ && request_address;
-
- // Update whether or not we need to request an address.
- request_address_ |= request_address;
-
- // If we now need to request an address when we did not before, we don't add
- // the listener. This is because if a request is currently in progress, we
- // don't want the new listener to be called back with a position without an
- // address. We add the listener when we make the next request.
- if (new_listener_requires_address) {
- MutexLock lock(&new_listeners_requiring_address_mutex_);
- new_listeners_requiring_address_.insert(listener);
- } else {
- LocationProviderBase::RegisterListener(listener, request_address);
- }
-
- // Signal to the worker thread that there is a new listener.
- is_new_listener_waiting_ = true;
- thread_notification_event_.Signal();
-}
-
-void NetworkLocationProvider::UnregisterListener(
- LocationProviderBase::ListenerInterface *listener) {
- assert(listener);
-
- // First try removing the listener from the set of new listeners waiting for
- // an address. Otherwise, try the regular listeners.
- MutexLock new_listeners_lock(&new_listeners_requiring_address_mutex_);
- ListenerSet::iterator iter = new_listeners_requiring_address_.find(listener);
- if (iter != new_listeners_requiring_address_.end()) {
- new_listeners_requiring_address_.erase(iter);
- } else {
- LocationProviderBase::UnregisterListener(listener);
- }
-
- // Update whether or not we need to request an address.
- if (request_address_) {
- if (!new_listeners_requiring_address_.empty()) {
- return;
- }
- MutexLock listeners_lock(GetListenersMutex());
- ListenerMap *listeners = GetListeners();
- for (ListenerMap::const_iterator iter = listeners->begin();
- iter != listeners->end();
- iter++) {
- if (iter->second.first == true) {
- return;
- }
- }
- request_address_ = false;
- }
+ if (radio_data_provider_)
+ radio_data_provider_->Unregister(this);
+ if (wifi_data_provider_)
+ wifi_data_provider_->Unregister(this);
}
// LocationProviderBase implementation
void NetworkLocationProvider::GetPosition(Position *position) {
- assert(position);
- MutexLock lock(&position_mutex_);
+ DCHECK(position);
+ AutoLock lock(position_mutex_);
*position = position_;
}
+void NetworkLocationProvider::UpdatePosition() {
+ if (is_new_data_available_) {
+ RequestPosition();
+ }
+}
+
// DeviceDataProviderInterface::ListenerInterface implementation.
void NetworkLocationProvider::DeviceDataUpdateAvailable(
- RadioDataProvider *provider) {
- MutexLock lock(&data_mutex_);
- assert(provider == radio_data_provider_);
- is_radio_data_complete_ = radio_data_provider_->GetData(&radio_data_);
-
- DeviceDataUpdateAvailableImpl();
+ RadioDataProvider* provider) {
+ {
+ AutoLock lock(data_mutex_);
+ DCHECK(provider == radio_data_provider_);
+ is_radio_data_complete_ = radio_data_provider_->GetData(&radio_data_);
+ }
+ OnDeviceDataUpdated();
}
void NetworkLocationProvider::DeviceDataUpdateAvailable(
- WifiDataProvider *provider) {
- assert(provider == wifi_data_provider_);
- MutexLock lock(&data_mutex_);
- is_wifi_data_complete_ = wifi_data_provider_->GetData(&wifi_data_);
-
- DeviceDataUpdateAvailableImpl();
+ WifiDataProvider* provider) {
+ {
+ AutoLock lock(data_mutex_);
+ DCHECK(provider == wifi_data_provider_);
+ is_wifi_data_complete_ = wifi_data_provider_->GetData(&wifi_data_);
+ }
+ OnDeviceDataUpdated();
}
// NetworkLocationRequest::ListenerInterface implementation.
void NetworkLocationProvider::LocationResponseAvailable(
- const Position &position,
+ const Position& position,
bool server_error,
- const std::string16 &access_token) {
+ const string16& access_token) {
+ CheckRunningInClientLoop();
// Record the position and update our cache.
- position_mutex_.Lock();
- position_ = position;
- if (position_.IsGoodFix()) {
- MutexLock lock(&data_mutex_);
- position_cache_->CachePosition(radio_data_, wifi_data_, position_);
+ {
+ AutoLock position_lock(position_mutex_);
+ position_ = position;
+ }
+ if (position.IsValidFix()) {
+ AutoLock lock(data_mutex_);
+ position_cache_->CachePosition(radio_data_, wifi_data_, position);
}
- position_mutex_.Unlock();
// Record access_token if it's set.
- if (!access_token.empty()) {
- AccessTokenManager::GetInstance()->SetToken(url_, access_token);
+ if (!access_token.empty() && access_token_ != access_token) {
+ access_token_ = access_token;
+ access_token_store_->SetAccessToken(request_->url(), access_token);
}
- // Get earliest time for next request.
- earliest_next_request_time_ = BackoffManager::ReportResponse(url_,
- server_error);
-
- // Signal to the worker thread that this request has completed.
- is_last_request_complete_ = true;
- thread_notification_event_.Signal();
-
+ // If new data arrived whilst request was pending reissue the request.
+ UpdatePosition();
// Let listeners know that we now have a position available.
UpdateListeners();
}
-// Thread implementation
-void NetworkLocationProvider::Run() {
- // Create the network request object. We must do this on the same thread from
- // which we'll call Start().
- request_ = NetworkLocationRequest::Create(browsing_context_, url_,
- host_name_, this);
- if (!request_) {
- LOG(("Failed to create NetworkLocationRequest object.\n"));
- assert(false);
- return;
+bool NetworkLocationProvider::StartProvider() {
+ CheckRunningInClientLoop();
+ DCHECK(radio_data_provider_ == NULL);
+ DCHECK(wifi_data_provider_ == NULL);
+ if (!request_->url().is_valid()) {
+ LOG(WARNING) << "StartProvider() : Failed, Bad URL: "
+ << request_->url().possibly_invalid_spec();
+ return false;
}
+ // Get the device data providers. The first call to Register will create the
+ // provider and it will be deleted by ref counting.
+ radio_data_provider_ = RadioDataProvider::Register(this);
+ wifi_data_provider_ = WifiDataProvider::Register(this);
+
+ MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ delayed_start_task_.NewRunnableMethod(
+ &NetworkLocationProvider::RequestPosition),
+ kDataCompleteWaitPeriod);
+ {
// Get the device data.
- data_mutex_.Lock();
+ AutoLock lock(data_mutex_);
is_radio_data_complete_ = radio_data_provider_->GetData(&radio_data_);
is_wifi_data_complete_ = wifi_data_provider_->GetData(&wifi_data_);
- timestamp_ = GetCurrentTimeMillis();
-
- // For the first request, wait for a certain maximum time period to get as
- // much device data as possible.
- int64 start_time = timestamp_;
- while (true) {
- if (is_radio_data_complete_ && is_wifi_data_complete_) {
- data_mutex_.Unlock();
- break;
- }
- data_mutex_.Unlock();
-
- int64 elapsed_time = GetCurrentTimeMillis() - start_time;
- int timeout = kDataCompleteWaitPeriod - static_cast<int>(elapsed_time);
- if (timeout <= 0) {
- break;
- }
- if (!thread_notification_event_.WaitWithTimeout(timeout)) {
- // Quit waiting if we time out.
- break;
- }
- // Terminate the thread if requested.
- if (is_shutting_down_) {
- return;
- }
- // The event should be due to new device data or a new listener.
- assert(is_new_data_available_ || is_new_listener_waiting_);
- // If we have new data available, inform listeners of movement.
- if (is_new_data_available_) {
- InformListenersOfMovement();
- }
- // Lock the data mutex to test is_radio_data_complete_ and
- // is_wifi_data_complete_ on the next loop.
- data_mutex_.Lock();
- }
-
- earliest_next_request_time_ = 0;
- MakeRequest();
-
- // Loop continually, making requests whenever new data becomes available,
- // subject to the minimum interval.
- //
- // This loop is structured such that we don't require mutex locks to
- // synchronise changes to is_new_data_available_ etc with signals on
- // thread_notification_event_. Note that if we get a signal before we wait,
- // the wait will proceed immediately, so we don't miss signals.
- int64 remaining_time = 1;
- while (!is_shutting_down_) {
- if (remaining_time > 0) {
- remaining_time = earliest_next_request_time_ - GetCurrentTimeMillis();
- }
-
- // If the minimum time period has not yet elapsed, set the timeout such
- // that the wait expires when the period has elapsed.
- if (remaining_time > 0) {
- thread_notification_event_.WaitWithTimeout(
- static_cast<int>(remaining_time));
- } else {
- thread_notification_event_.Wait();
- }
-
- // Update remaining time now we've woken up. Note that it can never
- // transition from <= 0 to > 0.
- if (remaining_time > 0) {
- remaining_time = earliest_next_request_time_ - GetCurrentTimeMillis();
- }
-
- bool make_request = false;
- if (is_new_listener_waiting_) {
- // A new listener has just registered with this provider. If new data is
- // available, force a new request now, unless a request is already in
- // progress. If not, update listeners with the last known position,
- // provided we have one.
- if (is_new_data_available_) {
- if (is_last_request_complete_) {
- make_request = true;
- }
- } else {
- // Before the first network request completes, position_ may not be
- // valid, so we do not update the listeners. They will be updated once
- // the network request completes.
- if (position_.IsInitialized()) {
- // Update listeners with the last known position.
- UpdateListeners();
- }
- }
- is_new_listener_waiting_ = false;
- }
-
- // If a new listener has now registered such that we now require an address,
- // we make a new request once the current request completes.
- new_listeners_requiring_address_mutex_.Lock();
- if (!new_listeners_requiring_address_.empty()) {
- if (is_last_request_complete_) {
- make_request = true;
- }
- }
- new_listeners_requiring_address_mutex_.Unlock();
-
- // If the thread is not shutting down, we have new data, the last request
- // has completed, and the minimum time has elapsed, make the next request.
- if (!is_shutting_down_ &&
- is_new_data_available_ &&
- is_last_request_complete_ &&
- remaining_time <= 0) {
- make_request = true;
- }
-
- // If we have new data available, inform listeners of movement.
- if (is_new_data_available_) {
- InformListenersOfMovement();
- }
-
- // TODO(steveblock): If the request does not complete within some maximum
- // time period, we should kill it and start a new request.
- if (make_request) {
- MakeRequest();
- remaining_time = 1;
- }
}
+ if (is_radio_data_complete_ || is_wifi_data_complete_)
+ OnDeviceDataUpdated();
+ return true;
}
// Other methods
-
-bool NetworkLocationProvider::MakeRequest() {
- // If we have new listeners waiting for an address, request_address_
- // must be true.
- assert(new_listeners_requiring_address_.empty() || request_address_);
-
- // Move the new listeners waiting for an address to the list of listeners.
- MutexLock lock(&new_listeners_requiring_address_mutex_);
- for (ListenerSet::const_iterator iter =
- new_listeners_requiring_address_.begin();
- iter != new_listeners_requiring_address_.end();
- iter++) {
- LocationProviderBase::RegisterListener(*iter, true);
+void NetworkLocationProvider::RequestPosition() {
+ CheckRunningInClientLoop();
+
+ delayed_start_task_.RevokeAll();
+ const Position* cached_position;
+ {
+ AutoLock lock(data_mutex_);
+ cached_position = position_cache_->FindPosition(radio_data_, wifi_data_);
}
- new_listeners_requiring_address_.clear();
-
- request_address_from_last_request_ = request_address_;
-
- BackoffManager::ReportRequest(url_);
-
- std::string16 access_token;
- AccessTokenManager::GetInstance()->GetToken(url_, &access_token);
-
- // Reset flags
- is_new_data_available_ = false;
- is_new_listener_waiting_ = false;
-
- data_mutex_.Lock();
- const Position *cached_position =
- position_cache_->FindPosition(radio_data_, wifi_data_);
- data_mutex_.Unlock();
+ DCHECK_NE(device_data_updated_timestamp_, kint64min) <<
+ "Timestamp must be set before looking up position";
if (cached_position) {
- assert(cached_position->IsGoodFix());
+ DCHECK(cached_position->IsValidFix());
// Record the position and update its timestamp.
- position_mutex_.Lock();
- position_ = *cached_position;
- position_.timestamp = timestamp_;
- position_mutex_.Unlock();
-
+ {
+ AutoLock lock(position_mutex_);
+ position_ = *cached_position;
+ // The timestamp of a position fix is determined by the timestamp
+ // of the source data update. (The value of position_.timestamp from
+ // the cache could be from weeks ago!)
+ position_.timestamp = device_data_updated_timestamp_;
+ }
+ is_new_data_available_ = false;
// Let listeners know that we now have a position available.
UpdateListeners();
- return true;
+ return;
}
- assert(request_);
- is_last_request_complete_ = false;
- MutexLock data_lock(&data_mutex_);
- return request_->MakeRequest(access_token,
- radio_data_,
- wifi_data_,
- request_address_,
- address_language_,
- kBadLatLng, // We don't have a position to pass
- kBadLatLng, // to the server.
- timestamp_);
-}
+ DCHECK(request_ != NULL);
+
+ // TODO(joth): Consider timing out any pending request.
+ if (request_->is_request_pending())
+ return;
+
+ is_new_data_available_ = false;
-void NetworkLocationProvider::DeviceDataUpdateAvailableImpl() {
- timestamp_ = GetCurrentTimeMillis();
+ if (access_token_.empty())
+ access_token_store_->GetAccessToken(request_->url(), &access_token_);
- // Signal to the worker thread that new data is available.
- is_new_data_available_ = true;
- thread_notification_event_.Signal();
+ AutoLock data_lock(data_mutex_);
+ request_->MakeRequest(access_token_, radio_data_, wifi_data_,
+ device_data_updated_timestamp_);
}
-#endif // if 0
+void NetworkLocationProvider::OnDeviceDataUpdated() {
+ if (MessageLoop::current() != client_loop()) {
+ client_loop()->PostTask(FROM_HERE,
+ NewRunnableMethod(this, &NetworkLocationProvider::OnDeviceDataUpdated));
+ return;
+ }
+ device_data_updated_timestamp_ = GetCurrentTimeMillis();
+
+ is_new_data_available_ = is_radio_data_complete_ || is_radio_data_complete_;
+ if (delayed_start_task_.empty() ||
+ (is_radio_data_complete_ && is_radio_data_complete_)) {
+ UpdatePosition();
+ }
+}
diff --git a/chrome/browser/geolocation/network_location_provider.h b/chrome/browser/geolocation/network_location_provider.h
index fed0001..94e5b5b 100644
--- a/chrome/browser/geolocation/network_location_provider.h
+++ b/chrome/browser/geolocation/network_location_provider.h
@@ -1,95 +1,64 @@
-// 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.
-
-#ifndef GEARS_GEOLOCATION_NETWORK_LOCATION_PROVIDER_H__
-#define GEARS_GEOLOCATION_NETWORK_LOCATION_PROVIDER_H__
-
-// TODO(joth): port to chromium
-#if 0
-
-#include "gears/base/common/common.h"
-#include "gears/base/common/mutex.h"
-#include "gears/base/common/string16.h"
-#include "gears/base/common/thread.h"
-#include "gears/geolocation/device_data_provider.h"
-#include "gears/geolocation/location_provider.h"
-#include "gears/geolocation/network_location_request.h"
-
-// PositionCache is an implementation detail of NetworkLocationProvider.
-class PositionCache;
+// 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.
+
+#ifndef CHROME_BROWSER_GEOLOCATION_NETWORK_LOCATION_PROVIDER_H_
+#define CHROME_BROWSER_GEOLOCATION_NETWORK_LOCATION_PROVIDER_H_
+
+#include <string>
+
+#include "base/basictypes.h"
+#include "base/lock.h"
+#include "base/string16.h"
+#include "base/thread.h"
+#include "chrome/browser/geolocation/device_data_provider.h"
+#include "chrome/browser/geolocation/geoposition.h"
+#include "chrome/browser/geolocation/location_provider.h"
+#include "chrome/browser/geolocation/network_location_request.h"
+
+class URLFetcherProtectEntry;
class NetworkLocationProvider
: public LocationProviderBase,
public RadioDataProvider::ListenerInterface,
public WifiDataProvider::ListenerInterface,
- public NetworkLocationRequest::ListenerInterface,
- public Thread {
+ public NetworkLocationRequest::ListenerInterface {
public:
- NetworkLocationProvider(BrowsingContext *browsing_context,
- const std::string16 &url,
- const std::string16 &host_name,
- const std::string16 &language);
+ NetworkLocationProvider(AccessTokenStore* access_token_store,
+ URLRequestContextGetter* context,
+ const GURL& url,
+ const string16& host_name);
virtual ~NetworkLocationProvider();
- // Override LocationProviderBase implementation.
- virtual void RegisterListener(
- LocationProviderBase::ListenerInterface *listener,
- bool request_address);
- virtual void UnregisterListener(
- LocationProviderBase::ListenerInterface *listener);
-
// LocationProviderBase implementation
+ virtual bool StartProvider();
virtual void GetPosition(Position *position);
+ virtual void UpdatePosition();
private:
- // DeviceDataProvider::ListenerInterface implementation.
- virtual void DeviceDataUpdateAvailable(RadioDataProvider *provider);
- virtual void DeviceDataUpdateAvailable(WifiDataProvider *provider);
+ // PositionCache is an implementation detail of NetworkLocationProvider.
+ class PositionCache;
- // NetworkLocationRequest::ListenerInterface implementation.
- virtual void LocationResponseAvailable(const Position &position,
- bool server_error,
- const std::string16 &access_token);
+ // Satisfies a position request from cache or network.
+ void RequestPosition();
- // Thread implementation
- virtual void Run();
+ // Internal helper used by DeviceDataUpdateAvailable
+ void OnDeviceDataUpdated();
- // Internal helper used by worker thread to make a network request
- bool MakeRequest();
+ // DeviceDataProvider::ListenerInterface implementation.
+ virtual void DeviceDataUpdateAvailable(RadioDataProvider* provider);
+ virtual void DeviceDataUpdateAvailable(WifiDataProvider* provider);
- // Internal helper used by DeviceDataUpdateAvailable
- void DeviceDataUpdateAvailableImpl();
+ // NetworkLocationRequest::ListenerInterface implementation.
+ virtual void LocationResponseAvailable(const Position& position,
+ bool server_error,
+ const string16& access_token);
- // The network location request object and the url and host name it will use.
- NetworkLocationRequest *request_;
- std::string16 url_;
- std::string16 host_name_;
+ AccessTokenStore* access_token_store_;
- // The device data providers
- RadioDataProvider *radio_data_provider_;
- WifiDataProvider *wifi_data_provider_;
+ // The device data providers, acquired via global factories.
+ RadioDataProvider* radio_data_provider_;
+ WifiDataProvider* wifi_data_provider_;
// The radio and wifi data, flags to indicate if each data set is complete,
// and their guarding mutex.
@@ -97,48 +66,28 @@ class NetworkLocationProvider
WifiData wifi_data_;
bool is_radio_data_complete_;
bool is_wifi_data_complete_;
- Mutex data_mutex_;
+ Lock data_mutex_;
// The timestamp for the latest device data update.
- int64 timestamp_;
+ int64 device_data_updated_timestamp_;
- // Parameters for the network request
- bool request_address_;
- bool request_address_from_last_request_;
- std::string16 address_language_;
+ string16 access_token_;
// The current best position estimate and its guarding mutex
Position position_;
- Mutex position_mutex_;
-
- // The event used to notify this object's (ie the network location provider)
- // worker thread about changes in available data, the network request status
- // and whether we're shutting down. The booleans are used to indicate what the
- // event signals.
- Event thread_notification_event_;
- bool is_shutting_down_;
- bool is_new_data_available_;
- bool is_last_request_complete_;
- bool is_new_listener_waiting_;
+ Lock position_mutex_;
- // When the last request did not request an address, this stores any new
- // listeners which have been added and require an address to be requested.
- typedef std::set<LocationProviderBase::ListenerInterface*> ListenerSet;
- ListenerSet new_listeners_requiring_address_;
- Mutex new_listeners_requiring_address_mutex_;
+ bool is_new_data_available_;
- // The earliest timestamp at which the next request can be made, in
- // milliseconds.
- int64 earliest_next_request_time_;
- BrowsingContext *browsing_context_;
+ // The network location request object, and the url it uses.
+ scoped_ptr<NetworkLocationRequest> request_;
+ ScopedRunnableMethodFactory<NetworkLocationProvider> delayed_start_task_;
// The cache of positions.
scoped_ptr<PositionCache> position_cache_;
- DISALLOW_EVIL_CONSTRUCTORS(NetworkLocationProvider);
+ DISALLOW_COPY_AND_ASSIGN(NetworkLocationProvider);
};
-#endif // if 0
-
-#endif // GEARS_GEOLOCATION_NETWORK_LOCATION_PROVIDER_H__
+#endif // CHROME_BROWSER_GEOLOCATION_NETWORK_LOCATION_PROVIDER_H_
diff --git a/chrome/browser/geolocation/network_location_request.cc b/chrome/browser/geolocation/network_location_request.cc
index 47bcffe..7fff715 100644
--- a/chrome/browser/geolocation/network_location_request.cc
+++ b/chrome/browser/geolocation/network_location_request.cc
@@ -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.
-
-// TODO(joth): port to chromium
-#if 0
-
-#include "gears/geolocation/network_location_request.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"
-
-static const char *kGearsNetworkLocationProtocolVersion = "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";
+// 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.
+
+#include "chrome/browser/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"
+
+namespace {
+const char* const kMimeApplicationJson = "application/json";
+
+// See http://code.google.com/apis/gears/geolocation_network_protocol.html
+const char* kGeoLocationNetworkProtocolVersion = "1.1.0";
+
+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);
-
-// 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();
+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
+
+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());
+
+ 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();
+
+ DCHECK(listener_);
+ DLOG(INFO) << "NetworkLocationRequest::Run() : "
+ "Calling listener with position.\n";
+ listener_->LocationResponseAvailable(position, server_error, access_token);
}
-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
-
- 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;
- }
+// Local functions.
+namespace {
- 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);
-
- 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);
-
- AddString("access_token", access_token, &body_object);
-
- body_object["request_address"] = request_address;
- AddString("address_language", address_language, &body_object);
-
- 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);
- }
+ body_object.SetString(L"version", kGeoLocationNetworkProtocolVersion);
+ AddString(L"host", host_name, &body_object);
+
+ AddString(L"access_token", access_token, &body_object);
+
+ body_object.SetBoolean(L"request_address", false);
- Json::FastWriter writer;
+ AddRadioData(radio_data, &body_object);
+ AddWifiData(wifi_data, &body_object);
+
+ // 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()));
-
- blob->reset(new BufferBlob(body_string.c_str(), body_string.size()));
+// char* current_locale = setlocale(LC_NUMERIC, "C");
+
+ 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)) {
- return false;
- }
- *out = object[property_name].asDouble();
- return true;
-}
-
-// 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()) {
+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;
}
- std::string out_utf8 = object[property_name].asString();
- return UTF8ToString16(out_utf8.c_str(), out_utf8.size(), out);
+ return value->GetAsReal(out);
}
-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);
+bool ParseServerResponse(const std::string& response_body,
+ int64 timestamp,
+ Position* position,
+ string16* access_token) {
+ DCHECK(position);
+ DCHECK(access_token);
+ DCHECK(timestamp != kint64min);
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;
- }
-
- // If location is not null, it must be an object.
- if (!location.isObject()) {
- return false;
+ 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);
// 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;
}
-
- // 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;
- }
- }
+ // All error paths covered: now start actually modifying postion.
+ position->latitude = latitude;
+ position->longitude = longitude;
+ position->timestamp = timestamp;
// 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());
- 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;
+ const int num_cell_towers = static_cast<int>(radio_data.cell_data.size());
+ if (num_cell_towers == 0) {
+ return;
}
- if (num_cell_towers > 0) {
- (*body_object)["cell_towers"] = cell_towers;
+ ListValue* cell_towers = new ListValue;
+ for (int i = 0; i < num_cell_towers; ++i) {
+ 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);
}
+ 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
diff --git a/chrome/browser/geolocation/network_location_request.h b/chrome/browser/geolocation/network_location_request.h
index 18a9081..4bf77fc 100644
--- a/chrome/browser/geolocation/network_location_request.h
+++ b/chrome/browser/geolocation/network_location_request.h
@@ -1,141 +1,75 @@
-// 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.
-
-#ifndef GEARS_GEOLOCATION_NETWORK_LOCATION_REQUEST_H__
-#define GEARS_GEOLOCATION_NETWORK_LOCATION_REQUEST_H__
-
-// TODO(joth): port to chromium
-#if 0
-
-#include <vector>
-#include "gears/base/common/basictypes.h" // For int64
-#include "gears/base/common/common.h"
-#include "gears/base/common/event.h"
-#include "gears/blob/blob.h"
-#include "gears/geolocation/geolocation.h"
-#include "gears/geolocation/device_data_provider.h"
-#include "gears/localserver/common/async_task.h"
-
-// An implementation of an AsyncTask that takes a set of device data and sends
-// it to a server to get a position fix. It performs formatting of the request
-// and interpretation of the response.
-class NetworkLocationRequest : public AsyncTask {
+// 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.
+
+#ifndef CHROME_BROWSER_GEOLOCATION_NETWORK_LOCATION_REQUEST_H_
+#define CHROME_BROWSER_GEOLOCATION_NETWORK_LOCATION_REQUEST_H_
+
+#include <string>
+#include "base/basictypes.h"
+#include "base/ref_counted.h"
+#include "chrome/browser/geolocation/device_data_provider.h"
+#include "chrome/browser/net/url_fetcher.h"
+#include "googleurl/src/gurl.h"
+
+struct Position;
+class URLRequestContextGetter;
+class URLFetcher;
+
+// Takes a set of device data and sends it to a server to get a position fix.
+// It performs formatting of the request and interpretation of the response.
+class NetworkLocationRequest : private URLFetcher::Delegate {
public:
- friend class scoped_ptr<NetworkLocationRequest>; // For use in Create().
-
// Interface for receiving callbacks from a NetworkLocationRequest object.
class ListenerInterface {
public:
// Updates the listener with a new position. server_error indicates whether
// was a server or network error - either no response or a 500 error code.
virtual void LocationResponseAvailable(
- const Position &position,
+ const Position& position,
bool server_error,
- const std::string16 &access_token) = 0;
+ const string16& access_token) = 0;
+
+ protected:
+ virtual ~ListenerInterface() {}
};
- // Creates the object and starts its worker thread running. Returns NULL if
- // creation or initialisation fails.
- static NetworkLocationRequest* Create(BrowsingContext *browsing_context,
- const std::string16 &url,
- const std::string16 &host_name,
- ListenerInterface *listener);
- bool 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,
+ // |url| is the server address to which the request wil be sent, |host_name|
+ // is the host of the webpage that caused this request.
+ // TODO(joth): is host needed? What to do when we reuse cached locations?
+ NetworkLocationRequest(URLRequestContextGetter* context,
+ const GURL& url,
+ const string16& host_name,
+ ListenerInterface* listener);
+ virtual ~NetworkLocationRequest();
+
+ // Makes a new request. Returns true if the new request was successfully
+ // started. In all cases, any currently pending request will be canceled.
+ bool MakeRequest(const string16& access_token,
+ const RadioData& radio_data,
+ const WifiData& wifi_data,
int64 timestamp);
- // This method aborts any pending request and instructs the worker thread to
- // terminate. The object is destructed once the thread terminates. This
- // method blocks until the AsyncTask::Run() implementation is complete, after
- // which the thread will not attempt to access external resources such as the
- // listener.
- void StopThreadAndDelete();
-
- private:
- // Private constructor and destructor. Callers should use Create() and
- // StopThreadAndDelete().
- NetworkLocationRequest(BrowsingContext *browsing_context,
- const std::string16 &url,
- const std::string16 &host_name,
- ListenerInterface *listener);
- virtual ~NetworkLocationRequest() {}
-
- void MakeRequestImpl();
- // AsyncTask implementation.
- virtual void Run();
-
- static bool 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);
-
- static void 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);
+ bool is_request_pending() const { return url_fetcher_ != NULL; }
+ const GURL& url() const { return url_; }
+ private:
+ // URLFetcher::Delegate
+ virtual void OnURLFetchComplete(const URLFetcher* source,
+ const GURL& url,
+ const URLRequestStatus& status,
+ int response_code,
+ const ResponseCookies& cookies,
+ const std::string& data);
+
+ scoped_refptr<URLRequestContextGetter> url_context_;
int64 timestamp_; // The timestamp of the data used to make the request.
- scoped_refptr<BlobInterface> post_body_;
- ListenerInterface *listener_;
- std::string16 url_;
- std::string16 host_name_;
-
- Mutex is_processing_response_mutex_;
-
- bool is_reverse_geocode_;
-
- Event thread_event_;
- bool is_shutting_down_;
-
-#ifdef USING_CCTESTS
- // Uses FormRequestBody for testing.
- friend void TestGeolocationFormRequestBody(JsCallContext *context);
- // Uses GetLocationFromResponse for testing.
- friend void TestGeolocationGetLocationFromResponse(
- JsCallContext *context,
- JsRunnerInterface *js_runner);
-#endif
+ ListenerInterface* listener_;
+ const GURL url_;
+ string16 host_name_;
+ scoped_ptr<URLFetcher> url_fetcher_;
DISALLOW_EVIL_CONSTRUCTORS(NetworkLocationRequest);
};
-#endif // if 0
-
-#endif // GEARS_GEOLOCATION_NETWORK_LOCATION_REQUEST_H__
+#endif // CHROME_BROWSER_GEOLOCATION_NETWORK_LOCATION_REQUEST_H_
diff --git a/chrome/browser/geolocation/wifi_data_provider_unittest_win.cc b/chrome/browser/geolocation/wifi_data_provider_unittest_win.cc
index 3710e76..8f7571b 100644
--- a/chrome/browser/geolocation/wifi_data_provider_unittest_win.cc
+++ b/chrome/browser/geolocation/wifi_data_provider_unittest_win.cc
@@ -9,7 +9,6 @@
#include "base/scoped_ptr.h"
#include "base/string_util.h"
#include "chrome/browser/geolocation/wifi_data_provider_common.h"
-#include "chrome/test/ui_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -42,7 +41,7 @@ class MessageLoopQuitListener
public:
explicit MessageLoopQuitListener(MessageLoop* message_loop)
: message_loop_to_quit_(message_loop) {
- assert(message_loop_to_quit_ != NULL);
+ DCHECK(message_loop_to_quit_ != NULL);
}
// ListenerInterface
virtual void DeviceDataUpdateAvailable(
@@ -74,7 +73,7 @@ class Win32WifiDataProviderTest : public testing::Test {
provider_.reset(CreateWin32WifiDataProvider(&wlan_api_));
}
virtual void TearDown() {
- provider_.reset(NULL);
+ provider_.reset();
}
protected:
@@ -98,7 +97,7 @@ TEST_F(Win32WifiDataProviderTest, CreateDestroy) {
TEST_F(Win32WifiDataProviderTest, StartThread) {
EXPECT_TRUE(provider_->StartDataProvider());
- provider_.reset(NULL); // Stop()s the thread.
+ provider_.reset(); // Stop()s the thread.
SUCCEED();
}
diff --git a/chrome/browser/geolocation/wifi_data_provider_win.cc b/chrome/browser/geolocation/wifi_data_provider_win.cc
index e7d52e2..c8f9ff9 100644
--- a/chrome/browser/geolocation/wifi_data_provider_win.cc
+++ b/chrome/browser/geolocation/wifi_data_provider_win.cc
@@ -30,10 +30,6 @@
#include "chrome/browser/geolocation/wifi_data_provider_common.h"
#include "chrome/browser/geolocation/wifi_data_provider_common_win.h"
-#ifdef _MSC_VER
-#pragma warning(disable:4355) // 'this' : used in base member initializer list
-#endif
-
// Taken from ndis.h for WinCE.
#define NDIS_STATUS_INVALID_LENGTH ((NDIS_STATUS)0xC0010014L)
#define NDIS_STATUS_BUFFER_TOO_SHORT ((NDIS_STATUS)0xC0010016L)
@@ -166,7 +162,7 @@ WifiDataProviderImplBase *WifiDataProvider::DefaultFactoryFunction() {
Win32WifiDataProvider::Win32WifiDataProvider()
: Thread(__FILE__),
is_first_scan_complete_(false),
- task_factory_(this) {
+ ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) {
}
Win32WifiDataProvider::~Win32WifiDataProvider() {
@@ -176,15 +172,15 @@ Win32WifiDataProvider::~Win32WifiDataProvider() {
}
void Win32WifiDataProvider::inject_mock_wlan_api(WlanApiInterface* wlan_api) {
- assert(wlan_api_ == NULL);
- assert(wlan_api);
+ DCHECK(wlan_api_ == NULL);
+ DCHECK(wlan_api);
wlan_api_.reset(wlan_api);
}
void Win32WifiDataProvider::inject_mock_polling_policy(
PollingPolicyInterface* policy) {
- assert(polling_policy_ == NULL);
- assert(policy);
+ DCHECK(polling_policy_ == NULL);
+ DCHECK(policy);
polling_policy_.reset(policy);
}
@@ -193,7 +189,7 @@ bool Win32WifiDataProvider::StartDataProvider() {
}
bool Win32WifiDataProvider::GetData(WifiData *data) {
- assert(data);
+ DCHECK(data);
AutoLock lock(data_mutex_);
*data = wifi_data_;
// If we've successfully completed a scan, indicate that we have all of the
@@ -223,17 +219,18 @@ void Win32WifiDataProvider::Init() {
kNoChangePollingInterval,
kTwoNoChangePollingInterval>);
}
- assert(polling_policy_ != NULL);
+ DCHECK(polling_policy_ != NULL);
ScheduleNextScan();
}
void Win32WifiDataProvider::CleanUp() {
// Destroy the wlan api instance in the thread in which it was created.
- wlan_api_.reset(NULL);
+ wlan_api_.reset();
}
void Win32WifiDataProvider::DoWifiScanTask() {
+ // TODO(joth): Almost all of this is shareable across platforms.
WifiData new_data;
if (wlan_api_->GetAccessPointData(&new_data.access_point_data)) {
bool update_available;
@@ -242,7 +239,7 @@ void Win32WifiDataProvider::DoWifiScanTask() {
wifi_data_ = new_data;
data_mutex_.Release();
polling_policy_->UpdatePollingInterval(update_available);
- if (update_available) {
+ if (update_available || !is_first_scan_complete_) {
is_first_scan_complete_ = true;
NotifyListeners();
}
@@ -278,7 +275,7 @@ WindowsWlanApi* WindowsWlanApi::Create() {
if (!GetSystemDirectory(&system_directory)) {
return NULL;
}
- assert(!system_directory.empty());
+ DCHECK(!system_directory.empty());
string16 dll_path = system_directory + L"wlanapi.dll";
HINSTANCE library = LoadLibraryEx(dll_path.c_str(),
NULL,
@@ -290,7 +287,7 @@ WindowsWlanApi* WindowsWlanApi::Create() {
}
void WindowsWlanApi::GetWLANFunctions(HINSTANCE wlan_library) {
- assert(wlan_library);
+ DCHECK(wlan_library);
WlanOpenHandle_function_ = reinterpret_cast<WlanOpenHandleFunction>(
GetProcAddress(wlan_library, "WlanOpenHandle"));
WlanEnumInterfaces_function_ = reinterpret_cast<WlanEnumInterfacesFunction>(
@@ -302,7 +299,7 @@ void WindowsWlanApi::GetWLANFunctions(HINSTANCE wlan_library) {
GetProcAddress(wlan_library, "WlanFreeMemory"));
WlanCloseHandle_function_ = reinterpret_cast<WlanCloseHandleFunction>(
GetProcAddress(wlan_library, "WlanCloseHandle"));
- assert(WlanOpenHandle_function_ &&
+ DCHECK(WlanOpenHandle_function_ &&
WlanEnumInterfaces_function_ &&
WlanGetNetworkBssList_function_ &&
WlanFreeMemory_function_ &&
@@ -311,7 +308,7 @@ void WindowsWlanApi::GetWLANFunctions(HINSTANCE wlan_library) {
bool WindowsWlanApi::GetAccessPointData(
WifiData::AccessPointDataSet *data) {
- assert(data);
+ DCHECK(data);
// Get the handle to the WLAN API.
DWORD negotiated_version;
@@ -326,7 +323,7 @@ bool WindowsWlanApi::GetAccessPointData(
&wlan_handle) != ERROR_SUCCESS) {
return false;
}
- assert(wlan_handle);
+ DCHECK(wlan_handle);
// Get the list of interfaces. WlanEnumInterfaces allocates interface_list.
WLAN_INTERFACE_INFO_LIST *interface_list = NULL;
@@ -334,7 +331,7 @@ bool WindowsWlanApi::GetAccessPointData(
ERROR_SUCCESS) {
return false;
}
- assert(interface_list);
+ DCHECK(interface_list);
// Go through the list of interfaces and get the data for each.
for (int i = 0; i < static_cast<int>(interface_list->dwNumberOfItems); ++i) {
@@ -360,7 +357,7 @@ int WindowsWlanApi::GetInterfaceDataWLAN(
const HANDLE wlan_handle,
const GUID &interface_id,
WifiData::AccessPointDataSet *data) {
- assert(data);
+ DCHECK(data);
// WlanGetNetworkBssList allocates bss_list.
WLAN_BSS_LIST *bss_list;
if ((*WlanGetNetworkBssList_function_)(wlan_handle,
@@ -391,7 +388,7 @@ int WindowsWlanApi::GetInterfaceDataWLAN(
WindowsNdisApi::WindowsNdisApi(
std::vector<string16>* interface_service_names)
: oid_buffer_size_(kInitialBufferSize) {
- assert(!interface_service_names->empty());
+ DCHECK(!interface_service_names->empty());
interface_service_names_.swap(*interface_service_names);
}
@@ -407,7 +404,7 @@ WindowsNdisApi* WindowsNdisApi::Create() {
}
bool WindowsNdisApi::GetAccessPointData(WifiData::AccessPointDataSet *data) {
- assert(data);
+ DCHECK(data);
int interfaces_failed = 0;
int interfaces_succeeded = 0;
@@ -452,7 +449,7 @@ bool WindowsNdisApi::GetInterfacesNDIS(
&network_cards_key) != ERROR_SUCCESS) {
return false;
}
- assert(network_cards_key);
+ DCHECK(network_cards_key);
for (int i = 0; ; ++i) {
TCHAR name[kStringLength];
@@ -473,7 +470,7 @@ bool WindowsNdisApi::GetInterfacesNDIS(
ERROR_SUCCESS) {
break;
}
- assert(hardware_key);
+ DCHECK(hardware_key);
TCHAR service_name[kStringLength];
DWORD service_name_size = kStringLength;
@@ -496,7 +493,7 @@ bool WindowsNdisApi::GetInterfacesNDIS(
bool WindowsNdisApi::GetInterfaceDataNDIS(HANDLE adapter_handle,
WifiData::AccessPointDataSet *data) {
- assert(data);
+ DCHECK(data);
scoped_ptr_malloc<BYTE> buffer(
reinterpret_cast<BYTE*>(malloc(oid_buffer_size_)));
@@ -532,7 +529,7 @@ bool WindowsNdisApi::GetInterfaceDataNDIS(HANDLE adapter_handle,
break;
}
}
- assert(buffer.get());
+ DCHECK(buffer.get());
if (result == ERROR_SUCCESS) {
NDIS_802_11_BSSID_LIST* bssid_list =
@@ -553,7 +550,7 @@ bool IsRunningOnVistaOrNewer() {
bool GetNetworkData(const WLAN_BSS_ENTRY &bss_entry,
AccessPointData *access_point_data) {
// Currently we get only MAC address, signal strength and SSID.
- assert(access_point_data);
+ DCHECK(access_point_data);
access_point_data->mac_address = MacAddressAsString16(bss_entry.dot11Bssid);
access_point_data->radio_signal_strength = bss_entry.lRssi;
// bss_entry.dot11Ssid.ucSSID is not null-terminated.
@@ -635,10 +632,10 @@ int PerformQuery(HANDLE adapter_handle,
}
bool ResizeBuffer(int requested_size, scoped_ptr_malloc<BYTE>* buffer) {
- assert(requested_size > 0);
- assert(buffer);
+ DCHECK(requested_size > 0);
+ DCHECK(buffer);
if (requested_size > kMaximumBufferSize) {
- buffer->reset(NULL);
+ buffer->reset();
return false;
}
@@ -648,7 +645,7 @@ bool ResizeBuffer(int requested_size, scoped_ptr_malloc<BYTE>* buffer) {
}
bool GetSystemDirectory(string16 *path) {
- assert(path);
+ DCHECK(path);
// Return value includes terminating NULL.
int buffer_size = ::GetSystemDirectory(NULL, 0);
if (buffer_size == 0) {
@@ -661,7 +658,7 @@ bool GetSystemDirectory(string16 *path) {
if (characters_written == 0) {
return false;
}
- assert(characters_written == buffer_size - 1);
+ DCHECK(characters_written == buffer_size - 1);
path->assign(buffer);
delete[] buffer;
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index c5db1102b4..1e14b7a 100755
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -854,6 +854,16 @@
'browser/geolocation/device_data_provider.h',
'browser/geolocation/empty_device_data_provider.cc',
'browser/geolocation/empty_device_data_provider.h',
+ 'browser/geolocation/geoposition.cc',
+ 'browser/geolocation/geoposition.h',
+ 'browser/geolocation/location_provider.cc',
+ 'browser/geolocation/location_provider.h',
+ 'browser/geolocation/location_provider_pool.cc',
+ 'browser/geolocation/location_provider_pool.h',
+ 'browser/geolocation/network_location_provider.cc',
+ 'browser/geolocation/network_location_provider.h',
+ 'browser/geolocation/network_location_request.cc',
+ 'browser/geolocation/network_location_request.h',
'browser/geolocation/wifi_data_provider_common.cc',
'browser/geolocation/wifi_data_provider_common.h',
'browser/geolocation/wifi_data_provider_common_win.cc',