| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // Provides wifi scan API binding for suitable for typical linux distributions. | 5 // Provides wifi scan API binding for suitable for typical linux distributions. |
| 6 // Currently, only the NetworkManager API is used, accessed via D-Bus (in turn | 6 // Currently, only the NetworkManager API is used, accessed via D-Bus (in turn |
| 7 // accessed via the GLib wrapper). | 7 // accessed via the GLib wrapper). |
| 8 | 8 |
| 9 #include "device/geolocation/wifi_data_provider_linux.h" | 9 #include "device/geolocation/wifi_data_provider_linux.h" |
| 10 | 10 |
| 11 #include <stddef.h> | 11 #include <stddef.h> |
| 12 #include <stdint.h> | 12 #include <stdint.h> |
| 13 | 13 |
| 14 #include <memory> | 14 #include <memory> |
| 15 | 15 |
| 16 #include "base/macros.h" | 16 #include "base/macros.h" |
| 17 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
| 19 #include "dbus/bus.h" | 19 #include "dbus/bus.h" |
| 20 #include "dbus/message.h" | 20 #include "dbus/message.h" |
| 21 #include "dbus/object_path.h" | 21 #include "dbus/object_path.h" |
| 22 #include "dbus/object_proxy.h" | 22 #include "dbus/object_proxy.h" |
| 23 #include "device/geolocation/wifi_data_provider_manager.h" | 23 #include "device/geolocation/wifi_data_provider_manager.h" |
| 24 | 24 |
| 25 namespace device { | 25 namespace device { |
| 26 namespace { | 26 namespace { |
| 27 // The time periods between successive polls of the wifi data. | 27 // The time periods between successive polls of the wifi data. |
| 28 const int kDefaultPollingIntervalMilliseconds = 10 * 1000; // 10s | 28 const int kDefaultPollingIntervalMilliseconds = 10 * 1000; // 10s |
| 29 const int kNoChangePollingIntervalMilliseconds = 2 * 60 * 1000; // 2 mins | 29 const int kNoChangePollingIntervalMilliseconds = 2 * 60 * 1000; // 2 mins |
| 30 const int kTwoNoChangePollingIntervalMilliseconds = 10 * 60 * 1000; // 10 mins | 30 const int kTwoNoChangePollingIntervalMilliseconds = 10 * 60 * 1000; // 10 mins |
| 31 const int kNoWifiPollingIntervalMilliseconds = 20 * 1000; // 20s | 31 const int kNoWifiPollingIntervalMilliseconds = 20 * 1000; // 20s |
| 32 | 32 |
| 33 const char kNetworkManagerServiceName[] = "org.freedesktop.NetworkManager"; | 33 const char kNetworkManagerServiceName[] = "org.freedesktop.NetworkManager"; |
| 34 const char kNetworkManagerPath[] = "/org/freedesktop/NetworkManager"; | 34 const char kNetworkManagerPath[] = "/org/freedesktop/NetworkManager"; |
| 35 const char kNetworkManagerInterface[] = "org.freedesktop.NetworkManager"; | 35 const char kNetworkManagerInterface[] = "org.freedesktop.NetworkManager"; |
| 36 | 36 |
| 37 // From http://projects.gnome.org/NetworkManager/developers/spec.html | 37 // From http://projects.gnome.org/NetworkManager/developers/spec.html |
| 38 enum { NM_DEVICE_TYPE_WIFI = 2 }; | 38 enum { NM_DEVICE_TYPE_WIFI = 2 }; |
| 39 | 39 |
| 40 // Wifi API binding to NetworkManager, to allow reuse of the polling behavior | 40 // Wifi API binding to NetworkManager, to allow reuse of the polling behavior |
| 41 // defined in WifiDataProviderCommon. | 41 // defined in WifiDataProviderCommon. |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 91 if (frequency_khz >= 2412000 && frequency_khz <= 2472000) // Channels 1-13. | 91 if (frequency_khz >= 2412000 && frequency_khz <= 2472000) // Channels 1-13. |
| 92 return (frequency_khz - 2407000) / 5000; | 92 return (frequency_khz - 2407000) / 5000; |
| 93 if (frequency_khz == 2484000) | 93 if (frequency_khz == 2484000) |
| 94 return 14; | 94 return 14; |
| 95 if (frequency_khz > 5000000 && frequency_khz < 6000000) // .11a bands. | 95 if (frequency_khz > 5000000 && frequency_khz < 6000000) // .11a bands. |
| 96 return (frequency_khz - 5000000) / 5000; | 96 return (frequency_khz - 5000000) / 5000; |
| 97 // Ignore everything else. | 97 // Ignore everything else. |
| 98 return AccessPointData().channel; // invalid channel | 98 return AccessPointData().channel; // invalid channel |
| 99 } | 99 } |
| 100 | 100 |
| 101 NetworkManagerWlanApi::NetworkManagerWlanApi() | 101 NetworkManagerWlanApi::NetworkManagerWlanApi() : network_manager_proxy_(NULL) {} |
| 102 : network_manager_proxy_(NULL) { | |
| 103 } | |
| 104 | 102 |
| 105 NetworkManagerWlanApi::~NetworkManagerWlanApi() { | 103 NetworkManagerWlanApi::~NetworkManagerWlanApi() { |
| 106 // Close the connection. | 104 // Close the connection. |
| 107 system_bus_->ShutdownAndBlock(); | 105 system_bus_->ShutdownAndBlock(); |
| 108 } | 106 } |
| 109 | 107 |
| 110 bool NetworkManagerWlanApi::Init() { | 108 bool NetworkManagerWlanApi::Init() { |
| 111 dbus::Bus::Options options; | 109 dbus::Bus::Options options; |
| 112 options.bus_type = dbus::Bus::SYSTEM; | 110 options.bus_type = dbus::Bus::SYSTEM; |
| 113 options.connection_type = dbus::Bus::PRIVATE; | 111 options.connection_type = dbus::Bus::PRIVATE; |
| 114 return InitWithBus(new dbus::Bus(options)); | 112 return InitWithBus(new dbus::Bus(options)); |
| 115 } | 113 } |
| 116 | 114 |
| 117 bool NetworkManagerWlanApi::InitWithBus(dbus::Bus* bus) { | 115 bool NetworkManagerWlanApi::InitWithBus(dbus::Bus* bus) { |
| 118 system_bus_ = bus; | 116 system_bus_ = bus; |
| 119 // system_bus_ will own all object proxies created from the bus. | 117 // system_bus_ will own all object proxies created from the bus. |
| 120 network_manager_proxy_ = | 118 network_manager_proxy_ = system_bus_->GetObjectProxy( |
| 121 system_bus_->GetObjectProxy(kNetworkManagerServiceName, | 119 kNetworkManagerServiceName, dbus::ObjectPath(kNetworkManagerPath)); |
| 122 dbus::ObjectPath(kNetworkManagerPath)); | |
| 123 // Validate the proxy object by checking we can enumerate devices. | 120 // Validate the proxy object by checking we can enumerate devices. |
| 124 std::vector<dbus::ObjectPath> adapter_paths; | 121 std::vector<dbus::ObjectPath> adapter_paths; |
| 125 const bool success = GetAdapterDeviceList(&adapter_paths); | 122 const bool success = GetAdapterDeviceList(&adapter_paths); |
| 126 VLOG(1) << "Init() result: " << success; | 123 VLOG(1) << "Init() result: " << success; |
| 127 return success; | 124 return success; |
| 128 } | 125 } |
| 129 | 126 |
| 130 bool NetworkManagerWlanApi::GetAccessPointData( | 127 bool NetworkManagerWlanApi::GetAccessPointData( |
| 131 WifiData::AccessPointDataSet* data) { | 128 WifiData::AccessPointDataSet* data) { |
| 132 std::vector<dbus::ObjectPath> device_paths; | 129 std::vector<dbus::ObjectPath> device_paths; |
| 133 if (!GetAdapterDeviceList(&device_paths)) { | 130 if (!GetAdapterDeviceList(&device_paths)) { |
| 134 LOG(WARNING) << "Could not enumerate access points"; | 131 LOG(WARNING) << "Could not enumerate access points"; |
| 135 return false; | 132 return false; |
| 136 } | 133 } |
| 137 int success_count = 0; | 134 int success_count = 0; |
| 138 int fail_count = 0; | 135 int fail_count = 0; |
| 139 | 136 |
| 140 // Iterate the devices, getting APs for each wireless adapter found | 137 // Iterate the devices, getting APs for each wireless adapter found |
| 141 for (size_t i = 0; i < device_paths.size(); ++i) { | 138 for (size_t i = 0; i < device_paths.size(); ++i) { |
| 142 const dbus::ObjectPath& device_path = device_paths[i]; | 139 const dbus::ObjectPath& device_path = device_paths[i]; |
| 143 VLOG(1) << "Checking device: " << device_path.value(); | 140 VLOG(1) << "Checking device: " << device_path.value(); |
| 144 | 141 |
| 145 dbus::ObjectProxy* device_proxy = | 142 dbus::ObjectProxy* device_proxy = |
| 146 system_bus_->GetObjectProxy(kNetworkManagerServiceName, | 143 system_bus_->GetObjectProxy(kNetworkManagerServiceName, device_path); |
| 147 device_path); | |
| 148 | 144 |
| 149 dbus::MethodCall method_call(DBUS_INTERFACE_PROPERTIES, "Get"); | 145 dbus::MethodCall method_call(DBUS_INTERFACE_PROPERTIES, "Get"); |
| 150 dbus::MessageWriter builder(&method_call); | 146 dbus::MessageWriter builder(&method_call); |
| 151 builder.AppendString("org.freedesktop.NetworkManager.Device"); | 147 builder.AppendString("org.freedesktop.NetworkManager.Device"); |
| 152 builder.AppendString("DeviceType"); | 148 builder.AppendString("DeviceType"); |
| 153 std::unique_ptr<dbus::Response> response(device_proxy->CallMethodAndBlock( | 149 std::unique_ptr<dbus::Response> response(device_proxy->CallMethodAndBlock( |
| 154 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | 150 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 155 if (!response) { | 151 if (!response) { |
| 156 LOG(WARNING) << "Failed to get the device type for " | 152 LOG(WARNING) << "Failed to get the device type for " |
| 157 << device_path.value(); | 153 << device_path.value(); |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 189 } | 185 } |
| 190 | 186 |
| 191 dbus::MessageReader reader(response.get()); | 187 dbus::MessageReader reader(response.get()); |
| 192 if (!reader.PopArrayOfObjectPaths(device_paths)) { | 188 if (!reader.PopArrayOfObjectPaths(device_paths)) { |
| 193 LOG(WARNING) << "Unexpected response: " << response->ToString(); | 189 LOG(WARNING) << "Unexpected response: " << response->ToString(); |
| 194 return false; | 190 return false; |
| 195 } | 191 } |
| 196 return true; | 192 return true; |
| 197 } | 193 } |
| 198 | 194 |
| 199 | |
| 200 bool NetworkManagerWlanApi::GetAccessPointsForAdapter( | 195 bool NetworkManagerWlanApi::GetAccessPointsForAdapter( |
| 201 const dbus::ObjectPath& adapter_path, WifiData::AccessPointDataSet* data) { | 196 const dbus::ObjectPath& adapter_path, |
| 197 WifiData::AccessPointDataSet* data) { |
| 202 // Create a proxy object for this wifi adapter, and ask it to do a scan | 198 // Create a proxy object for this wifi adapter, and ask it to do a scan |
| 203 // (or at least, dump its scan results). | 199 // (or at least, dump its scan results). |
| 204 dbus::ObjectProxy* device_proxy = | 200 dbus::ObjectProxy* device_proxy = |
| 205 system_bus_->GetObjectProxy(kNetworkManagerServiceName, | 201 system_bus_->GetObjectProxy(kNetworkManagerServiceName, adapter_path); |
| 206 adapter_path); | 202 dbus::MethodCall method_call("org.freedesktop.NetworkManager.Device.Wireless", |
| 207 dbus::MethodCall method_call( | 203 "GetAccessPoints"); |
| 208 "org.freedesktop.NetworkManager.Device.Wireless", | |
| 209 "GetAccessPoints"); | |
| 210 std::unique_ptr<dbus::Response> response(device_proxy->CallMethodAndBlock( | 204 std::unique_ptr<dbus::Response> response(device_proxy->CallMethodAndBlock( |
| 211 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); | 205 &method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT)); |
| 212 if (!response) { | 206 if (!response) { |
| 213 LOG(WARNING) << "Failed to get access points data for " | 207 LOG(WARNING) << "Failed to get access points data for " |
| 214 << adapter_path.value(); | 208 << adapter_path.value(); |
| 215 return false; | 209 return false; |
| 216 } | 210 } |
| 217 dbus::MessageReader reader(response.get()); | 211 dbus::MessageReader reader(response.get()); |
| 218 std::vector<dbus::ObjectPath> access_point_paths; | 212 std::vector<dbus::ObjectPath> access_point_paths; |
| 219 if (!reader.PopArrayOfObjectPaths(&access_point_paths)) { | 213 if (!reader.PopArrayOfObjectPaths(&access_point_paths)) { |
| 220 LOG(WARNING) << "Unexpected response for " << adapter_path.value() << ": " | 214 LOG(WARNING) << "Unexpected response for " << adapter_path.value() << ": " |
| 221 << response->ToString(); | 215 << response->ToString(); |
| 222 return false; | 216 return false; |
| 223 } | 217 } |
| 224 | 218 |
| 225 VLOG(1) << "Wireless adapter " << adapter_path.value() << " found " | 219 VLOG(1) << "Wireless adapter " << adapter_path.value() << " found " |
| 226 << access_point_paths.size() << " access points."; | 220 << access_point_paths.size() << " access points."; |
| 227 | 221 |
| 228 for (size_t i = 0; i < access_point_paths.size(); ++i) { | 222 for (size_t i = 0; i < access_point_paths.size(); ++i) { |
| 229 const dbus::ObjectPath& access_point_path = access_point_paths[i]; | 223 const dbus::ObjectPath& access_point_path = access_point_paths[i]; |
| 230 VLOG(1) << "Checking access point: " << access_point_path.value(); | 224 VLOG(1) << "Checking access point: " << access_point_path.value(); |
| 231 | 225 |
| 232 dbus::ObjectProxy* access_point_proxy = | 226 dbus::ObjectProxy* access_point_proxy = system_bus_->GetObjectProxy( |
| 233 system_bus_->GetObjectProxy(kNetworkManagerServiceName, | 227 kNetworkManagerServiceName, access_point_path); |
| 234 access_point_path); | |
| 235 | 228 |
| 236 AccessPointData access_point_data; | 229 AccessPointData access_point_data; |
| 237 { | 230 { |
| 238 std::unique_ptr<dbus::Response> response( | 231 std::unique_ptr<dbus::Response> response( |
| 239 GetAccessPointProperty(access_point_proxy, "Ssid")); | 232 GetAccessPointProperty(access_point_proxy, "Ssid")); |
| 240 if (!response) | 233 if (!response) |
| 241 continue; | 234 continue; |
| 242 // The response should contain a variant that contains an array of bytes. | 235 // The response should contain a variant that contains an array of bytes. |
| 243 dbus::MessageReader reader(response.get()); | 236 dbus::MessageReader reader(response.get()); |
| 244 dbus::MessageReader variant_reader(response.get()); | 237 dbus::MessageReader variant_reader(response.get()); |
| 245 if (!reader.PopVariant(&variant_reader)) { | 238 if (!reader.PopVariant(&variant_reader)) { |
| 246 LOG(WARNING) << "Unexpected response for " << access_point_path.value() | 239 LOG(WARNING) << "Unexpected response for " << access_point_path.value() |
| 247 << ": " << response->ToString(); | 240 << ": " << response->ToString(); |
| 248 continue; | 241 continue; |
| 249 } | 242 } |
| 250 const uint8_t* ssid_bytes = NULL; | 243 const uint8_t* ssid_bytes = NULL; |
| 251 size_t ssid_length = 0; | 244 size_t ssid_length = 0; |
| 252 if (!variant_reader.PopArrayOfBytes(&ssid_bytes, &ssid_length)) { | 245 if (!variant_reader.PopArrayOfBytes(&ssid_bytes, &ssid_length)) { |
| 253 LOG(WARNING) << "Unexpected response for " << access_point_path.value() | 246 LOG(WARNING) << "Unexpected response for " << access_point_path.value() |
| 254 << ": " << response->ToString(); | 247 << ": " << response->ToString(); |
| 255 continue; | 248 continue; |
| 256 } | 249 } |
| 257 std::string ssid(ssid_bytes, ssid_bytes + ssid_length); | 250 std::string ssid(ssid_bytes, ssid_bytes + ssid_length); |
| 258 access_point_data.ssid = base::UTF8ToUTF16(ssid); | 251 access_point_data.ssid = base::UTF8ToUTF16(ssid); |
| 259 } | 252 } |
| 260 | 253 |
| 261 { // Read the mac address | 254 { // Read the mac address |
| 262 std::unique_ptr<dbus::Response> response( | 255 std::unique_ptr<dbus::Response> response( |
| 263 GetAccessPointProperty(access_point_proxy, "HwAddress")); | 256 GetAccessPointProperty(access_point_proxy, "HwAddress")); |
| 264 if (!response) | 257 if (!response) |
| 265 continue; | 258 continue; |
| 266 dbus::MessageReader reader(response.get()); | 259 dbus::MessageReader reader(response.get()); |
| 267 std::string mac; | 260 std::string mac; |
| 268 if (!reader.PopVariantOfString(&mac)) { | 261 if (!reader.PopVariantOfString(&mac)) { |
| 269 LOG(WARNING) << "Unexpected response for " << access_point_path.value() | 262 LOG(WARNING) << "Unexpected response for " << access_point_path.value() |
| 270 << ": " << response->ToString(); | 263 << ": " << response->ToString(); |
| 271 continue; | 264 continue; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 291 uint8_t strength = 0; | 284 uint8_t strength = 0; |
| 292 if (!reader.PopVariantOfByte(&strength)) { | 285 if (!reader.PopVariantOfByte(&strength)) { |
| 293 LOG(WARNING) << "Unexpected response for " << access_point_path.value() | 286 LOG(WARNING) << "Unexpected response for " << access_point_path.value() |
| 294 << ": " << response->ToString(); | 287 << ": " << response->ToString(); |
| 295 continue; | 288 continue; |
| 296 } | 289 } |
| 297 // Convert strength as a percentage into dBs. | 290 // Convert strength as a percentage into dBs. |
| 298 access_point_data.radio_signal_strength = -100 + strength / 2; | 291 access_point_data.radio_signal_strength = -100 + strength / 2; |
| 299 } | 292 } |
| 300 | 293 |
| 301 { // Read the channel | 294 { // Read the channel |
| 302 std::unique_ptr<dbus::Response> response( | 295 std::unique_ptr<dbus::Response> response( |
| 303 GetAccessPointProperty(access_point_proxy, "Frequency")); | 296 GetAccessPointProperty(access_point_proxy, "Frequency")); |
| 304 if (!response) | 297 if (!response) |
| 305 continue; | 298 continue; |
| 306 dbus::MessageReader reader(response.get()); | 299 dbus::MessageReader reader(response.get()); |
| 307 uint32_t frequency = 0; | 300 uint32_t frequency = 0; |
| 308 if (!reader.PopVariantOfUint32(&frequency)) { | 301 if (!reader.PopVariantOfUint32(&frequency)) { |
| 309 LOG(WARNING) << "Unexpected response for " << access_point_path.value() | 302 LOG(WARNING) << "Unexpected response for " << access_point_path.value() |
| 310 << ": " << response->ToString(); | 303 << ": " << response->ToString(); |
| 311 continue; | 304 continue; |
| 312 } | 305 } |
| 313 | 306 |
| 314 // NetworkManager returns frequency in MHz. | 307 // NetworkManager returns frequency in MHz. |
| 315 access_point_data.channel = | 308 access_point_data.channel = frquency_in_khz_to_channel(frequency * 1000); |
| 316 frquency_in_khz_to_channel(frequency * 1000); | |
| 317 } | 309 } |
| 318 VLOG(1) << "Access point data of " << access_point_path.value() << ": " | 310 VLOG(1) << "Access point data of " << access_point_path.value() << ": " |
| 319 << "SSID: " << access_point_data.ssid << ", " | 311 << "SSID: " << access_point_data.ssid << ", " |
| 320 << "MAC: " << access_point_data.mac_address << ", " | 312 << "MAC: " << access_point_data.mac_address << ", " |
| 321 << "Strength: " << access_point_data.radio_signal_strength << ", " | 313 << "Strength: " << access_point_data.radio_signal_strength << ", " |
| 322 << "Channel: " << access_point_data.channel; | 314 << "Channel: " << access_point_data.channel; |
| 323 | 315 |
| 324 data->insert(access_point_data); | 316 data->insert(access_point_data); |
| 325 } | 317 } |
| 326 return true; | 318 return true; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 342 return response; | 334 return response; |
| 343 } | 335 } |
| 344 | 336 |
| 345 } // namespace | 337 } // namespace |
| 346 | 338 |
| 347 // static | 339 // static |
| 348 WifiDataProvider* WifiDataProviderManager::DefaultFactoryFunction() { | 340 WifiDataProvider* WifiDataProviderManager::DefaultFactoryFunction() { |
| 349 return new WifiDataProviderLinux(); | 341 return new WifiDataProviderLinux(); |
| 350 } | 342 } |
| 351 | 343 |
| 352 WifiDataProviderLinux::WifiDataProviderLinux() { | 344 WifiDataProviderLinux::WifiDataProviderLinux() {} |
| 353 } | |
| 354 | 345 |
| 355 WifiDataProviderLinux::~WifiDataProviderLinux() { | 346 WifiDataProviderLinux::~WifiDataProviderLinux() {} |
| 356 } | |
| 357 | 347 |
| 358 WifiDataProviderCommon::WlanApiInterface* | 348 WifiDataProviderCommon::WlanApiInterface* WifiDataProviderLinux::NewWlanApi() { |
| 359 WifiDataProviderLinux::NewWlanApi() { | |
| 360 std::unique_ptr<NetworkManagerWlanApi> wlan_api(new NetworkManagerWlanApi); | 349 std::unique_ptr<NetworkManagerWlanApi> wlan_api(new NetworkManagerWlanApi); |
| 361 if (wlan_api->Init()) | 350 if (wlan_api->Init()) |
| 362 return wlan_api.release(); | 351 return wlan_api.release(); |
| 363 return NULL; | 352 return NULL; |
| 364 } | 353 } |
| 365 | 354 |
| 366 WifiPollingPolicy* WifiDataProviderLinux::NewPollingPolicy() { | 355 WifiPollingPolicy* WifiDataProviderLinux::NewPollingPolicy() { |
| 367 return new GenericWifiPollingPolicy<kDefaultPollingIntervalMilliseconds, | 356 return new GenericWifiPollingPolicy<kDefaultPollingIntervalMilliseconds, |
| 368 kNoChangePollingIntervalMilliseconds, | 357 kNoChangePollingIntervalMilliseconds, |
| 369 kTwoNoChangePollingIntervalMilliseconds, | 358 kTwoNoChangePollingIntervalMilliseconds, |
| 370 kNoWifiPollingIntervalMilliseconds>; | 359 kNoWifiPollingIntervalMilliseconds>; |
| 371 } | 360 } |
| 372 | 361 |
| 373 WifiDataProviderCommon::WlanApiInterface* | 362 WifiDataProviderCommon::WlanApiInterface* |
| 374 WifiDataProviderLinux::NewWlanApiForTesting(dbus::Bus* bus) { | 363 WifiDataProviderLinux::NewWlanApiForTesting(dbus::Bus* bus) { |
| 375 std::unique_ptr<NetworkManagerWlanApi> wlan_api(new NetworkManagerWlanApi); | 364 std::unique_ptr<NetworkManagerWlanApi> wlan_api(new NetworkManagerWlanApi); |
| 376 if (wlan_api->InitWithBus(bus)) | 365 if (wlan_api->InitWithBus(bus)) |
| 377 return wlan_api.release(); | 366 return wlan_api.release(); |
| 378 return NULL; | 367 return NULL; |
| 379 } | 368 } |
| 380 | 369 |
| 381 } // namespace device | 370 } // namespace device |
| OLD | NEW |