Index: chrome/browser/geolocation/network_location_provider.cc |
diff --git a/chrome/browser/geolocation/network_location_provider.cc b/chrome/browser/geolocation/network_location_provider.cc |
index 88dc22fc9a308432229c297dbbf9c6d2dcb74b9e..f90cc9ffd6686ff76510f219527d6636ba3344a9 100644 |
--- a/chrome/browser/geolocation/network_location_provider.cc |
+++ b/chrome/browser/geolocation/network_location_provider.cc |
@@ -26,12 +26,13 @@ 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, |
+ bool CachePosition(const GatewayData& gateway_data, |
+ const RadioData& radio_data, |
const WifiData& wifi_data, |
const Geoposition& position) { |
// Check that we can generate a valid key for the device data. |
string16 key; |
- if (!MakeKey(radio_data, wifi_data, &key)) { |
+ if (!MakeKey(gateway_data, radio_data, wifi_data, &key)) { |
return false; |
} |
// If the cache is full, remove the oldest entry. |
@@ -53,10 +54,11 @@ class NetworkLocationProvider::PositionCache { |
// Searches for a cached position response for the current set of cell ID and |
// WiFi data. Returns the cached position if available, NULL otherwise. |
- const Geoposition *FindPosition(const RadioData &radio_data, |
+ const Geoposition *FindPosition(const GatewayData &gateway_data, |
+ const RadioData &radio_data, |
const WifiData &wifi_data) { |
string16 key; |
- if (!MakeKey(radio_data, wifi_data, &key)) { |
+ if (!MakeKey(gateway_data, radio_data, wifi_data, &key)) { |
return NULL; |
} |
CacheMap::const_iterator iter = cache_.find(key); |
@@ -65,16 +67,26 @@ class NetworkLocationProvider::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*/, |
+ static bool MakeKey(const GatewayData& gateway_data, |
+ const RadioData& /*radio_data*/, |
const WifiData& wifi_data, |
string16* key) { |
- // Currently we use only the WiFi data, and base the key only on the MAC |
- // addresses. |
+ // Currently we use only the WiFi data and gateway 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); |
+ key->reserve(wifi_data.access_point_data.size() * 19 + |
+ gateway_data.router_data.size() * 19); |
const string16 separator(ASCIIToUTF16("|")); |
+ for (GatewayData::RouterDataSet::const_iterator iter = |
+ gateway_data.router_data.begin(); |
+ iter != gateway_data.router_data.end(); |
+ iter++) { |
+ *key += separator; |
+ *key += iter->mac_address; |
+ *key += separator; |
+ } |
for (WifiData::AccessPointDataSet::const_iterator iter = |
wifi_data.access_point_data.begin(); |
iter != wifi_data.access_point_data.end(); |
@@ -115,8 +127,10 @@ NetworkLocationProvider::NetworkLocationProvider( |
const GURL& url, |
const string16& access_token) |
: access_token_store_(access_token_store), |
+ gateway_data_provider_(NULL), |
radio_data_provider_(NULL), |
wifi_data_provider_(NULL), |
+ is_gateway_data_complete_(false), |
is_radio_data_complete_(false), |
is_wifi_data_complete_(false), |
access_token_(access_token), |
@@ -143,7 +157,8 @@ void NetworkLocationProvider::UpdatePosition() { |
// poke each data provider to get them to expedite their next scan. |
// Whilst in the delayed start, only send request if all data is ready. |
if (delayed_start_task_.empty() || |
- (is_radio_data_complete_ && is_wifi_data_complete_)) { |
+ (is_gateway_data_complete_ && is_radio_data_complete_ && |
+ is_wifi_data_complete_)) { |
RequestPosition(); |
} |
} |
@@ -160,6 +175,13 @@ void NetworkLocationProvider::OnPermissionGranted( |
// DeviceDataProviderInterface::ListenerInterface implementation. |
void NetworkLocationProvider::DeviceDataUpdateAvailable( |
+ GatewayDataProvider* provider) { |
+ DCHECK(provider == gateway_data_provider_); |
+ is_gateway_data_complete_ = gateway_data_provider_->GetData(&gateway_data_); |
+ OnDeviceDataUpdated(); |
+} |
+ |
+void NetworkLocationProvider::DeviceDataUpdateAvailable( |
RadioDataProvider* provider) { |
DCHECK(provider == radio_data_provider_); |
is_radio_data_complete_ = radio_data_provider_->GetData(&radio_data_); |
@@ -178,13 +200,15 @@ void NetworkLocationProvider::LocationResponseAvailable( |
const Geoposition& position, |
bool server_error, |
const string16& access_token, |
+ const GatewayData& gateway_data, |
const RadioData& radio_data, |
const WifiData& wifi_data) { |
DCHECK(CalledOnValidThread()); |
// Record the position and update our cache. |
position_ = position; |
if (position.IsValidFix()) { |
- position_cache_->CachePosition(radio_data, wifi_data, position); |
+ position_cache_->CachePosition(gateway_data, radio_data, |
+ wifi_data, position); |
} |
// Record access_token if it's set. |
@@ -210,6 +234,7 @@ bool NetworkLocationProvider::StartProvider(bool high_accuracy) { |
// Get the device data providers. The first call to Register will create the |
// provider and it will be deleted by ref counting. |
+ gateway_data_provider_ = GatewayDataProvider::Register(this); |
radio_data_provider_ = RadioDataProvider::Register(this); |
wifi_data_provider_ = WifiDataProvider::Register(this); |
@@ -219,9 +244,11 @@ bool NetworkLocationProvider::StartProvider(bool high_accuracy) { |
&NetworkLocationProvider::RequestPosition), |
kDataCompleteWaitPeriod); |
// Get the device data. |
+ is_gateway_data_complete_ = gateway_data_provider_->GetData(&gateway_data_); |
is_radio_data_complete_ = radio_data_provider_->GetData(&radio_data_); |
is_wifi_data_complete_ = wifi_data_provider_->GetData(&wifi_data_); |
- if (is_radio_data_complete_ || is_wifi_data_complete_) |
+ if (is_gateway_data_complete_ || is_radio_data_complete_ || |
+ is_wifi_data_complete_) |
OnDeviceDataUpdated(); |
return true; |
} |
@@ -229,9 +256,11 @@ bool NetworkLocationProvider::StartProvider(bool high_accuracy) { |
void NetworkLocationProvider::StopProvider() { |
DCHECK(CalledOnValidThread()); |
if (IsStarted()) { |
+ gateway_data_provider_->Unregister(this); |
radio_data_provider_->Unregister(this); |
wifi_data_provider_->Unregister(this); |
} |
+ gateway_data_provider_ = NULL; |
radio_data_provider_ = NULL; |
wifi_data_provider_ = NULL; |
delayed_start_task_.RevokeAll(); |
@@ -244,7 +273,7 @@ void NetworkLocationProvider::RequestPosition() { |
return; |
const Geoposition* cached_position = |
- position_cache_->FindPosition(radio_data_, wifi_data_); |
+ position_cache_->FindPosition(gateway_data_, radio_data_, wifi_data_); |
DCHECK(!device_data_updated_timestamp_.is_null()) << |
"Timestamp must be set before looking up position"; |
if (cached_position) { |
@@ -278,7 +307,7 @@ void NetworkLocationProvider::RequestPosition() { |
// approximation of usage. We do not need to guarantee that this network |
// request was triggered by an API call from this specific host. |
request_->MakeRequest(most_recent_authorized_host_, access_token_, |
- radio_data_, wifi_data_, |
+ gateway_data_, radio_data_, wifi_data_, |
device_data_updated_timestamp_); |
} |
@@ -286,11 +315,13 @@ void NetworkLocationProvider::OnDeviceDataUpdated() { |
DCHECK(CalledOnValidThread()); |
device_data_updated_timestamp_ = base::Time::Now(); |
- is_new_data_available_ = is_radio_data_complete_ || is_wifi_data_complete_; |
+ is_new_data_available_ = is_gateway_data_complete_ || |
+ is_radio_data_complete_ || is_wifi_data_complete_; |
UpdatePosition(); |
} |
bool NetworkLocationProvider::IsStarted() const { |
+ DCHECK_EQ(!!gateway_data_provider_, !!radio_data_provider_); |
DCHECK_EQ(!!radio_data_provider_, !!wifi_data_provider_); |
return wifi_data_provider_ != NULL; |
} |