summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerikchen@chromium.org <erikchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-12 01:27:44 +0000
committererikchen@chromium.org <erikchen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-12 01:27:44 +0000
commite088f02c609c97c659633fc4fe77a0198101e494 (patch)
treefdabad9c786c54f0cdb2c8ec36eca51d0f2050e1
parent6bad505fe05fe36557de1db0a16a84bcc3e1aa48 (diff)
downloadchromium_src-e088f02c609c97c659633fc4fe77a0198101e494.zip
chromium_src-e088f02c609c97c659633fc4fe77a0198101e494.tar.gz
chromium_src-e088f02c609c97c659633fc4fe77a0198101e494.tar.bz2
mac: Add metrics to record Bluetooth availability and capabilities.
The new Handoff feature in OSX 10.10 only works with devices that support Bluetooth LE. Record metrics to determine the percentage of Chrome users that this affects. BUG=392166 Review URL: https://codereview.chromium.org/374203004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282771 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--base/mac/sdk_forward_declarations.h4
-rw-r--r--chrome/browser/mac/bluetooth_utility.h28
-rw-r--r--chrome/browser/mac/bluetooth_utility.mm82
-rw-r--r--chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc9
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--tools/metrics/histograms/histograms.xml16
6 files changed, 141 insertions, 0 deletions
diff --git a/base/mac/sdk_forward_declarations.h b/base/mac/sdk_forward_declarations.h
index 3a0878da..1a27b5d 100644
--- a/base/mac/sdk_forward_declarations.h
+++ b/base/mac/sdk_forward_declarations.h
@@ -160,6 +160,10 @@ enum CWChannelBand {
- (BluetoothHCIPowerState)powerState;
@end
+enum {
+ kBluetoothFeatureLESupportedController = (1 << 6L),
+};
+
@protocol IOBluetoothDeviceInquiryDelegate
- (void)deviceInquiryStarted:(IOBluetoothDeviceInquiry*)sender;
- (void)deviceInquiryDeviceFound:(IOBluetoothDeviceInquiry*)sender
diff --git a/chrome/browser/mac/bluetooth_utility.h b/chrome/browser/mac/bluetooth_utility.h
new file mode 100644
index 0000000..df54d35
--- /dev/null
+++ b/chrome/browser/mac/bluetooth_utility.h
@@ -0,0 +1,28 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_MAC_BLUETOOTH_UTILITY_H_
+#define CHROME_BROWSER_MAC_BLUETOOTH_UTILITY_H_
+
+namespace bluetooth_utility {
+
+// The enum is used in a histogram, so the values must not change.
+enum BluetoothAvailability {
+ BLUETOOTH_AVAILABILITY_ERROR = 0, // Error determining availability.
+ BLUETOOTH_NOT_AVAILABLE = 1,
+ BLUETOOTH_AVAILABLE_WITHOUT_LE = 2,
+ BLUETOOTH_AVAILABLE_WITH_LE = 3,
+
+ // On OSX 10.6, if the Link Manager Protocol version supports Low Energy,
+ // there is no further indication of whether Low Energy is supported.
+ BLUETOOTH_AVAILABLE_LE_UNKNOWN = 4,
+ BLUETOOTH_AVAILABILITY_COUNT,
+};
+
+// Returns the bluetooth availability of the system's hardware.
+BluetoothAvailability GetBluetoothAvailability();
+
+} // namespace bluetooth_utility
+
+#endif // CHROME_BROWSER_MAC_BLUETOOTH_UTILITY_H_
diff --git a/chrome/browser/mac/bluetooth_utility.mm b/chrome/browser/mac/bluetooth_utility.mm
new file mode 100644
index 0000000..26824d9
--- /dev/null
+++ b/chrome/browser/mac/bluetooth_utility.mm
@@ -0,0 +1,82 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/mac/bluetooth_utility.h"
+
+#import <Foundation/Foundation.h>
+#include <IOKit/IOKitLib.h>
+
+#include "base/mac/foundation_util.h"
+#include "base/mac/mac_util.h"
+#include "base/mac/scoped_ioobject.h"
+#include "base/mac/sdk_forward_declarations.h"
+
+namespace bluetooth_utility {
+
+BluetoothAvailability GetBluetoothAvailability() {
+ base::ScopedCFTypeRef<CFMutableDictionaryRef> matching_dict(
+ IOServiceMatching("IOBluetoothHCIController"));
+ if (!matching_dict)
+ return BLUETOOTH_AVAILABILITY_ERROR;
+
+ // IOServiceGetMatchingServices takes ownership of matching_dict.
+ io_iterator_t iter;
+ int kr = IOServiceGetMatchingServices(
+ kIOMasterPortDefault, matching_dict.release(), &iter);
+ if (kr != KERN_SUCCESS)
+ return BLUETOOTH_NOT_AVAILABLE;
+ base::mac::ScopedIOObject<io_iterator_t> scoped_iter(iter);
+
+ int bluetooth_available = false;
+ base::mac::ScopedIOObject<io_service_t> device;
+ while (device.reset(IOIteratorNext(scoped_iter.get())), device) {
+ bluetooth_available = true;
+
+ CFMutableDictionaryRef dict;
+ kr = IORegistryEntryCreateCFProperties(
+ device, &dict, kCFAllocatorDefault, kNilOptions);
+ if (kr != KERN_SUCCESS)
+ continue;
+ base::ScopedCFTypeRef<CFMutableDictionaryRef> scoped_dict(dict);
+
+ NSDictionary* objc_dict = base::mac::CFToNSCast(scoped_dict.get());
+ NSNumber* lmp_version =
+ base::mac::ObjCCast<NSNumber>([objc_dict objectForKey:@"LMPVersion"]);
+ if (!lmp_version)
+ continue;
+
+ // The LMP version is too low to support Bluetooth LE.
+ if ([lmp_version intValue] < 6)
+ continue;
+
+ // Check the supported features registry entry for Bluetooth LE
+ // availability. The relevant bit has a different meaning on OSX 10.6, and
+ // could change again in the future.
+ if (base::mac::IsOSSnowLeopard())
+ return BLUETOOTH_AVAILABLE_LE_UNKNOWN;
+
+ NSData* data = base::mac::ObjCCast<NSData>(
+ [objc_dict objectForKey:@"HCISupportedFeatures"]);
+
+ NSUInteger supported_features_index = 4;
+ NSUInteger length = [data length];
+ if (length < supported_features_index + 1)
+ continue;
+
+ // The bytes are indexed in reverse order.
+ NSUInteger index = length - supported_features_index - 1;
+
+ const unsigned char* bytes =
+ static_cast<const unsigned char*>([data bytes]);
+ const unsigned char byte = bytes[index];
+ bool le_supported = byte & kBluetoothFeatureLESupportedController;
+ if (le_supported)
+ return BLUETOOTH_AVAILABLE_WITH_LE;
+ }
+
+ return bluetooth_available ? BLUETOOTH_AVAILABLE_WITHOUT_LE
+ : BLUETOOTH_AVAILABILITY_ERROR;
+}
+
+} // namespace bluetooth_utility
diff --git a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
index bd9ccf2..93f0f46 100644
--- a/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
+++ b/chrome/browser/metrics/chrome_browser_main_extra_parts_metrics.cc
@@ -18,6 +18,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chrome_browser_main.h"
#include "chrome/browser/chrome_browser_metrics_service_observer.h"
+#include "chrome/browser/mac/bluetooth_utility.h"
#include "chrome/browser/pref_service_flags_storage.h"
#include "chrome/browser/shell_integration.h"
#include "content/public/browser/browser_thread.h"
@@ -94,6 +95,14 @@ void RecordStartupMetricsOnBlockingPool() {
#if defined(OS_WIN)
GoogleUpdateSettings::RecordChromeUpdatePolicyHistograms();
#endif // defined(OS_WIN)
+
+#if defined(OS_MACOSX) && !defined(OS_IOS)
+ bluetooth_utility::BluetoothAvailability availability =
+ bluetooth_utility::GetBluetoothAvailability();
+ UMA_HISTOGRAM_ENUMERATION("OSX.BluetoothAvailability",
+ availability,
+ bluetooth_utility::BLUETOOTH_AVAILABILITY_COUNT);
+#endif // defined(OS_MACOSX) && !defined(OS_IOS)
}
void RecordLinuxGlibcVersion() {
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 147ee16..533feba 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -656,6 +656,8 @@
'browser/lifetime/application_lifetime_win.cc',
'browser/mac/dock.h',
'browser/mac/dock.mm',
+ 'browser/mac/bluetooth_utility.h',
+ 'browser/mac/bluetooth_utility.mm',
'browser/mac/install_from_dmg.h',
'browser/mac/install_from_dmg.mm',
'browser/mac/keystone_glue.h',
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index b8d29d6..1374c6a 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -18976,6 +18976,14 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<summary>The number of clicks on the origin chip.</summary>
</histogram>
+<histogram name="OSX.BluetoothAvailability" enum="BluetoothAvailability">
+ <owner>erikchen@chromium.org</owner>
+ <summary>
+ The availability and capabilities of the Bluetooth driver on OSX devices.
+ This metric is logged on startup.
+ </summary>
+</histogram>
+
<histogram name="OSX.CatSixtyFour" enum="CatSixtyFour">
<owner>mark@chromium.org</owner>
<summary>The cat's flavor and how many bits there are in it.</summary>
@@ -35540,6 +35548,14 @@ Therefore, the affected-histogram name has to have at least one dot in it.
<int value="5" label="Blacklist disabled."/>
</enum>
+<enum name="BluetoothAvailability" type="int">
+ <int value="0" label="Unexpected error"/>
+ <int value="1" label="Not available"/>
+ <int value="2" label="Available without LE"/>
+ <int value="3" label="Available with LE"/>
+ <int value="4" label="Available unknown LE"/>
+</enum>
+
<enum name="BluetoothPairingMethod" type="int">
<int value="0" label="No user interaction required"/>
<int value="1" label="PIN Code requested from user"/>