Skip to content

Commit

Permalink
Add GetConnectionInfo function for BluetoothDevice, replacing the exi…
Browse files Browse the repository at this point in the history
…sting

GetRSSI, GetHostTransmitPower, and GetMaximumHostTransmitPower functions.

On Mac, this function uses IOBluetooth APIs.
On ChromeOS, this function is a wrapper for the GetConnInfo() DBus plugin API.
On Windows, this function is unimplemented.

BUG=382683

Review URL: https://codereview.chromium.org/735893002

Cr-Commit-Position: refs/heads/master@{#310372}
  • Loading branch information
tengs authored and Commit bot committed Jan 7, 2015
1 parent 574fc99 commit d060690
Show file tree
Hide file tree
Showing 19 changed files with 246 additions and 305 deletions.
80 changes: 38 additions & 42 deletions chromeos/dbus/bluetooth_device_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,13 @@

namespace chromeos {

namespace {

// Value returned for the the RSSI or TX power if it cannot be read.
const int kUnknownPower = 127;

} // namespace

const char BluetoothDeviceClient::kNoResponseError[] =
"org.chromium.Error.NoResponse";
const char BluetoothDeviceClient::kUnknownDeviceError[] =
Expand All @@ -41,10 +48,6 @@ BluetoothDeviceClient::Properties::Properties(
RegisterProperty(bluetooth_device::kLegacyPairingProperty, &legacy_pairing);
RegisterProperty(bluetooth_device::kModaliasProperty, &modalias);
RegisterProperty(bluetooth_device::kRSSIProperty, &rssi);
RegisterProperty(bluetooth_device::kConnectionRSSI, &connection_rssi);
RegisterProperty(bluetooth_device::kConnectionTXPower, &connection_tx_power);
RegisterProperty(bluetooth_device::kConnectionTXPowerMax,
&connection_tx_power_max);
}

BluetoothDeviceClient::Properties::~Properties() {
Expand Down Expand Up @@ -273,37 +276,12 @@ class BluetoothDeviceClientImpl
}

// BluetoothDeviceClient override.
virtual void StartConnectionMonitor(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const ErrorCallback& error_callback) override {
dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
bluetooth_device::kStartConnectionMonitor);

dbus::ObjectProxy* object_proxy =
object_manager_->GetObjectProxy(object_path);
if (!object_proxy) {
error_callback.Run(kUnknownDeviceError, "");
return;
}
object_proxy->CallMethodWithErrorCallback(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
weak_ptr_factory_.GetWeakPtr(),
callback),
base::Bind(&BluetoothDeviceClientImpl::OnError,
weak_ptr_factory_.GetWeakPtr(),
error_callback));
}

// BluetoothDeviceClient override.
virtual void StopConnectionMonitor(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const ErrorCallback& error_callback) override {
dbus::MethodCall method_call(bluetooth_device::kBluetoothDeviceInterface,
bluetooth_device::kStopConnectionMonitor);
void GetConnInfo(const dbus::ObjectPath& object_path,
const ConnInfoCallback& callback,
const ErrorCallback& error_callback) override {
dbus::MethodCall method_call(
bluetooth_plugin_device::kBluetoothPluginInterface,
bluetooth_plugin_device::kGetConnInfo);

dbus::ObjectProxy* object_proxy =
object_manager_->GetObjectProxy(object_path);
Expand All @@ -312,14 +290,11 @@ class BluetoothDeviceClientImpl
return;
}
object_proxy->CallMethodWithErrorCallback(
&method_call,
dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&BluetoothDeviceClientImpl::OnSuccess,
weak_ptr_factory_.GetWeakPtr(),
callback),
&method_call, dbus::ObjectProxy::TIMEOUT_USE_DEFAULT,
base::Bind(&BluetoothDeviceClientImpl::OnGetConnInfoSuccess,
weak_ptr_factory_.GetWeakPtr(), callback),
base::Bind(&BluetoothDeviceClientImpl::OnError,
weak_ptr_factory_.GetWeakPtr(),
error_callback));
weak_ptr_factory_.GetWeakPtr(), error_callback));
}

protected:
Expand Down Expand Up @@ -365,6 +340,27 @@ class BluetoothDeviceClientImpl
callback.Run();
}

// Called when a response for the GetConnInfo method is received.
void OnGetConnInfoSuccess(const ConnInfoCallback& callback,
dbus::Response* response) {
int16 rssi = kUnknownPower;
int16 transmit_power = kUnknownPower;
int16 max_transmit_power = kUnknownPower;

if (!response) {
LOG(ERROR) << "GetConnInfo succeeded, but no response received.";
callback.Run(rssi, transmit_power, max_transmit_power);
return;
}

dbus::MessageReader reader(response);
if (!reader.PopInt16(&rssi) || !reader.PopInt16(&transmit_power) ||
!reader.PopInt16(&max_transmit_power)) {
LOG(ERROR) << "Arguments for GetConnInfo invalid.";
}
callback.Run(rssi, transmit_power, max_transmit_power);
}

// Called when a response for a failed method call is received.
void OnError(const ErrorCallback& error_callback,
dbus::ErrorResponse* response) {
Expand Down
38 changes: 12 additions & 26 deletions chromeos/dbus/bluetooth_device_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,20 +80,6 @@ class CHROMEOS_EXPORT BluetoothDeviceClient : public DBusClient {
// discovered during inquiry. Read-only.
dbus::Property<int16> rssi;

// Received signal strength indicator when a connection is open to the
// device. This property is not set unless connection monitor is enabled.
// Read-only.
dbus::Property<int16> connection_rssi;

// The transmit power level of the host when a connection is open
// to the device. This property is not set unless connection monitor is
// enabled. Read-only.
dbus::Property<int16> connection_tx_power;

// The maximum transmit power level of the host that can be set
// when connected to the device. Read-only.
dbus::Property<int16> connection_tx_power_max;

Properties(dbus::ObjectProxy* object_proxy,
const std::string& interface_name,
const PropertyChangedCallback& callback);
Expand Down Expand Up @@ -184,18 +170,18 @@ class CHROMEOS_EXPORT BluetoothDeviceClient : public DBusClient {
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;

// Starts connection monitor for the device with object path
// |object_path|. Connection monitor is a mode the connection properties,
// RSSI and TX power are tracked and updated when they change.
virtual void StartConnectionMonitor(const dbus::ObjectPath& object_path,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;

// Stops connection monitor for the device with object path
// |object_path|.
virtual void StopConnectionMonitor(const dbus::ObjectPath& object_path,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;
// The callback invoked for a successful GetConnInfo API call with the
// RSSI, TX power, and maximum TX power of the current connection.
typedef base::Callback<void(int16 rssi,
int16 transmit_power,
int16 max_transmit_power)> ConnInfoCallback;

// Returns the RSSI, TX power, and maximum TX power of a connection to the
// device with object path |object_path|. If the device is not connected, then
// an error will be returned.
virtual void GetConnInfo(const dbus::ObjectPath& object_path,
const ConnInfoCallback& callback,
const ErrorCallback& error_callback) = 0;

// Creates the instance.
static BluetoothDeviceClient* Create();
Expand Down
36 changes: 23 additions & 13 deletions chromeos/dbus/fake_bluetooth_device_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ const int kSimulationIntervalMs = 750;
const int kMinRSSI = -90;
const int kMaxRSSI = -30;

// The default value of connection info properties from GetConnInfo().
const int kUnkownPower = 127;


void SimulatedProfileSocket(int fd) {
// Simulate a server-side socket of a profile; read data from the socket,
Expand Down Expand Up @@ -221,7 +224,9 @@ FakeBluetoothDeviceClient::FakeBluetoothDeviceClient()
discovery_simulation_step_(0),
incoming_pairing_simulation_step_(0),
pairing_cancelled_(false),
connection_monitor_started_(false) {
connection_rssi_(kUnkownPower),
transmit_power_(kUnkownPower),
max_transmit_power_(kUnkownPower) {
Properties* properties = new Properties(base::Bind(
&FakeBluetoothDeviceClient::OnPropertyChanged,
base::Unretained(this),
Expand Down Expand Up @@ -461,21 +466,17 @@ void FakeBluetoothDeviceClient::CancelPairing(
callback.Run();
}

void FakeBluetoothDeviceClient::StartConnectionMonitor(
void FakeBluetoothDeviceClient::GetConnInfo(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const ConnInfoCallback& callback,
const ErrorCallback& error_callback) {
VLOG(1) << "StartConnectionMonitor: " << object_path.value();
connection_monitor_started_ = true;
callback.Run();
}
Properties* properties = GetProperties(object_path);
if (!properties->connected.value()) {
error_callback.Run("org.bluez.Error.NotConnected", "Not Connected");
return;
}

void FakeBluetoothDeviceClient::StopConnectionMonitor(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const ErrorCallback& error_callback) {
connection_monitor_started_ = false;
callback.Run();
callback.Run(connection_rssi_, transmit_power_, max_transmit_power_);
}

void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
Expand Down Expand Up @@ -1019,6 +1020,15 @@ void FakeBluetoothDeviceClient::UpdateDeviceRSSI(
properties->rssi.ReplaceValue(rssi);
}

void FakeBluetoothDeviceClient::UpdateConnectionInfo(
uint16 connection_rssi,
uint16 transmit_power,
uint16 max_transmit_power) {
connection_rssi_ = connection_rssi;
transmit_power_ = transmit_power;
max_transmit_power_ = max_transmit_power;
}

void FakeBluetoothDeviceClient::PinCodeCallback(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
Expand Down
22 changes: 13 additions & 9 deletions chromeos/dbus/fake_bluetooth_device_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,9 @@ class CHROMEOS_EXPORT FakeBluetoothDeviceClient
virtual void CancelPairing(const dbus::ObjectPath& object_path,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
virtual void StartConnectionMonitor(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
virtual void StopConnectionMonitor(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
void GetConnInfo(const dbus::ObjectPath& object_path,
const ConnInfoCallback& callback,
const ErrorCallback& error_callback) override;

void SetSimulationIntervalMs(int interval_ms);

Expand Down Expand Up @@ -105,6 +100,12 @@ class CHROMEOS_EXPORT FakeBluetoothDeviceClient
const base::Closure& callback,
const ErrorCallback& error_callback);

// Updates the connection properties of the fake device that will be returned
// by GetConnInfo.
void UpdateConnectionInfo(uint16 connection_rssi,
uint16 transmit_power,
uint16 max_transmit_power);

// Object paths, names, addresses and bluetooth classes of the devices
// we can emulate.
static const char kPairedDevicePath[];
Expand Down Expand Up @@ -250,7 +251,10 @@ class CHROMEOS_EXPORT FakeBluetoothDeviceClient
uint32_t discovery_simulation_step_;
uint32_t incoming_pairing_simulation_step_;
bool pairing_cancelled_;
bool connection_monitor_started_;

int16 connection_rssi_;
int16 transmit_power_;
int16 max_transmit_power_;
};

} // namespace chromeos
Expand Down
4 changes: 1 addition & 3 deletions device/bluetooth/bluetooth_adapter_chromeos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -379,9 +379,7 @@ void BluetoothAdapterChromeOS::DevicePropertyChanged(
property_name == properties->trusted.name() ||
property_name == properties->connected.name() ||
property_name == properties->uuids.name() ||
property_name == properties->rssi.name() ||
property_name == properties->connection_rssi.name() ||
property_name == properties->connection_tx_power.name())
property_name == properties->rssi.name())
NotifyDeviceChanged(device_chromeos);

// When a device becomes paired, mark it as trusted so that the user does
Expand Down
46 changes: 46 additions & 0 deletions device/bluetooth/bluetooth_chromeos_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ class TestObserver : public BluetoothAdapter::Observer {
scoped_refptr<BluetoothAdapter> adapter_;
};

// Callback for BluetoothDevice::GetConnectionInfo() that simply saves the
// connection info to the bound argument.
void SaveConnectionInfo(BluetoothDevice::ConnectionInfo* out,
const BluetoothDevice::ConnectionInfo& conn_info) {
*out = conn_info;
};

} // namespace

class TestPairingDelegate : public BluetoothDevice::PairingDelegate {
Expand Down Expand Up @@ -3272,4 +3279,43 @@ TEST_F(BluetoothChromeOSTest, DeviceId) {
EXPECT_EQ(0, device->GetDeviceID());
}

TEST_F(BluetoothChromeOSTest, GetConnectionInfoForDisconnectedDevice) {
GetAdapter();
BluetoothDevice* device =
adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);

// Calling GetConnectionInfo for an unconnected device should return a result
// in which all fields are filled with BluetoothDevice::kUnknownPower.
BluetoothDevice::ConnectionInfo conn_info(0, 0, 0);
device->GetConnectionInfo(base::Bind(&SaveConnectionInfo, &conn_info));
int unknown_power = BluetoothDevice::kUnknownPower;
EXPECT_NE(0, unknown_power);
EXPECT_EQ(unknown_power, conn_info.rssi);
EXPECT_EQ(unknown_power, conn_info.transmit_power);
EXPECT_EQ(unknown_power, conn_info.max_transmit_power);
}

TEST_F(BluetoothChromeOSTest, GetConnectionInfoForConnectedDevice) {
GetAdapter();
BluetoothDevice* device =
adapter_->GetDevice(FakeBluetoothDeviceClient::kPairedDeviceAddress);

device->Connect(
NULL,
base::Bind(&BluetoothChromeOSTest::Callback,
base::Unretained(this)),
base::Bind(&BluetoothChromeOSTest::ConnectErrorCallback,
base::Unretained(this)));
EXPECT_TRUE(device->IsConnected());

// Calling GetConnectionInfo for a connected device should return valid
// results.
fake_bluetooth_device_client_->UpdateConnectionInfo(-10, 3, 4);
BluetoothDevice::ConnectionInfo conn_info;
device->GetConnectionInfo(base::Bind(&SaveConnectionInfo, &conn_info));
EXPECT_EQ(-10, conn_info.rssi);
EXPECT_EQ(3, conn_info.transmit_power);
EXPECT_EQ(4, conn_info.max_transmit_power);
}

} // namespace chromeos
13 changes: 13 additions & 0 deletions device/bluetooth/bluetooth_device.cc
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ BluetoothDevice::~BluetoothDevice() {
STLDeleteValues(&gatt_services_);
}

BluetoothDevice::ConnectionInfo::ConnectionInfo()
: rssi(kUnknownPower),
transmit_power(kUnknownPower),
max_transmit_power(kUnknownPower) {}

BluetoothDevice::ConnectionInfo::ConnectionInfo(
int rssi, int transmit_power, int max_transmit_power)
: rssi(rssi),
transmit_power(transmit_power),
max_transmit_power(max_transmit_power) {}

BluetoothDevice::ConnectionInfo::~ConnectionInfo() {}

base::string16 BluetoothDevice::GetName() const {
std::string name = GetDeviceName();
if (!name.empty()) {
Expand Down
Loading

0 comments on commit d060690

Please sign in to comment.