Skip to content

Commit

Permalink
Hook up RSSI and host transmit power Bluetooth device properties for …
Browse files Browse the repository at this point in the history
…ChromeOS.

BUG=365966

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269676 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
tengs@chromium.org committed May 11, 2014
1 parent 2ad5ef5 commit 73e3bf3
Show file tree
Hide file tree
Showing 15 changed files with 247 additions and 18 deletions.
28 changes: 26 additions & 2 deletions chrome/browser/extensions/api/bluetooth/bluetooth_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include <string>

#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "chrome/browser/extensions/api/bluetooth/bluetooth_api_utils.h"
Expand Down Expand Up @@ -457,13 +458,36 @@ bool BluetoothConnectFunction::DoWork(scoped_refptr<BluetoothAdapter> adapter) {

device->ConnectToProfile(
bluetooth_profile,
base::Bind(&BluetoothConnectFunction::OnSuccessCallback, this),
base::Bind(&BluetoothConnectFunction::OnConnectedCallback,
this,
adapter,
device->GetAddress()),
base::Bind(&BluetoothConnectFunction::OnErrorCallback, this));

return true;
}

void BluetoothConnectFunction::OnSuccessCallback() {
void BluetoothConnectFunction::OnConnectedCallback(
scoped_refptr<device::BluetoothAdapter> adapter,
const std::string& device_address) {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

// TODO(tengs): Remove this once we have an API for starting the connection
// monitor.
BluetoothDevice* device = adapter->GetDevice(device_address);
if (!device) {
SetError(kInvalidDevice);
SendResponse(false);
return;
}
// Start the connection monitor, and return success even if this fails,
// as the connection was still opened successfully.
device->StartConnectionMonitor(
base::Bind(&BluetoothConnectFunction::OnMonitorStartedCallback, this),
base::Bind(&BluetoothConnectFunction::OnMonitorStartedCallback, this));
}

void BluetoothConnectFunction::OnMonitorStartedCallback() {
DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
SendResponse(true);
}
Expand Down
4 changes: 3 additions & 1 deletion chrome/browser/extensions/api/bluetooth/bluetooth_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@ class BluetoothConnectFunction : public BluetoothExtensionFunction {
virtual bool DoWork(scoped_refptr<device::BluetoothAdapter> adapter) OVERRIDE;

private:
void OnSuccessCallback();
void OnConnectedCallback(scoped_refptr<device::BluetoothAdapter> adapter,
const std::string& device_address);
void OnMonitorStartedCallback();
void OnErrorCallback(const std::string& error);
};

Expand Down
54 changes: 54 additions & 0 deletions chromeos/dbus/bluetooth_device_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ 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 @@ -267,6 +271,56 @@ class BluetoothDeviceClientImpl
weak_ptr_factory_.GetWeakPtr(), error_callback));
}

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

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

protected:
virtual void Init(dbus::Bus* bus) OVERRIDE {
object_manager_ = bus->GetObjectManager(
Expand Down
30 changes: 29 additions & 1 deletion chromeos/dbus/bluetooth_device_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,24 @@ class CHROMEOS_EXPORT BluetoothDeviceClient : public DBusClient {
// Remote Device ID information in Linux kernel modalias format. Read-only.
dbus::Property<std::string> modalias;

// Received signal strength indicator. Read-only.
// Received signal strength indicator that is set when the device is
// 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 @@ -169,6 +184,19 @@ 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;

// Creates the instance.
static BluetoothDeviceClient* Create();

Expand Down
27 changes: 22 additions & 5 deletions chromeos/dbus/fake_bluetooth_device_client.cc
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ FakeBluetoothDeviceClient::FakeBluetoothDeviceClient()
: simulation_interval_ms_(kSimulationIntervalMs),
discovery_simulation_step_(0),
incoming_pairing_simulation_step_(0),
pairing_cancelled_(false) {
pairing_cancelled_(false),
connection_monitor_started_(false) {
Properties* properties = new Properties(base::Bind(
&FakeBluetoothDeviceClient::OnPropertyChanged,
base::Unretained(this),
Expand Down Expand Up @@ -459,6 +460,22 @@ void FakeBluetoothDeviceClient::CancelPairing(
callback.Run();
}

void FakeBluetoothDeviceClient::StartConnectionMonitor(
const dbus::ObjectPath& object_path,
const base::Closure& callback,
const ErrorCallback& error_callback) {
VLOG(1) << "StartConnectionMonitor: " << object_path.value();
connection_monitor_started_ = true;
callback.Run();
}

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

void FakeBluetoothDeviceClient::BeginDiscoverySimulation(
const dbus::ObjectPath& adapter_path) {
Expand Down Expand Up @@ -677,12 +694,12 @@ void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
dbus::ObjectPath(kLowEnergyPath));

} else if (discovery_simulation_step_ == 4) {
UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
base::RandInt(kMinRSSI, kMaxRSSI));
CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
dbus::ObjectPath(kDisplayPinCodePath));
CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
dbus::ObjectPath(kVanishingDevicePath));
UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
base::RandInt(kMinRSSI, kMaxRSSI));

} else if (discovery_simulation_step_ == 7) {
CreateDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
Expand Down Expand Up @@ -713,10 +730,10 @@ void FakeBluetoothDeviceClient::DiscoverySimulationTimer() {
base::RandInt(kMinRSSI, kMaxRSSI));

} else if (discovery_simulation_step_ == 13) {
RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
dbus::ObjectPath(kVanishingDevicePath));
UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
base::RandInt(kMinRSSI, kMaxRSSI));
RemoveDevice(dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath),
dbus::ObjectPath(kVanishingDevicePath));

} else if (discovery_simulation_step_ == 14) {
UpdateDeviceRSSI(dbus::ObjectPath(kLowEnergyPath),
Expand Down
13 changes: 11 additions & 2 deletions chromeos/dbus/fake_bluetooth_device_client.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ 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 SetSimulationIntervalMs(int interval_ms);

Expand Down Expand Up @@ -192,8 +200,8 @@ class CHROMEOS_EXPORT FakeBluetoothDeviceClient
const dbus::ObjectPath& object_path,
Properties* properties);

// Updates the RSSI property of fake device with object path |object_path|
// to |rssi|, if the fake device exists.
// Updates the inquiry RSSI property of fake device with object path
// |object_path| to |rssi|, if the fake device exists.
void UpdateDeviceRSSI(const dbus::ObjectPath& object_path, int16 rssi);

void PinCodeCallback(
Expand Down Expand Up @@ -242,6 +250,7 @@ class CHROMEOS_EXPORT FakeBluetoothDeviceClient
uint32_t discovery_simulation_step_;
uint32_t incoming_pairing_simulation_step_;
bool pairing_cancelled_;
bool connection_monitor_started_;
};

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

// When a device becomes paired, mark it as trusted so that the user does
Expand Down
6 changes: 6 additions & 0 deletions device/bluetooth/bluetooth_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,12 @@ class BluetoothDevice {
const base::Closure& callback,
const ErrorCallback& error_callback) = 0;

// Starts monitoring the connection properties, RSSI and TX power. These
// properties will be tracked, and updated when their values change. Exactly
// one of |callback| or |error_callback| will be run.
virtual void StartConnectionMonitor(const base::Closure& callback,
const ErrorCallback& error_callback) = 0;

// Returns the list of discovered GATT services.
virtual std::vector<BluetoothGattService*> GetGattServices() const;

Expand Down
63 changes: 57 additions & 6 deletions device/bluetooth/bluetooth_device_chromeos.cc
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ BluetoothDeviceChromeOS::BluetoothDeviceChromeOS(
: adapter_(adapter),
object_path_(object_path),
num_connecting_calls_(0),
connection_monitor_started_(false),
ui_task_runner_(ui_task_runner),
socket_thread_(socket_thread),
weak_ptr_factory_(this) {
Expand Down Expand Up @@ -223,18 +224,39 @@ uint16 BluetoothDeviceChromeOS::GetDeviceID() const {
}

int BluetoothDeviceChromeOS::GetRSSI() const {
NOTIMPLEMENTED();
return kUnknownPower;
BluetoothDeviceClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
object_path_);
DCHECK(properties);

if (!IsConnected()) {
NOTIMPLEMENTED();
return kUnknownPower;
}

return connection_monitor_started_ ? properties->connection_rssi.value()
: kUnknownPower;
}

int BluetoothDeviceChromeOS::GetCurrentHostTransmitPower() const {
NOTIMPLEMENTED();
return kUnknownPower;
BluetoothDeviceClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
object_path_);
DCHECK(properties);

return IsConnected() && connection_monitor_started_
? properties->connection_tx_power.value()
: kUnknownPower;
}

int BluetoothDeviceChromeOS::GetMaximumHostTransmitPower() const {
NOTIMPLEMENTED();
return kUnknownPower;
BluetoothDeviceClient::Properties* properties =
DBusThreadManager::Get()->GetBluetoothDeviceClient()->GetProperties(
object_path_);
DCHECK(properties);

return IsConnected() ? properties->connection_tx_power_max.value()
: kUnknownPower;
}

bool BluetoothDeviceChromeOS::IsPaired() const {
Expand Down Expand Up @@ -459,6 +481,19 @@ void BluetoothDeviceChromeOS::ClearOutOfBandPairingData(
error_callback.Run();
}

void BluetoothDeviceChromeOS::StartConnectionMonitor(
const base::Closure& callback,
const ErrorCallback& error_callback) {
DBusThreadManager::Get()->GetBluetoothDeviceClient()->StartConnectionMonitor(
object_path_,
base::Bind(&BluetoothDeviceChromeOS::OnStartConnectionMonitor,
weak_ptr_factory_.GetWeakPtr(),
callback),
base::Bind(&BluetoothDeviceChromeOS::OnStartConnectionMonitorError,
weak_ptr_factory_.GetWeakPtr(),
error_callback));
}

BluetoothPairingChromeOS* BluetoothDeviceChromeOS::BeginPairing(
BluetoothDevice::PairingDelegate* pairing_delegate) {
pairing_.reset(new BluetoothPairingChromeOS(this, pairing_delegate));
Expand Down Expand Up @@ -655,6 +690,22 @@ void BluetoothDeviceChromeOS::OnSetTrusted(bool success) {
<< ": Failed to set device as trusted";
}

void BluetoothDeviceChromeOS::OnStartConnectionMonitor(
const base::Closure& callback) {
connection_monitor_started_ = true;
callback.Run();
}

void BluetoothDeviceChromeOS::OnStartConnectionMonitorError(
const ErrorCallback& error_callback,
const std::string& error_name,
const std::string& error_message) {
LOG(WARNING) << object_path_.value()
<< ": Failed to start connection monitor: " << error_name << ": "
<< error_message;
error_callback.Run();
}

void BluetoothDeviceChromeOS::OnDisconnect(const base::Closure& callback) {
VLOG(1) << object_path_.value() << ": Disconnected";
callback.Run();
Expand Down
Loading

0 comments on commit 73e3bf3

Please sign in to comment.