Chromium Code Reviews| Index: chromeos/network/geolocation_handler.cc |
| diff --git a/chromeos/network/geolocation_handler.cc b/chromeos/network/geolocation_handler.cc |
| index 0041ccf5c79c5b2665a88665ac72ae35fe98a558..e6cabaa33b14d42d0426f8f58b36a683baa77c0d 100644 |
| --- a/chromeos/network/geolocation_handler.cc |
| +++ b/chromeos/network/geolocation_handler.cc |
| @@ -16,10 +16,15 @@ |
| namespace chromeos { |
| +namespace { |
| + |
| +const std::string kDevicePropertyNames[] = {shill::kGeoWifiAccessPointsProperty, |
| + shill::kGeoCellTowersProperty}; |
| + |
| +} // namespace |
| + |
| GeolocationHandler::GeolocationHandler() |
| - : wifi_enabled_(false), |
| - weak_ptr_factory_(this) { |
| -} |
| + : cellular_enabled_(false), wifi_enabled_(false), weak_ptr_factory_(this) {} |
| GeolocationHandler::~GeolocationHandler() { |
| ShillManagerClient* manager_client = |
| @@ -43,14 +48,32 @@ bool GeolocationHandler::GetWifiAccessPoints( |
| if (!wifi_enabled_) |
| return false; |
| // Always request updated access points. |
| - RequestWifiAccessPoints(); |
| + RequestGeolocationObjects(); |
| // If no data has been received, return false. |
| - if (geolocation_received_time_.is_null()) |
| + if (access_point_received_time_.is_null()) |
| return false; |
| if (access_points) |
| *access_points = wifi_access_points_; |
| if (age_ms) { |
| - base::TimeDelta dtime = base::Time::Now() - geolocation_received_time_; |
| + base::TimeDelta dtime = base::Time::Now() - access_point_received_time_; |
| + *age_ms = dtime.InMilliseconds(); |
| + } |
| + return true; |
| +} |
| + |
| +bool GeolocationHandler::GetCellTowers(CellTowerVector* cell_towers, |
| + int64_t* age_ms) { |
| + if (!cellular_enabled_) |
| + return false; |
|
Ben Chan
2017/02/02 20:49:25
nit: use blank line to separate short if-statement
can Skylar cook
2017/02/03 00:15:20
Done.
|
| + // Always request updated info |
| + RequestGeolocationObjects(); |
| + // If no data has been received, return false. |
| + if (cell_towers_received_time_.is_null()) |
| + return false; |
| + if (cell_towers) |
| + *cell_towers = cell_towers_; |
| + if (age_ms) { |
| + base::TimeDelta dtime = base::Time::Now() - cell_towers_received_time_; |
| *age_ms = dtime.InMilliseconds(); |
| } |
| return true; |
| @@ -80,6 +103,8 @@ void GeolocationHandler::HandlePropertyChanged(const std::string& key, |
| if (!value.GetAsList(&technologies) || !technologies) |
| return; |
| bool wifi_was_enabled = wifi_enabled_; |
| + bool cellular_was_enabled = cellular_enabled_; |
| + cellular_enabled_ = false; |
| wifi_enabled_ = false; |
| for (base::ListValue::const_iterator iter = technologies->begin(); |
| iter != technologies->end(); ++iter) { |
| @@ -87,14 +112,21 @@ void GeolocationHandler::HandlePropertyChanged(const std::string& key, |
| (*iter)->GetAsString(&technology); |
| if (technology == shill::kTypeWifi) { |
| wifi_enabled_ = true; |
| - break; |
| + } else if (technology == shill::kTypeCellular) { |
| + cellular_enabled_ = true; |
| } |
| + if (wifi_enabled_ && cellular_enabled_) |
| + break; |
| + } |
| + |
| + // Request initial location data. |
| + if ((!wifi_was_enabled && wifi_enabled_) || |
| + (!cellular_was_enabled && cellular_enabled_)) { |
| + RequestGeolocationObjects(); |
| } |
| - if (!wifi_was_enabled && wifi_enabled_) |
| - RequestWifiAccessPoints(); // Request initial location data. |
| } |
| -void GeolocationHandler::RequestWifiAccessPoints() { |
| +void GeolocationHandler::RequestGeolocationObjects() { |
| DBusThreadManager::Get()->GetShillManagerClient()->GetNetworksForGeolocation( |
| base::Bind(&GeolocationHandler::GeolocationCallback, |
| weak_ptr_factory_.GetWeakPtr())); |
| @@ -108,17 +140,30 @@ void GeolocationHandler::GeolocationCallback( |
| return; |
| } |
| wifi_access_points_.clear(); |
| + cell_towers_.clear(); |
| if (properties.empty()) |
| return; // No enabled devices, don't update received time. |
| // Dictionary<device_type, entry_list> |
| - for (base::DictionaryValue::Iterator iter(properties); |
| - !iter.IsAtEnd(); iter.Advance()) { |
| + // Example dict returned from shill: |
| + // { |
| + // kGeoWifiAccessPointsProperty: [ {kGeoMacAddressProperty: mac_value, ...}, |
| + // ... |
| + // ], |
| + // kGeoCellTowersProperty: [ {kGeoCellIdProperty: cell_id_value, ...}, ... ] |
| + // } |
| + for (auto device_type : kDevicePropertyNames) { |
| + if (!properties.HasKey(device_type)) { |
| + continue; |
| + } |
| + |
| const base::ListValue* entry_list = NULL; |
| - if (!iter.value().GetAsList(&entry_list)) { |
| - LOG(WARNING) << "Geolocation dictionary value not a List: " << iter.key(); |
| + if (!properties.GetList(device_type, &entry_list)) { |
| + LOG(WARNING) << "Geolocation dictionary value not a List: " |
| + << device_type; |
| continue; |
| } |
| + |
| // List[Dictionary<key, value_str>] |
| for (size_t i = 0; i < entry_list->GetSize(); ++i) { |
| const base::DictionaryValue* entry = NULL; |
| @@ -127,29 +172,57 @@ void GeolocationHandler::GeolocationCallback( |
| continue; |
| } |
| // Docs: developers.google.com/maps/documentation/business/geolocation |
| - WifiAccessPoint wap; |
| - entry->GetString(shill::kGeoMacAddressProperty, &wap.mac_address); |
| - std::string age_str; |
| - if (entry->GetString(shill::kGeoAgeProperty, &age_str)) { |
| - int64_t age_ms; |
| - if (base::StringToInt64(age_str, &age_ms)) { |
| - wap.timestamp = |
| - base::Time::Now() - base::TimeDelta::FromMilliseconds(age_ms); |
| + if (device_type.compare(shill::kGeoWifiAccessPointsProperty) == 0) { |
|
Ben Chan
2017/02/02 20:49:25
why not use string::operator==?
can Skylar cook
2017/02/03 00:15:20
Because I'm still in (C++)-- mode haha. Done.
|
| + WifiAccessPoint wap; |
| + |
| + std::string age_str; |
| + if (entry->GetString(shill::kGeoAgeProperty, &age_str)) { |
| + int64_t age_ms; |
| + if (base::StringToInt64(age_str, &age_ms)) { |
| + wap.timestamp = |
| + base::Time::Now() - base::TimeDelta::FromMilliseconds(age_ms); |
| + } |
| } |
| + entry->GetString(shill::kGeoMacAddressProperty, &wap.mac_address); |
| + |
| + std::string strength_str; |
| + if (entry->GetString(shill::kGeoSignalStrengthProperty, &strength_str)) |
| + base::StringToInt(strength_str, &wap.signal_strength); |
| + |
| + std::string signal_str; |
| + if (entry->GetString(shill::kGeoSignalToNoiseRatioProperty, |
| + &signal_str)) { |
| + base::StringToInt(signal_str, &wap.signal_to_noise); |
| + } |
| + |
| + std::string channel_str; |
| + if (entry->GetString(shill::kGeoChannelProperty, &channel_str)) |
| + base::StringToInt(channel_str, &wap.channel); |
| + |
| + wifi_access_points_.push_back(wap); |
| + access_point_received_time_ = base::Time::Now(); |
| + |
| + } else if (device_type.compare(shill::kGeoCellTowersProperty) == 0) { |
| + CellTower ct; |
| + |
| + std::string age_str; |
| + if (entry->GetString(shill::kGeoAgeProperty, &age_str)) { |
| + int64_t age_ms; |
| + if (base::StringToInt64(age_str, &age_ms)) { |
| + ct.timestamp = |
| + base::Time::Now() - base::TimeDelta::FromMilliseconds(age_ms); |
| + } |
| + } |
| + entry->GetString(shill::kGeoCellIdProperty, &ct.ci); |
| + entry->GetString(shill::kGeoLocationAreaCodeProperty, &ct.lac); |
| + entry->GetString(shill::kGeoMobileCountryCodeProperty, &ct.mcc); |
| + entry->GetString(shill::kGeoMobileNetworkCodeProperty, &ct.mnc); |
| + |
| + cell_towers_.push_back(ct); |
| + cell_towers_received_time_ = base::Time::Now(); |
| } |
| - std::string strength_str; |
| - if (entry->GetString(shill::kGeoSignalStrengthProperty, &strength_str)) |
| - base::StringToInt(strength_str, &wap.signal_strength); |
| - std::string signal_str; |
| - if (entry->GetString(shill::kGeoSignalToNoiseRatioProperty, &signal_str)) |
| - base::StringToInt(signal_str, &wap.signal_to_noise); |
| - std::string channel_str; |
| - if (entry->GetString(shill::kGeoChannelProperty, &channel_str)) |
| - base::StringToInt(channel_str, &wap.channel); |
| - wifi_access_points_.push_back(wap); |
| } |
| } |
| - geolocation_received_time_ = base::Time::Now(); |
| } |
| } // namespace chromeos |