From eb6725fe48e19c20cda719fec1e0044a1229b7bb Mon Sep 17 00:00:00 2001 From: "isherman@chromium.org" Date: Thu, 1 May 2014 06:13:30 +0000 Subject: Expose device RSSI and Tx power via the chrome.bluetooth API. This CL only implements the fetching of these values on Mac. BUG=365966 TEST=browser_tests R=kalman@chromium.org, keybuk@chromium.org Review URL: https://codereview.chromium.org/246603008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@267458 0039d316-1c4b-4281-b951-d872f2087c98 --- device/bluetooth/bluetooth_device.h | 25 ++++++++++ device/bluetooth/bluetooth_device_chromeos.cc | 15 ++++++ device/bluetooth/bluetooth_device_chromeos.h | 3 ++ device/bluetooth/bluetooth_device_mac.h | 10 ++++ device/bluetooth/bluetooth_device_mac.mm | 63 +++++++++++++++++++++++--- device/bluetooth/bluetooth_device_win.cc | 15 ++++++ device/bluetooth/bluetooth_device_win.h | 3 ++ device/bluetooth/test/mock_bluetooth_device.cc | 6 +++ device/bluetooth/test/mock_bluetooth_device.h | 3 ++ 9 files changed, 137 insertions(+), 6 deletions(-) (limited to 'device/bluetooth') diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h index 28fd7ac..220066c 100644 --- a/device/bluetooth/bluetooth_device.h +++ b/device/bluetooth/bluetooth_device.h @@ -66,6 +66,9 @@ class BluetoothDevice { DEVICE_KEYBOARD_MOUSE_COMBO }; + // The value returned if the RSSI or transmit power cannot be read. + static const int kUnknownPower = 127; + // Possible errors passed back to an error callback function in case of a // failed call to Connect(). enum ConnectErrorCode { @@ -227,6 +230,28 @@ class BluetoothDevice { // DEVICE_PERIPHERAL. DeviceType GetDeviceType() const; + // Gets the "received signal strength indication" (RSSI) of the current + // connection to the device. The RSSI indicates the power present in the + // received radio signal, measured in dBm, to a resolution of 1dBm. Larger + // (typically, less negative) values indicate a stronger signal. + // If the device is not currently connected, then returns the RSSI read from + // the last inquiry that returned the device, where available. In case of an + // error, returns |kUnknownPower|. Otherwise, returns the connection's RSSI. + virtual int GetRSSI() const = 0; + + // These two methods are used to read the current or maximum transmit power + // ("Tx power") of the current connection to the device. The transmit power + // indicates the strength of the signal broadcast from the host's Bluetooth + // antenna when communicating with the device, measured in dBm, to a + // resolution of 1dBm. Larger (typically, less negative) values + // indicate a stronger signal. + // It is only meaningful to call this method when there is a connection + // established to the device. If there is no connection, or in case of an + // error, returns |kUnknownPower|. Otherwise, returns the connection's + // transmit power. + virtual int GetCurrentHostTransmitPower() const = 0; + virtual int GetMaximumHostTransmitPower() const = 0; + // Indicates whether the device is known to support pairing based on its // device class and address. bool IsPairable() const; diff --git a/device/bluetooth/bluetooth_device_chromeos.cc b/device/bluetooth/bluetooth_device_chromeos.cc index b5f7386..e894136 100644 --- a/device/bluetooth/bluetooth_device_chromeos.cc +++ b/device/bluetooth/bluetooth_device_chromeos.cc @@ -212,6 +212,21 @@ uint16 BluetoothDeviceChromeOS::GetDeviceID() const { return device_id; } +int BluetoothDeviceChromeOS::GetRSSI() const { + NOTIMPLEMENTED(); + return kUnknownPower; +} + +int BluetoothDeviceChromeOS::GetCurrentHostTransmitPower() const { + NOTIMPLEMENTED(); + return kUnknownPower; +} + +int BluetoothDeviceChromeOS::GetMaximumHostTransmitPower() const { + NOTIMPLEMENTED(); + return kUnknownPower; +} + bool BluetoothDeviceChromeOS::IsPaired() const { BluetoothDeviceClient::Properties* properties = DBusThreadManager::Get()->GetBluetoothDeviceClient()-> diff --git a/device/bluetooth/bluetooth_device_chromeos.h b/device/bluetooth/bluetooth_device_chromeos.h index 156d9ea..96265ae 100644 --- a/device/bluetooth/bluetooth_device_chromeos.h +++ b/device/bluetooth/bluetooth_device_chromeos.h @@ -37,6 +37,9 @@ class BluetoothDeviceChromeOS virtual uint16 GetVendorID() const OVERRIDE; virtual uint16 GetProductID() const OVERRIDE; virtual uint16 GetDeviceID() const OVERRIDE; + virtual int GetRSSI() const OVERRIDE; + virtual int GetCurrentHostTransmitPower() const OVERRIDE; + virtual int GetMaximumHostTransmitPower() const OVERRIDE; virtual bool IsPaired() const OVERRIDE; virtual bool IsConnected() const OVERRIDE; virtual bool IsConnectable() const OVERRIDE; diff --git a/device/bluetooth/bluetooth_device_mac.h b/device/bluetooth/bluetooth_device_mac.h index ec87ff7..1503f1dc 100644 --- a/device/bluetooth/bluetooth_device_mac.h +++ b/device/bluetooth/bluetooth_device_mac.h @@ -5,6 +5,8 @@ #ifndef DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_MAC_H_ #define DEVICE_BLUETOOTH_BLUETOOTH_DEVICE_MAC_H_ +#import + #include #include "base/basictypes.h" @@ -32,6 +34,9 @@ class BluetoothDeviceMac : public BluetoothDevice { virtual uint16 GetVendorID() const OVERRIDE; virtual uint16 GetProductID() const OVERRIDE; virtual uint16 GetDeviceID() const OVERRIDE; + virtual int GetRSSI() const OVERRIDE; + virtual int GetCurrentHostTransmitPower() const OVERRIDE; + virtual int GetMaximumHostTransmitPower() const OVERRIDE; virtual bool IsPaired() const OVERRIDE; virtual bool IsConnected() const OVERRIDE; virtual bool IsConnectable() const OVERRIDE; @@ -72,6 +77,11 @@ class BluetoothDeviceMac : public BluetoothDevice { private: friend class BluetoothAdapterMac; + // Implementation to read the host's transmit power level of type + // |power_level_type|. + int GetHostTransmitPower( + BluetoothHCITransmitPowerLevelType power_level_type) const; + // List of observers interested in event notifications from us. ObserverList observers_; diff --git a/device/bluetooth/bluetooth_device_mac.mm b/device/bluetooth/bluetooth_device_mac.mm index 24c2b45..aaeffb8 100644 --- a/device/bluetooth/bluetooth_device_mac.mm +++ b/device/bluetooth/bluetooth_device_mac.mm @@ -4,11 +4,6 @@ #include "device/bluetooth/bluetooth_device_mac.h" -#include -#import -#import -#import - #include #include "base/basictypes.h" @@ -28,13 +23,23 @@ @interface IOBluetoothDevice (LionSDKDeclarations) - (NSString*)addressString; -- (NSString*)name; - (unsigned int)classOfDevice; +- (BluetoothConnectionHandle)connectionHandle; +- (BluetoothHCIRSSIValue)rawRSSI; - (NSArray*)services; @end #endif // MAC_OS_X_VERSION_10_7 +// Undocumented API for accessing the Bluetooth transmit power level. +// Similar to the API defined here [ http://goo.gl/20Q5vE ]. +@interface IOBluetoothHostController (UndocumentedAPI) +- (IOReturn) + BluetoothHCIReadTransmitPowerLevel:(BluetoothConnectionHandle)connection + inType:(BluetoothHCITransmitPowerLevelType)type + outTransmitPowerLevel:(BluetoothHCITransmitPowerLevel*)level; +@end + namespace device { BluetoothDeviceMac::BluetoothDeviceMac(IOBluetoothDevice* device) @@ -84,6 +89,30 @@ uint16 BluetoothDeviceMac::GetDeviceID() const { return 0; } +int BluetoothDeviceMac::GetRSSI() const { + if (![device_ isConnected]) { + NOTIMPLEMENTED(); + return kUnknownPower; + } + + int rssi = [device_ rawRSSI]; + + // The API guarantees that +127 is returned in case the RSSI is not readable: + // http://goo.gl/bpURYv + if (rssi == 127) + return kUnknownPower; + + return rssi; +} + +int BluetoothDeviceMac::GetCurrentHostTransmitPower() const { + return GetHostTransmitPower(kReadCurrentTransmitPowerLevel); +} + +int BluetoothDeviceMac::GetMaximumHostTransmitPower() const { + return GetHostTransmitPower(kReadMaximumTransmitPowerLevel); +} + bool BluetoothDeviceMac::IsPaired() const { return [device_ isPaired]; } @@ -183,4 +212,26 @@ void BluetoothDeviceMac::ClearOutOfBandPairingData( NOTIMPLEMENTED(); } +int BluetoothDeviceMac::GetHostTransmitPower( + BluetoothHCITransmitPowerLevelType power_level_type) const { + IOBluetoothHostController* controller = + [IOBluetoothHostController defaultController]; + + // Bail if the undocumented API is unavailable on this machine. + SEL selector = @selector( + BluetoothHCIReadTransmitPowerLevel:inType:outTransmitPowerLevel:); + if (![controller respondsToSelector:selector]) + return kUnknownPower; + + BluetoothHCITransmitPowerLevel power_level; + IOReturn result = + [controller BluetoothHCIReadTransmitPowerLevel:[device_ connectionHandle] + inType:power_level_type + outTransmitPowerLevel:&power_level]; + if (result != kIOReturnSuccess) + return kUnknownPower; + + return power_level; +} + } // namespace device diff --git a/device/bluetooth/bluetooth_device_win.cc b/device/bluetooth/bluetooth_device_win.cc index 81a9386..53995ff 100644 --- a/device/bluetooth/bluetooth_device_win.cc +++ b/device/bluetooth/bluetooth_device_win.cc @@ -111,6 +111,21 @@ uint16 BluetoothDeviceWin::GetDeviceID() const { return 0; } +int BluetoothDeviceWin::GetRSSI() const { + NOTIMPLEMENTED(); + return kUnknownPower; +} + +int BluetoothDeviceWin::GetCurrentHostTransmitPower() const { + NOTIMPLEMENTED(); + return kUnknownPower; +} + +int BluetoothDeviceWin::GetMaximumHostTransmitPower() const { + NOTIMPLEMENTED(); + return kUnknownPower; +} + bool BluetoothDeviceWin::IsPaired() const { return paired_; } diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h index 232da0f..128a87c 100644 --- a/device/bluetooth/bluetooth_device_win.h +++ b/device/bluetooth/bluetooth_device_win.h @@ -40,6 +40,9 @@ class BluetoothDeviceWin : public BluetoothDevice { virtual uint16 GetVendorID() const OVERRIDE; virtual uint16 GetProductID() const OVERRIDE; virtual uint16 GetDeviceID() const OVERRIDE; + virtual int GetRSSI() const OVERRIDE; + virtual int GetCurrentHostTransmitPower() const OVERRIDE; + virtual int GetMaximumHostTransmitPower() const OVERRIDE; virtual bool IsPaired() const OVERRIDE; virtual bool IsConnected() const OVERRIDE; virtual bool IsConnectable() const OVERRIDE; diff --git a/device/bluetooth/test/mock_bluetooth_device.cc b/device/bluetooth/test/mock_bluetooth_device.cc index 5235d5b..e8130da 100644 --- a/device/bluetooth/test/mock_bluetooth_device.cc +++ b/device/bluetooth/test/mock_bluetooth_device.cc @@ -26,6 +26,12 @@ MockBluetoothDevice::MockBluetoothDevice(MockBluetoothAdapter* adapter, .WillByDefault(testing::Return(address_)); ON_CALL(*this, GetDeviceType()) .WillByDefault(testing::Return(DEVICE_UNKNOWN)); + ON_CALL(*this, GetRSSI()) + .WillByDefault(testing::Return(kUnknownPower)); + ON_CALL(*this, GetCurrentHostTransmitPower()) + .WillByDefault(testing::Return(kUnknownPower)); + ON_CALL(*this, GetMaximumHostTransmitPower()) + .WillByDefault(testing::Return(kUnknownPower)); ON_CALL(*this, GetVendorIDSource()) .WillByDefault(testing::Return(VENDOR_ID_UNKNOWN)); ON_CALL(*this, GetVendorID()) diff --git a/device/bluetooth/test/mock_bluetooth_device.h b/device/bluetooth/test/mock_bluetooth_device.h index 4d910d1..9291e9b 100644 --- a/device/bluetooth/test/mock_bluetooth_device.h +++ b/device/bluetooth/test/mock_bluetooth_device.h @@ -38,6 +38,9 @@ class MockBluetoothDevice : public BluetoothDevice { MOCK_CONST_METHOD0(GetDeviceID, uint16()); MOCK_CONST_METHOD0(GetName, base::string16()); MOCK_CONST_METHOD0(GetDeviceType, BluetoothDevice::DeviceType()); + MOCK_CONST_METHOD0(GetRSSI, int()); + MOCK_CONST_METHOD0(GetCurrentHostTransmitPower, int()); + MOCK_CONST_METHOD0(GetMaximumHostTransmitPower, int()); MOCK_CONST_METHOD0(IsPaired, bool()); MOCK_CONST_METHOD0(IsConnected, bool()); MOCK_CONST_METHOD0(IsConnectable, bool()); -- cgit v1.1