summaryrefslogtreecommitdiffstats
path: root/chrome/browser/geolocation
diff options
context:
space:
mode:
authorjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-14 22:27:18 +0000
committerjoth@chromium.org <joth@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-14 22:27:18 +0000
commitfdabdc748152405ebdd2f7910ee9d5aebe26588c (patch)
treeeefa0df13b6ffc0602c893ccd4eda44faf60a5d1 /chrome/browser/geolocation
parentd2c7813156033f186d10370f0d1dfe06603fba92 (diff)
downloadchromium_src-fdabdc748152405ebdd2f7910ee9d5aebe26588c.zip
chromium_src-fdabdc748152405ebdd2f7910ee9d5aebe26588c.tar.gz
chromium_src-fdabdc748152405ebdd2f7910ee9d5aebe26588c.tar.bz2
Fix for OSX 10.6 wifi crash: can't call [CWInterface +interface] on a machine that has no wifi adapter.
Instead enumerate all adapters and open each one explicitly. Has the benefit that it will get more comprehensive results on a machine with multiple adapters BUG=41337 TEST=opened maps.google.com/maps/m on 10.6 desktop & laptop machines Review URL: http://codereview.chromium.org/1545035 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44559 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/geolocation')
-rw-r--r--chrome/browser/geolocation/wifi_data_provider_corewlan_mac.mm83
1 files changed, 48 insertions, 35 deletions
diff --git a/chrome/browser/geolocation/wifi_data_provider_corewlan_mac.mm b/chrome/browser/geolocation/wifi_data_provider_corewlan_mac.mm
index 8fc280a..955f86e 100644
--- a/chrome/browser/geolocation/wifi_data_provider_corewlan_mac.mm
+++ b/chrome/browser/geolocation/wifi_data_provider_corewlan_mac.mm
@@ -11,7 +11,7 @@
#include "base/scoped_nsautorelease_pool.h"
#include "base/scoped_nsobject.h"
-#include "base/utf_string_conversions.h"
+#include "base/sys_string_conversions.h"
// Define a subset of the CoreWLAN interfaces we require. We can't depend on
// CoreWLAN.h existing as we need to build on 10.5 SDKs. We can't just send
@@ -22,6 +22,8 @@
@interface CWInterface : NSObject
+ (CWInterface*)interface;
++ (CWInterface*)interfaceWithName:(NSString*)name;
++ (NSArray*)supportedInterfaces;
- (NSArray*)scanForNetworksWithParameters:(NSDictionary*)parameters
error:(NSError**)error;
@end
@@ -54,7 +56,6 @@ class CoreWlanApi : public WifiDataProviderCommon::WlanApiInterface {
private:
scoped_nsobject<NSBundle> bundle_;
- scoped_nsobject<CWInterface> corewlan_interface_;
scoped_nsobject<NSString> merge_key_;
DISALLOW_COPY_AND_ASSIGN(CoreWlanApi);
@@ -72,12 +73,6 @@ bool CoreWlanApi::Init() {
DLOG(INFO) << "Failed to load the CoreWLAN framework bundle";
return false;
}
- corewlan_interface_.reset([[bundle_ classNamed:@"CWInterface"] interface]);
- if (!corewlan_interface_) {
- DLOG(INFO) << "Failed to create the CWInterface instance";
- return false;
- }
- [corewlan_interface_ retain];
// Dynamically look up the value of the kCWScanKeyMerge (i.e. without build
// time dependency on the 10.6 specific library).
@@ -104,40 +99,58 @@ bool CoreWlanApi::Init() {
bool CoreWlanApi::GetAccessPointData(WifiData::AccessPointDataSet* data) {
base::ScopedNSAutoreleasePool auto_pool;
- DCHECK(corewlan_interface_);
- NSError* err = nil;
// Initialize the scan parameters with scan key merging disabled, so we get
// every AP listed in the scan without any SSID de-duping logic.
NSDictionary* params =
[NSDictionary dictionaryWithObject:[NSNumber numberWithBool:NO]
forKey:merge_key_.get()];
- NSArray* scan = [corewlan_interface_ scanForNetworksWithParameters:params
- error:&err];
-
- const int error_code = [err code];
- const int count = [scan count];
- if (error_code && !count) {
- DLOG(WARNING) << "CoreWLAN scan failed " << error_code;
- return false;
- }
- DLOG(INFO) << "Found " << count << " wifi APs";
-
- for (CWNetwork* network in scan) {
- DCHECK(network);
- AccessPointData access_point_data;
- NSData* mac = [network bssidData];
- DCHECK([mac length] == 6);
- access_point_data.mac_address = MacAddressAsString16(
- static_cast<const uint8*>([mac bytes]));
- access_point_data.radio_signal_strength = [[network rssi] intValue];
- access_point_data.channel = [[network channel] intValue];
- access_point_data.signal_to_noise =
- access_point_data.radio_signal_strength - [[network noise] intValue];
- access_point_data.ssid = UTF8ToUTF16([[network ssid] UTF8String]);
- data->insert(access_point_data);
+ Class cw_interface_class = [bundle_ classNamed:@"CWInterface"];
+ NSArray* supported_interfaces = [cw_interface_class supportedInterfaces];
+ uint interface_error_count = 0;
+ for (NSString* interface_name in supported_interfaces) {
+ CWInterface* corewlan_interface =
+ [cw_interface_class interfaceWithName:interface_name];
+ if (!corewlan_interface) {
+ DLOG(WARNING) << interface_name << ": initWithName failed";
+ ++interface_error_count;
+ continue;
+ }
+
+ NSError* err = nil;
+ NSArray* scan = [corewlan_interface scanForNetworksWithParameters:params
+ error:&err];
+ const int error_code = [err code];
+ const int count = [scan count];
+ // We could get an error code but count != 0 if the scan was interrupted,
+ // for example. For our purposes this is not fatal, so process as normal.
+ if (error_code && count == 0) {
+ DLOG(WARNING) << interface_name << ": CoreWLAN scan failed with error "
+ << error_code;
+ ++interface_error_count;
+ continue;
+ }
+ DLOG(INFO) << interface_name << ": found " << count << " wifi APs";
+
+ for (CWNetwork* network in scan) {
+ DCHECK(network);
+ AccessPointData access_point_data;
+ NSData* mac = [network bssidData];
+ DCHECK([mac length] == 6);
+ access_point_data.mac_address = MacAddressAsString16(
+ static_cast<const uint8*>([mac bytes]));
+ access_point_data.radio_signal_strength = [[network rssi] intValue];
+ access_point_data.channel = [[network channel] intValue];
+ access_point_data.signal_to_noise =
+ access_point_data.radio_signal_strength - [[network noise] intValue];
+ access_point_data.ssid = base::SysNSStringToUTF16([network ssid]);
+ data->insert(access_point_data);
+ }
}
- return true;
+ // Return true even if some interfaces failed to scan, so long as at least
+ // one interface did not fail.
+ return interface_error_count == 0 ||
+ [supported_interfaces count] > interface_error_count;
}
WifiDataProviderCommon::WlanApiInterface* NewCoreWlanApi() {