From 7bff37cc70e0e4fe323e0ec1917fa71b1f37674e Mon Sep 17 00:00:00 2001 From: ortuno Date: Mon, 2 Nov 2015 01:37:13 -0800 Subject: bluetooth: Wire up GattServices property from device And add GattServicesDiscovered to BluetoothAdapter::Observer. GattServicesDiscovered gets called when all GATT Services of a devices have been discovered. BUG=484504 Review URL: https://codereview.chromium.org/1413903009 Cr-Commit-Position: refs/heads/master@{#357325} --- chromeos/dbus/bluetooth_device_client.cc | 1 + chromeos/dbus/bluetooth_device_client.h | 6 +++++ chromeos/dbus/fake_bluetooth_device_client.cc | 1 + device/bluetooth/bluetooth_adapter.h | 5 ++++ device/bluetooth/bluetooth_adapter_chromeos.cc | 12 +++++++++ device/bluetooth/bluetooth_adapter_chromeos.h | 1 + .../bluetooth/bluetooth_gatt_chromeos_unittest.cc | 31 ++++++++++++++++++++++ .../test/test_bluetooth_adapter_observer.cc | 13 +++++++++ .../test/test_bluetooth_adapter_observer.h | 6 +++++ 9 files changed, 76 insertions(+) diff --git a/chromeos/dbus/bluetooth_device_client.cc b/chromeos/dbus/bluetooth_device_client.cc index 7b1d590..8fcf74b 100644 --- a/chromeos/dbus/bluetooth_device_client.cc +++ b/chromeos/dbus/bluetooth_device_client.cc @@ -48,6 +48,7 @@ BluetoothDeviceClient::Properties::Properties( RegisterProperty(bluetooth_device::kModaliasProperty, &modalias); RegisterProperty(bluetooth_device::kRSSIProperty, &rssi); RegisterProperty(bluetooth_device::kTxPowerProperty, &tx_power); + RegisterProperty(bluetooth_device::kGattServicesProperty, &gatt_services); } BluetoothDeviceClient::Properties::~Properties() {} diff --git a/chromeos/dbus/bluetooth_device_client.h b/chromeos/dbus/bluetooth_device_client.h index 6768b3e..e9c2905 100644 --- a/chromeos/dbus/bluetooth_device_client.h +++ b/chromeos/dbus/bluetooth_device_client.h @@ -84,6 +84,12 @@ class CHROMEOS_EXPORT BluetoothDeviceClient : public DBusClient { // discovered during inquiry. Read-only. dbus::Property rssi; + // List of GATT service object paths. Each referenced object exports the + // org.bluez.GattService1 interface and represents a remote GATT service. + // This property will be updated once all remote GATT services of this + // device have been discovered and exported over D-Bus. Read-only. + dbus::Property> gatt_services; + Properties(dbus::ObjectProxy* object_proxy, const std::string& interface_name, const PropertyChangedCallback& callback); diff --git a/chromeos/dbus/fake_bluetooth_device_client.cc b/chromeos/dbus/fake_bluetooth_device_client.cc index b910b37..1aa01a5 100644 --- a/chromeos/dbus/fake_bluetooth_device_client.cc +++ b/chromeos/dbus/fake_bluetooth_device_client.cc @@ -390,6 +390,7 @@ void FakeBluetoothDeviceClient::Connect(const dbus::ObjectPath& object_path, DBusThreadManager::Get()->GetBluetoothGattServiceClient()); gatt_service_client->ExposeHeartRateService( dbus::ObjectPath(kLowEnergyPath)); + properties->gatt_services.ReplaceValue(gatt_service_client->GetServices()); } AddInputDeviceIfNeeded(object_path, properties); diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h index 0dc2b8f..63969fc 100644 --- a/device/bluetooth/bluetooth_adapter.h +++ b/device/bluetooth/bluetooth_adapter.h @@ -109,6 +109,11 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter BluetoothDevice* device, BluetoothGattService* service) {} + // Called when all the GATT Services in |device| have been discovered + // and GattServiceAdded has been called for each service. + virtual void GattServicesDiscovered(BluetoothAdapter* adapter, + BluetoothDevice* device) {} + // Called when all characteristic and descriptor discovery procedures are // known to be completed for the GATT service |service|. This method will be // called after the initial discovery of a GATT service and will usually be diff --git a/device/bluetooth/bluetooth_adapter_chromeos.cc b/device/bluetooth/bluetooth_adapter_chromeos.cc index 851815f..70ec7fb 100644 --- a/device/bluetooth/bluetooth_adapter_chromeos.cc +++ b/device/bluetooth/bluetooth_adapter_chromeos.cc @@ -474,6 +474,10 @@ void BluetoothAdapterChromeOS::DevicePropertyChanged( NotifyDeviceChanged(device_chromeos); } + if (property_name == properties->gatt_services.name()) { + NotifyGattServicesDiscovered(device_chromeos); + } + // When a device becomes paired, mark it as trusted so that the user does // not need to approve every incoming connection if (property_name == properties->paired.name() && @@ -932,6 +936,14 @@ void BluetoothAdapterChromeOS::NotifyGattServiceChanged( GattServiceChanged(this, service)); } +void BluetoothAdapterChromeOS::NotifyGattServicesDiscovered( + BluetoothDeviceChromeOS* device) { + DCHECK(device->adapter_ == this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattServicesDiscovered(this, device)); +} + void BluetoothAdapterChromeOS::NotifyGattDiscoveryComplete( BluetoothRemoteGattServiceChromeOS* service) { DCHECK_EQ(service->GetAdapter(), this); diff --git a/device/bluetooth/bluetooth_adapter_chromeos.h b/device/bluetooth/bluetooth_adapter_chromeos.h index 7570780..46c634f 100644 --- a/device/bluetooth/bluetooth_adapter_chromeos.h +++ b/device/bluetooth/bluetooth_adapter_chromeos.h @@ -128,6 +128,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterChromeOS void NotifyGattServiceAdded(BluetoothRemoteGattServiceChromeOS* service); void NotifyGattServiceRemoved(BluetoothRemoteGattServiceChromeOS* service); void NotifyGattServiceChanged(BluetoothRemoteGattServiceChromeOS* service); + void NotifyGattServicesDiscovered(BluetoothDeviceChromeOS* device); void NotifyGattDiscoveryComplete(BluetoothRemoteGattServiceChromeOS* service); void NotifyGattCharacteristicAdded( BluetoothRemoteGattCharacteristicChromeOS* characteristic); diff --git a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc index d93dcc2..5cf067c 100644 --- a/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc +++ b/device/bluetooth/bluetooth_gatt_chromeos_unittest.cc @@ -352,6 +352,37 @@ TEST_F(BluetoothGattChromeOSTest, GattServiceAddedAndRemoved) { adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress)); } +TEST_F(BluetoothGattChromeOSTest, ServicesDiscovered) { + // Create a fake LE device. We store the device pointer here because this is a + // test. It's unsafe to do this in production as the device might get deleted. + fake_bluetooth_device_client_->CreateDevice( + dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), + dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + BluetoothDevice* device = + adapter_->GetDevice(FakeBluetoothDeviceClient::kLowEnergyAddress); + FakeBluetoothDeviceClient::Properties* properties = + fake_bluetooth_device_client_->GetProperties( + dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + + ASSERT_TRUE(device); + + TestBluetoothAdapterObserver observer(adapter_); + + EXPECT_EQ(0, observer.gatt_services_discovered_count()); + + // Expose the fake Heart Rate Service. + fake_bluetooth_gatt_service_client_->ExposeHeartRateService( + dbus::ObjectPath(FakeBluetoothDeviceClient::kLowEnergyPath)); + // Notify that all services have been discovered. + properties->gatt_services.ReplaceValue( + fake_bluetooth_gatt_service_client_->GetServices()); + + EXPECT_EQ(1, observer.gatt_services_discovered_count()); + EXPECT_EQ(device, observer.last_device()); + EXPECT_EQ(FakeBluetoothDeviceClient::kLowEnergyAddress, + observer.last_device_address()); +} + TEST_F(BluetoothGattChromeOSTest, GattCharacteristicAddedAndRemoved) { fake_bluetooth_device_client_->CreateDevice( dbus::ObjectPath(FakeBluetoothAdapterClient::kAdapterPath), diff --git a/device/bluetooth/test/test_bluetooth_adapter_observer.cc b/device/bluetooth/test/test_bluetooth_adapter_observer.cc index 811ffb6..5d20565 100644 --- a/device/bluetooth/test/test_bluetooth_adapter_observer.cc +++ b/device/bluetooth/test/test_bluetooth_adapter_observer.cc @@ -39,6 +39,7 @@ void TestBluetoothAdapterObserver::Reset() { last_device_address_.clear(); gatt_service_added_count_ = 0; gatt_service_removed_count_ = 0; + gatt_services_discovered_count_ = 0; gatt_service_changed_count_ = 0; gatt_discovery_complete_count_ = 0; gatt_characteristic_added_count_ = 0; @@ -175,6 +176,18 @@ void TestBluetoothAdapterObserver::GattServiceRemoved( QuitMessageLoop(); } +void TestBluetoothAdapterObserver::GattServicesDiscovered( + BluetoothAdapter* adapter, + BluetoothDevice* device) { + ASSERT_EQ(adapter_.get(), adapter); + + ++gatt_services_discovered_count_; + last_device_ = device; + last_device_address_ = device->GetAddress(); + + QuitMessageLoop(); +} + void TestBluetoothAdapterObserver::GattDiscoveryCompleteForService( BluetoothAdapter* adapter, BluetoothGattService* service) { diff --git a/device/bluetooth/test/test_bluetooth_adapter_observer.h b/device/bluetooth/test/test_bluetooth_adapter_observer.h index 7ec06889..60b3088 100644 --- a/device/bluetooth/test/test_bluetooth_adapter_observer.h +++ b/device/bluetooth/test/test_bluetooth_adapter_observer.h @@ -40,6 +40,8 @@ class TestBluetoothAdapterObserver : public BluetoothAdapter::Observer { void GattServiceRemoved(BluetoothAdapter* adapter, BluetoothDevice* device, BluetoothGattService* service) override; + void GattServicesDiscovered(BluetoothAdapter* adapter, + BluetoothDevice* device) override; void GattDiscoveryCompleteForService(BluetoothAdapter* adapter, BluetoothGattService* service) override; void GattServiceChanged(BluetoothAdapter* adapter, @@ -82,6 +84,9 @@ class TestBluetoothAdapterObserver : public BluetoothAdapter::Observer { // GATT related: int gatt_service_added_count() { return gatt_service_added_count_; } int gatt_service_removed_count() { return gatt_service_removed_count_; } + int gatt_services_discovered_count() { + return gatt_services_discovered_count_; + } int gatt_service_changed_count() { return gatt_service_changed_count_; } int gatt_discovery_complete_count() { return gatt_discovery_complete_count_; } int gatt_characteristic_added_count() { @@ -144,6 +149,7 @@ class TestBluetoothAdapterObserver : public BluetoothAdapter::Observer { // GATT related: int gatt_service_added_count_; int gatt_service_removed_count_; + int gatt_services_discovered_count_; int gatt_service_changed_count_; int gatt_discovery_complete_count_; int gatt_characteristic_added_count_; -- cgit v1.1