diff options
author | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-15 10:55:38 +0000 |
---|---|---|
committer | joth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-15 10:55:38 +0000 |
commit | 63259a5095c73aafc0e3d84b0e1ba1ef48b05048 (patch) | |
tree | e776c25f7f1c3326e70d961b6e6d874c3de0081f /chrome | |
parent | dfb6bc0a84ab1a4de19741428c24bc4d2d290305 (diff) | |
download | chromium_src-63259a5095c73aafc0e3d84b0e1ba1ef48b05048.zip chromium_src-63259a5095c73aafc0e3d84b0e1ba1ef48b05048.tar.gz chromium_src-63259a5095c73aafc0e3d84b0e1ba1ef48b05048.tar.bz2 |
Implement wifi geolocation for Chrome OS
Update network_library to use libcros to fetch wifi access point list, and update the geolocation code to use this for wifi scanning.
Depends on changes codereview.chromium.org/2927007 and codereview.chromium.org/2958008 (will be landed after them both)
BUG=45671
TEST=Open maps.google.com/maps/m on netbook with wifi enabled, it should go to your location with a few hundred
Review URL: http://codereview.chromium.org/2905008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@52476 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
6 files changed, 105 insertions, 89 deletions
diff --git a/chrome/browser/chromeos/cros/mock_network_library.h b/chrome/browser/chromeos/cros/mock_network_library.h index f498931..7ae212e 100644 --- a/chrome/browser/chromeos/cros/mock_network_library.h +++ b/chrome/browser/chromeos/cros/mock_network_library.h @@ -47,6 +47,7 @@ class MockNetworkLibrary : public NetworkLibrary { CellularNetwork*)); MOCK_METHOD0(RequestWifiScan, void(void)); + MOCK_METHOD1(GetWifiAccessPoints, bool(WifiAccessPointVector*)); MOCK_METHOD0(ConnectToPreferredNetworkIfAvailable, bool(void)); MOCK_METHOD0(PreferredNetworkConnected, bool(void)); MOCK_METHOD0(PreferredNetworkFailed, bool(void)); diff --git a/chrome/browser/chromeos/cros/network_library.cc b/chrome/browser/chromeos/cros/network_library.cc index 086b31a..46fd7ae 100644 --- a/chrome/browser/chromeos/cros/network_library.cc +++ b/chrome/browser/chromeos/cros/network_library.cc @@ -158,12 +158,10 @@ void WirelessNetwork::ConfigureFromService(const ServiceInfo& service) { void CellularNetwork::Clear() { WirelessNetwork::Clear(); - cell_towers_.clear(); } void CellularNetwork::ConfigureFromService(const ServiceInfo& service) { WirelessNetwork::ConfigureFromService(service); - // TODO(joth): Update |cell_towers_| once ChromeOS side is implemented. } //////////////////////////////////////////////////////////////////////////////// @@ -175,7 +173,6 @@ void WifiNetwork::Clear() { passphrase_.clear(); identity_.clear(); cert_path_.clear(); - access_points_.clear(); } void WifiNetwork::ConfigureFromService(const ServiceInfo& service) { @@ -184,7 +181,6 @@ void WifiNetwork::ConfigureFromService(const ServiceInfo& service) { passphrase_ = service.passphrase; identity_ = service.identity; cert_path_ = service.cert_path; - // TODO(joth): Update |access_points_| once ChromeOS side is implemented. } std::string WifiNetwork::GetEncryptionString() { @@ -295,6 +291,31 @@ void NetworkLibraryImpl::RequestWifiScan() { } } +bool NetworkLibraryImpl::GetWifiAccessPoints(WifiAccessPointVector* result) { + if (!CrosLibrary::Get()->EnsureLoaded()) + return false; + DeviceNetworkList* network_list = GetDeviceNetworkList(); + if (network_list == NULL) + return false; + result->clear(); + result->reserve(network_list->network_size); + const base::Time now = base::Time::Now(); + for (size_t i = 0; i < network_list->network_size; ++i) { + DCHECK(network_list->networks[i].address); + DCHECK(network_list->networks[i].name); + WifiAccessPoint ap; + ap.mac_address = network_list->networks[i].address; + ap.name = network_list->networks[i].name; + ap.timestamp = now - + base::TimeDelta::FromSeconds(network_list->networks[i].age_seconds); + ap.signal_strength = network_list->networks[i].strength; + ap.channel = network_list->networks[i].channel; + result->push_back(ap); + } + FreeDeviceNetworkList(network_list); + return true; +} + bool NetworkLibraryImpl::ConnectToPreferredNetworkIfAvailable() { // TODO(chocobo): Add the concept of preferred network to libcros. // So that we don't have to hard-code Google-A here. diff --git a/chrome/browser/chromeos/cros/network_library.h b/chrome/browser/chromeos/cros/network_library.h index 35b9314..df55c07 100644 --- a/chrome/browser/chromeos/cros/network_library.h +++ b/chrome/browser/chromeos/cros/network_library.h @@ -110,56 +110,19 @@ class WirelessNetwork : public Network { class CellularNetwork : public WirelessNetwork { public: - struct CellTower { - enum RadioType { - RADIOTYPE_GSM, - RADIOTYPE_CDMA, - RADIOTYPE_WCDMA, - } radio_type; // GSM/WCDMA CDMA - int mobile_country_code; // MCC MCC - int mobile_network_code; // MNC SID - int location_area_code; // LAC NID - int cell_id; // CID BID - base::Time timestamp; // Timestamp when this cell was primary - int signal_strength; // Radio signal strength measured in dBm. - int timing_advance; // Represents the distance from the cell tower. Each - // unit is roughly 550 meters. - }; - typedef std::vector<CellTower> CellTowerVector; - CellularNetwork() : WirelessNetwork() {} explicit CellularNetwork(const ServiceInfo& service) : WirelessNetwork() { ConfigureFromService(service); } - // Returns list of recently visible cell towers for this network. If the - // network is not visible (e.g. if this object was obtained from a remembered - // networks call) then this list will be empty. - // TODO(joth): Provide implementation in NetworkLibraryImpl to fill this. - const CellTowerVector& cell_towers() const { return cell_towers_; } - void set_cell_towers(const CellTowerVector& cell_towers) { - cell_towers_ = cell_towers; - } // WirelessNetwork overrides. virtual void Clear(); virtual void ConfigureFromService(const ServiceInfo& service); - - protected: - CellTowerVector cell_towers_; }; class WifiNetwork : public WirelessNetwork { public: - struct AccessPoint { - std::string mac_address; // The mac address of the WiFi node. - base::Time timestamp; // Timestamp when this AP was detected. - int signal_strength; // Radio signal strength measured in dBm. - int signal_to_noise; // Current signal to noise ratio measured in dB. - int channel; // Wifi channel number. - }; - typedef std::vector<AccessPoint> AccessPointVector; - WifiNetwork() : WirelessNetwork(), encryption_(SECURITY_NONE) {} @@ -186,16 +149,6 @@ class WifiNetwork : public WirelessNetwork { void set_cert_path(const std::string& cert_path) { cert_path_ = cert_path; } - // Returns list of recently visible access points (base stations) for this - // network. If the network is not visible (e.g. if this object was obtained - // from a remembered networks call) then this list will be empty. - // TODO(joth): Provide implementation in NetworkLibraryImpl to fill this. - const AccessPointVector& access_points() const { - return access_points_; - } - void set_access_points(const AccessPointVector& access_points) { - access_points_ = access_points; - } // WirelessNetwork overrides. virtual void Clear(); @@ -210,12 +163,39 @@ class WifiNetwork : public WirelessNetwork { std::string passphrase_; std::string identity_; std::string cert_path_; - AccessPointVector access_points_; }; typedef std::vector<WifiNetwork> WifiNetworkVector; typedef std::vector<CellularNetwork> CellularNetworkVector; +struct CellTower { + enum RadioType { + RADIOTYPE_GSM, + RADIOTYPE_CDMA, + RADIOTYPE_WCDMA, + } radio_type; // GSM/WCDMA CDMA + int mobile_country_code; // MCC MCC + int mobile_network_code; // MNC SID + int location_area_code; // LAC NID + int cell_id; // CID BID + base::Time timestamp; // Timestamp when this cell was primary + int signal_strength; // Radio signal strength measured in dBm. + int timing_advance; // Represents the distance from the cell tower. Each + // unit is roughly 550 meters. +}; + +struct WifiAccessPoint { + std::string mac_address; // The mac address of the WiFi node. + std::string name; // The SSID of the WiFi node. + base::Time timestamp; // Timestamp when this AP was detected. + int signal_strength; // Radio signal strength measured in dBm. + int signal_to_noise; // Current signal to noise ratio measured in dB. + int channel; // Wifi channel number. +}; + +typedef std::vector<CellTower> CellTowerVector; +typedef std::vector<WifiAccessPoint> WifiAccessPointVector; + struct NetworkIPConfig { NetworkIPConfig(const std::string& device_path, IPConfigType type, const std::string& address, const std::string& netmask, @@ -308,6 +288,16 @@ class NetworkLibrary { // Request a scan for new wifi networks. virtual void RequestWifiScan() = 0; + // Reads out the results of the last wifi scan. These results are not + // pre-cached in the library, so the call may block whilst the results are + // read over IPC. + // Returns false if an error occurred in reading the results. Note that + // a true return code only indicates the result set was successfully read, + // it does not imply a scan has successfully completed yet. + virtual bool GetWifiAccessPoints(WifiAccessPointVector* result) = 0; + + // TODO(joth): Add GetCellTowers to retrieve a CellTowerVector. + // Attempt to connect to the preferred network if available and it is set up. // This call will return true if connection is started. // If the preferred network is not available or not setup, returns false. @@ -438,6 +428,7 @@ class NetworkLibraryImpl : public NetworkLibrary, CellularNetwork* network) const; virtual void RequestWifiScan(); + virtual bool GetWifiAccessPoints(WifiAccessPointVector* result); virtual bool ConnectToPreferredNetworkIfAvailable(); virtual bool PreferredNetworkConnected(); virtual bool PreferredNetworkFailed(); diff --git a/chrome/browser/geolocation/libgps_wrapper_linux.cc b/chrome/browser/geolocation/libgps_wrapper_linux.cc index 141ad2f..f1c3728 100644 --- a/chrome/browser/geolocation/libgps_wrapper_linux.cc +++ b/chrome/browser/geolocation/libgps_wrapper_linux.cc @@ -84,11 +84,13 @@ bool LibGps::Start() { if (library().is_open()) return true; errno = 0; + static int fail_count = 0; if (!library().open(NULL, NULL)) { // See gps.h NL_NOxxx for definition of gps_open() error numbers. - LOG(INFO) << "gps_open() failed: " << errno; + LOG_IF(WARNING, 0 == fail_count++) << "gps_open() failed: " << errno; return false; } + fail_count = 0; if (!StartStreaming()) { LOG(INFO) << "StartStreaming failed"; library().close(); diff --git a/chrome/browser/geolocation/wifi_data_provider_chromeos.cc b/chrome/browser/geolocation/wifi_data_provider_chromeos.cc index 41097d3..1a0343c 100644 --- a/chrome/browser/geolocation/wifi_data_provider_chromeos.cc +++ b/chrome/browser/geolocation/wifi_data_provider_chromeos.cc @@ -45,22 +45,21 @@ NetworkLibraryWlanApi::~NetworkLibraryWlanApi() { } bool NetworkLibraryWlanApi::GetAccessPointData( - WifiData::AccessPointDataSet* data) { - const WifiNetworkVector& networks = network_library_->wifi_networks(); - for (WifiNetworkVector::const_iterator i = networks.begin(); - i != networks.end(); ++i) { - for (WifiNetwork::AccessPointVector::const_iterator j = - i->access_points().begin(); j != i->access_points().end(); ++j) { - AccessPointData ap_data; - ap_data.mac_address = ASCIIToUTF16(j->mac_address); - ap_data.radio_signal_strength = j->signal_strength; - ap_data.channel = j->channel; - ap_data.signal_to_noise = j->signal_to_noise; - ap_data.ssid = UTF8ToUTF16(i->name()); - data->insert(ap_data); - } + WifiData::AccessPointDataSet* result) { + WifiAccessPointVector access_points; + if (!network_library_->GetWifiAccessPoints(&access_points)) + return false; + for (WifiAccessPointVector::const_iterator i = access_points.begin(); + i != access_points.end(); ++i) { + AccessPointData ap_data; + ap_data.mac_address = ASCIIToUTF16(i->mac_address); + ap_data.radio_signal_strength = i->signal_strength; + ap_data.channel = i->channel; + ap_data.signal_to_noise = i->signal_to_noise; + ap_data.ssid = UTF8ToUTF16(i->name); + result->insert(ap_data); } - return !data->empty() || network_library_->wifi_available(); + return !result->empty() || network_library_->wifi_enabled(); } } // namespace diff --git a/chrome/browser/geolocation/wifi_data_provider_unittest_chromeos.cc b/chrome/browser/geolocation/wifi_data_provider_unittest_chromeos.cc index ca31a21..acd4f3a 100644 --- a/chrome/browser/geolocation/wifi_data_provider_unittest_chromeos.cc +++ b/chrome/browser/geolocation/wifi_data_provider_unittest_chromeos.cc @@ -8,70 +8,72 @@ #include "chrome/browser/chromeos/cros/mock_network_library.h" #include "testing/gtest/include/gtest/gtest.h" +using ::testing::DoAll; +using ::testing::NotNull; using ::testing::Return; using ::testing::ReturnRef; +using ::testing::SetArgumentPointee; namespace chromeos { class GeolocationChromeOsWifiDataProviderTest : public testing::Test { protected: GeolocationChromeOsWifiDataProviderTest() - : api_(WifiDataProviderChromeOs::NewWlanApi(&net_lib_)){} - virtual void SetUp() { - EXPECT_CALL(net_lib_, wifi_networks()) - .WillOnce(ReturnRef(wifi_network_data_)); + : api_(WifiDataProviderChromeOs::NewWlanApi(&net_lib_)) { } - void AddWifiAps(int ssids, int aps_per_ssid) { + + static WifiAccessPointVector MakeWifiAps(int ssids, int aps_per_ssid) { + WifiAccessPointVector ret; for (int i = 0; i < ssids; ++i) { - WifiNetwork network; - network.set_name(StringPrintf("SSID %d", i)); - std::vector<WifiNetwork::AccessPoint> aps; for (int j = 0; j < aps_per_ssid; ++j) { - WifiNetwork::AccessPoint ap; + WifiAccessPoint ap; + ap.name = StringPrintf("SSID %d", i); ap.channel = i * 10 + j; ap.mac_address = StringPrintf("%02X:%02X:%02X:%02X:%02X:%02X", i, j, 3, 4, 5, 6); ap.signal_strength = j; ap.signal_to_noise = i; - aps.push_back(ap); + ret.push_back(ap); } - network.set_access_points(aps); - wifi_network_data_.push_back(network); } + return ret; } chromeos::MockNetworkLibrary net_lib_; scoped_ptr<WifiDataProviderCommon::WlanApiInterface> api_; - WifiNetworkVector wifi_network_data_; WifiData::AccessPointDataSet ap_data_; }; -TEST_F(GeolocationChromeOsWifiDataProviderTest, NoWifiAvailable) { - EXPECT_CALL(net_lib_, wifi_available()) - .WillRepeatedly(Return(false)); +TEST_F(GeolocationChromeOsWifiDataProviderTest, WifiPoweredOff) { + EXPECT_CALL(net_lib_, GetWifiAccessPoints(NotNull())) + .WillOnce(Return(false)); EXPECT_FALSE(api_->GetAccessPointData(&ap_data_)); EXPECT_EQ(0u, ap_data_.size()); } TEST_F(GeolocationChromeOsWifiDataProviderTest, NoAccessPointsInRange) { - EXPECT_CALL(net_lib_, wifi_available()) + EXPECT_CALL(net_lib_, GetWifiAccessPoints(NotNull())) + .WillOnce(Return(true)); + EXPECT_CALL(net_lib_, wifi_enabled()) .WillRepeatedly(Return(true)); EXPECT_TRUE(api_->GetAccessPointData(&ap_data_)); EXPECT_EQ(0u, ap_data_.size()); } TEST_F(GeolocationChromeOsWifiDataProviderTest, GetOneAccessPoint) { - AddWifiAps(1, 1); + EXPECT_CALL(net_lib_, GetWifiAccessPoints(NotNull())) + .WillOnce(DoAll(SetArgumentPointee<0>(MakeWifiAps(1, 1)), Return(true))); EXPECT_TRUE(api_->GetAccessPointData(&ap_data_)); - EXPECT_EQ(1u, ap_data_.size()); + ASSERT_EQ(1u, ap_data_.size()); EXPECT_EQ("00:00:03:04:05:06", UTF16ToUTF8(ap_data_.begin()->mac_address)); EXPECT_EQ("SSID 0", UTF16ToUTF8(ap_data_.begin()->ssid)); } TEST_F(GeolocationChromeOsWifiDataProviderTest, GetManyAccessPoints) { - AddWifiAps(3, 4); + EXPECT_CALL(net_lib_, GetWifiAccessPoints(NotNull())) + .WillOnce(DoAll(SetArgumentPointee<0>(MakeWifiAps(3, 4)), Return(true))); EXPECT_TRUE(api_->GetAccessPointData(&ap_data_)); - EXPECT_EQ(12u, ap_data_.size()); + ASSERT_EQ(12u, ap_data_.size()); } } // namespace chromeos |