Skip to content

Commit

Permalink
device/bluetooth: Add SetConnectionLatency API to "bluetooth_device".
Browse files Browse the repository at this point in the history
This CL implements this API only for BlueZ devices using the new SetLEConnectionParameters DBus API. Support for other platforms will come later.

BUG=721559

Review-Url: https://codereview.chromium.org/2901593002
Cr-Commit-Position: refs/heads/master@{#474566}
  • Loading branch information
tengs authored and Commit bot committed May 25, 2017
1 parent a173de9 commit c967751
Show file tree
Hide file tree
Showing 18 changed files with 223 additions and 0 deletions.
3 changes: 3 additions & 0 deletions device/bluetooth/bluetooth_classic_device_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ class BluetoothClassicDeviceMac : public BluetoothDeviceMac {
bool ExpectingPasskey() const override;
bool ExpectingConfirmation() const override;
void GetConnectionInfo(const ConnectionInfoCallback& callback) override;
void SetConnectionLatency(ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
void Connect(PairingDelegate* pairing_delegate,
const base::Closure& callback,
const ConnectErrorCallback& error_callback) override;
Expand Down
7 changes: 7 additions & 0 deletions device/bluetooth/bluetooth_classic_device_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ BluetoothUUID ExtractUuid(IOBluetoothSDPDataElement* service_class_data) {
callback.Run(connection_info);
}

void BluetoothClassicDeviceMac::SetConnectionLatency(
ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) {
NOTIMPLEMENTED();
}

void BluetoothClassicDeviceMac::Connect(
PairingDelegate* pairing_delegate,
const base::Closure& callback,
Expand Down
13 changes: 13 additions & 0 deletions device/bluetooth/bluetooth_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDevice {
~ConnectionInfo();
};

// Possible connection latency values to pass to SetConnectionLatency().
enum ConnectionLatency {
CONNECTION_LATENCY_LOW,
CONNECTION_LATENCY_MEDIUM,
CONNECTION_LATENCY_HIGH,
};

// Possible errors passed back to an error callback function in case of a
// failed call to Connect().
enum ConnectErrorCode {
Expand Down Expand Up @@ -390,6 +397,12 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDevice {
// the callback will be populated with |kUnknownPower|.
virtual void GetConnectionInfo(const ConnectionInfoCallback& callback) = 0;

// Sets the connection latency for the device. This API is only valid for LE
// devices.
virtual void SetConnectionLatency(ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;

// Initiates a connection to the device, pairing first if necessary.
//
// Method calls will be made on the supplied object |pairing_delegate|
Expand Down
7 changes: 7 additions & 0 deletions device/bluetooth/bluetooth_device_android.cc
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,13 @@ void BluetoothDeviceAndroid::GetConnectionInfo(
callback.Run(ConnectionInfo());
}

void BluetoothDeviceAndroid::SetConnectionLatency(
ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) {
NOTIMPLEMENTED();
}

void BluetoothDeviceAndroid::Connect(
PairingDelegate* pairing_delegate,
const base::Closure& callback,
Expand Down
3 changes: 3 additions & 0 deletions device/bluetooth/bluetooth_device_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceAndroid final
bool ExpectingPasskey() const override;
bool ExpectingConfirmation() const override;
void GetConnectionInfo(const ConnectionInfoCallback& callback) override;
void SetConnectionLatency(ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
void Connect(device::BluetoothDevice::PairingDelegate* pairing_delegate,
const base::Closure& callback,
const ConnectErrorCallback& error_callback) override;
Expand Down
7 changes: 7 additions & 0 deletions device/bluetooth/bluetooth_device_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,13 @@ void BluetoothDeviceWin::GetConnectionInfo(
callback.Run(ConnectionInfo());
}

void BluetoothDeviceWin::SetConnectionLatency(
ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) {
NOTIMPLEMENTED();
}

void BluetoothDeviceWin::Connect(
PairingDelegate* pairing_delegate,
const base::Closure& callback,
Expand Down
3 changes: 3 additions & 0 deletions device/bluetooth/bluetooth_device_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWin : public BluetoothDevice {
bool ExpectingPasskey() const override;
bool ExpectingConfirmation() const override;
void GetConnectionInfo(const ConnectionInfoCallback& callback) override;
void SetConnectionLatency(ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
void Connect(PairingDelegate* pairing_delegate,
const base::Closure& callback,
const ConnectErrorCallback& error_callback) override;
Expand Down
3 changes: 3 additions & 0 deletions device/bluetooth/bluetooth_low_energy_device_mac.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothLowEnergyDeviceMac
bool ExpectingPasskey() const override;
bool ExpectingConfirmation() const override;
void GetConnectionInfo(const ConnectionInfoCallback& callback) override;
void SetConnectionLatency(ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
void Connect(PairingDelegate* pairing_delegate,
const base::Closure& callback,
const ConnectErrorCallback& error_callback) override;
Expand Down
7 changes: 7 additions & 0 deletions device/bluetooth/bluetooth_low_energy_device_mac.mm
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,13 @@
NOTIMPLEMENTED();
}

void BluetoothLowEnergyDeviceMac::SetConnectionLatency(
ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) {
NOTIMPLEMENTED();
}

void BluetoothLowEnergyDeviceMac::Connect(
PairingDelegate* pairing_delegate,
const base::Closure& callback,
Expand Down
64 changes: 64 additions & 0 deletions device/bluetooth/bluez/bluetooth_device_bluez.cc
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ using device::BluetoothUUID;

namespace {

// The unit for connection interval values are in multiples of 1.25ms.
const uint16_t MIN_CONNECTION_INTERVAL_LOW = 6;
const uint16_t MAX_CONNECTION_INTERVAL_LOW = 6;
const uint16_t MIN_CONNECTION_INTERVAL_MEDIUM = 40;
const uint16_t MAX_CONNECTION_INTERVAL_MEDIUM = 56;
const uint16_t MIN_CONNECTION_INTERVAL_HIGH = 80;
const uint16_t MAX_CONNECTION_INTERVAL_HIGH = 100;

// Histogram enumerations for pairing results.
enum UMAPairingResult {
UMA_PAIRING_RESULT_SUCCESS,
Expand Down Expand Up @@ -443,6 +451,47 @@ void BluetoothDeviceBlueZ::GetConnectionInfo(
weak_ptr_factory_.GetWeakPtr(), callback));
}

void BluetoothDeviceBlueZ::SetConnectionLatency(
ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) {
uint16_t min_connection_interval = MIN_CONNECTION_INTERVAL_MEDIUM;
uint16_t max_connection_interval = MAX_CONNECTION_INTERVAL_MEDIUM;
switch (connection_latency) {
case ConnectionLatency::CONNECTION_LATENCY_LOW:
min_connection_interval = MIN_CONNECTION_INTERVAL_LOW;
max_connection_interval = MAX_CONNECTION_INTERVAL_LOW;
break;
case ConnectionLatency::CONNECTION_LATENCY_MEDIUM:
min_connection_interval = MIN_CONNECTION_INTERVAL_MEDIUM;
max_connection_interval = MAX_CONNECTION_INTERVAL_MEDIUM;
break;
case ConnectionLatency::CONNECTION_LATENCY_HIGH:
min_connection_interval = MIN_CONNECTION_INTERVAL_HIGH;
max_connection_interval = MAX_CONNECTION_INTERVAL_HIGH;
break;
default:
NOTREACHED();
break;
}

BLUETOOTH_LOG(EVENT) << "Setting LE connection parameters: min="
<< min_connection_interval
<< ", max=" << max_connection_interval;
bluez::BluetoothDeviceClient::ConnectionParameters connection_parameters;
connection_parameters.min_connection_interval = min_connection_interval;
connection_parameters.max_connection_interval = max_connection_interval;

bluez::BluetoothDeviceClient* client =
bluez::BluezDBusManager::Get()->GetBluetoothDeviceClient();
client->SetLEConnectionParameters(
object_path_, connection_parameters,
base::Bind(&BluetoothDeviceBlueZ::OnSetLEConnectionParameters,
weak_ptr_factory_.GetWeakPtr(), callback),
base::Bind(&BluetoothDeviceBlueZ::OnSetLEConnectionParametersError,
weak_ptr_factory_.GetWeakPtr(), error_callback));
}

void BluetoothDeviceBlueZ::Connect(
BluetoothDevice::PairingDelegate* pairing_delegate,
const base::Closure& callback,
Expand Down Expand Up @@ -784,6 +833,21 @@ void BluetoothDeviceBlueZ::OnGetConnInfoError(
callback.Run(ConnectionInfo());
}

void BluetoothDeviceBlueZ::OnSetLEConnectionParameters(
const base::Closure& callback) {
callback.Run();
}

void BluetoothDeviceBlueZ::OnSetLEConnectionParametersError(
const ErrorCallback& callback,
const std::string& error_name,
const std::string& error_message) {
BLUETOOTH_LOG(ERROR) << object_path_.value()
<< ": Failed to set connection parameters: "
<< error_name << ": " << error_message;
callback.Run();
}

void BluetoothDeviceBlueZ::OnGetServiceRecordsError(
const GetServiceRecordsErrorCallback& error_callback,
const std::string& error_name,
Expand Down
10 changes: 10 additions & 0 deletions device/bluetooth/bluez/bluetooth_device_bluez.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceBlueZ
bool ExpectingPasskey() const override;
bool ExpectingConfirmation() const override;
void GetConnectionInfo(const ConnectionInfoCallback& callback) override;
void SetConnectionLatency(ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
void Connect(device::BluetoothDevice::PairingDelegate* pairing_delegate,
const base::Closure& callback,
const ConnectErrorCallback& error_callback) override;
Expand Down Expand Up @@ -187,6 +190,13 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceBlueZ
const std::string& error_name,
const std::string& error_message);

// Called by dbus:: on completion of the D-Bus method call to set the
// connection parameters of the device.
void OnSetLEConnectionParameters(const base::Closure& callback);
void OnSetLEConnectionParametersError(const ErrorCallback& callback,
const std::string& error_name,
const std::string& error_message);

// Called by dbus:: in case of an error during the GetServiceRecords API call.
void OnGetServiceRecordsError(
const GetServiceRecordsErrorCallback& error_callback,
Expand Down
47 changes: 47 additions & 0 deletions device/bluetooth/dbus/bluetooth_device_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,53 @@ class BluetoothDeviceClientImpl : public BluetoothDeviceClient,
weak_ptr_factory_.GetWeakPtr(), error_callback));
}

void SetLEConnectionParameters(const dbus::ObjectPath& object_path,
const ConnectionParameters& conn_params,
const base::Closure& callback,
const ErrorCallback& error_callback) override {
dbus::ObjectProxy* object_proxy =
object_manager_->GetObjectProxy(object_path);
if (!object_proxy) {
error_callback.Run(kUnknownDeviceError, "");
return;
}

// TODO(crbug.com/725367): Use constants in cros_system_api once it is
// rolled.
dbus::MethodCall method_call(
bluetooth_plugin_device::kBluetoothPluginInterface,
"SetLEConnectionParameters");

dbus::MessageWriter writer(&method_call);
dbus::MessageWriter dict_writer(nullptr);
writer.OpenArray("{sq}", &dict_writer);

{
dbus::MessageWriter dict_entry_writer(nullptr);
dict_writer.OpenDictEntry(&dict_entry_writer);
dict_entry_writer.AppendString("MinimumConnectionInterval");
dict_entry_writer.AppendUint16(conn_params.min_connection_interval);
dict_writer.CloseContainer(&dict_entry_writer);
}

{
dbus::MessageWriter dict_entry_writer(nullptr);
dict_writer.OpenDictEntry(&dict_entry_writer);
dict_entry_writer.AppendString("MaximumConnectionInterval");
dict_entry_writer.AppendUint16(conn_params.max_connection_interval);
dict_writer.CloseContainer(&dict_entry_writer);
}

writer.CloseContainer(&dict_writer);

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));
}

void GetServiceRecords(const dbus::ObjectPath& object_path,
const ServiceRecordsCallback& callback,
const ErrorCallback& error_callback) override {
Expand Down
18 changes: 18 additions & 0 deletions device/bluetooth/dbus/bluetooth_device_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,17 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceClient : public BluezDBusClient {
~Properties() override;
};

// Connection parameters that can be passed to SetLEConnectionParameters().
struct ConnectionParameters {
// The lower bound to request for the connection interval.
// In units of 1.25ms.
uint16_t min_connection_interval;

// The upper bound to request for the connection interval.
// In units of 1.25ms.
uint16_t max_connection_interval;
};

// Interface for observing changes from a remote bluetooth device.
class Observer {
public:
Expand Down Expand Up @@ -216,6 +227,13 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceClient : public BluezDBusClient {
const ConnInfoCallback& callback,
const ErrorCallback& error_callback) = 0;

// Sets the connection parameters (e.g. connection interval) for the device.
virtual void SetLEConnectionParameters(
const dbus::ObjectPath& object_path,
const ConnectionParameters& conn_params,
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;

// Returns the currently discovered service records for the device with
// object path |object_path|. If the device is not connected, then an error
// will be returned.
Expand Down
14 changes: 14 additions & 0 deletions device/bluetooth/dbus/fake_bluetooth_device_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -595,6 +595,20 @@ void FakeBluetoothDeviceClient::GetConnInfo(
callback.Run(connection_rssi_, transmit_power_, max_transmit_power_);
}

void FakeBluetoothDeviceClient::SetLEConnectionParameters(
const dbus::ObjectPath& object_path,
const ConnectionParameters& conn_params,
const base::Closure& callback,
const ErrorCallback& error_callback) {
Properties* properties = GetProperties(object_path);
if (!properties->connected.value()) {
error_callback.Run(bluetooth_device::kErrorNotConnected, "Not Connected");
return;
}

callback.Run();
}

void FakeBluetoothDeviceClient::GetServiceRecords(
const dbus::ObjectPath& object_path,
const ServiceRecordsCallback& callback,
Expand Down
4 changes: 4 additions & 0 deletions device/bluetooth/dbus/fake_bluetooth_device_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ class DEVICE_BLUETOOTH_EXPORT FakeBluetoothDeviceClient
void GetConnInfo(const dbus::ObjectPath& object_path,
const ConnInfoCallback& callback,
const ErrorCallback& error_callback) override;
void SetLEConnectionParameters(const dbus::ObjectPath& object_path,
const ConnectionParameters& conn_params,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
void GetServiceRecords(const dbus::ObjectPath& object_path,
const ServiceRecordsCallback& callback,
const ErrorCallback& error_callback) override;
Expand Down
6 changes: 6 additions & 0 deletions device/bluetooth/test/fake_peripheral.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,12 @@ void FakePeripheral::GetConnectionInfo(const ConnectionInfoCallback& callback) {
NOTREACHED();
}

void FakePeripheral::SetConnectionLatency(ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) {
NOTREACHED();
}

void FakePeripheral::Connect(PairingDelegate* pairing_delegate,
const base::Closure& callback,
const ConnectErrorCallback& error_callback) {
Expand Down
3 changes: 3 additions & 0 deletions device/bluetooth/test/fake_peripheral.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ class FakePeripheral : public device::BluetoothDevice {
bool ExpectingPasskey() const override;
bool ExpectingConfirmation() const override;
void GetConnectionInfo(const ConnectionInfoCallback& callback) override;
void SetConnectionLatency(ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback) override;
void Connect(PairingDelegate* pairing_delegate,
const base::Closure& callback,
const ConnectErrorCallback& error_callback) override;
Expand Down
4 changes: 4 additions & 0 deletions device/bluetooth/test/mock_bluetooth_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ class MockBluetoothDevice : public BluetoothDevice {
MOCK_CONST_METHOD0(ExpectingPasskey, bool());
MOCK_CONST_METHOD0(ExpectingConfirmation, bool());
MOCK_METHOD1(GetConnectionInfo, void(const ConnectionInfoCallback& callback));
MOCK_METHOD3(SetConnectionLatency,
void(ConnectionLatency connection_latency,
const base::Closure& callback,
const ErrorCallback& error_callback));
MOCK_METHOD3(Connect,
void(BluetoothDevice::PairingDelegate* pairing_delegate,
const base::Closure& callback,
Expand Down

0 comments on commit c967751

Please sign in to comment.