diff options
author | gogerald <gogerald@chromium.org> | 2016-02-10 14:25:56 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-10 22:27:21 +0000 |
commit | 43eba589ad78fbae63cef04ad67e8468e60b1165 (patch) | |
tree | 3844721ced912d73f01d66b9406a2f0a3b411d90 /device | |
parent | e9da717d1cd3fd4b41b04456b9e454c5c028cac3 (diff) | |
download | chromium_src-43eba589ad78fbae63cef04ad67e8468e60b1165.zip chromium_src-43eba589ad78fbae63cef04ad67e8468e60b1165.tar.gz chromium_src-43eba589ad78fbae63cef04ad67e8468e60b1165.tar.bz2 |
Add BluetoothRemoteGattServiceWin to BluetoothDeviceWin
This CL adds BluetoothRemoteGattServiceWin to BluetoothDeviceWin. The upcoming CL will implement BluetoothRemoteGattServiceWin.
BUG=579202
Review URL: https://codereview.chromium.org/1681853003
Cr-Commit-Position: refs/heads/master@{#374751}
Diffstat (limited to 'device')
21 files changed, 469 insertions, 166 deletions
diff --git a/device/bluetooth/BUILD.gn b/device/bluetooth/BUILD.gn index 4175f54..0fb13c8 100644 --- a/device/bluetooth/BUILD.gn +++ b/device/bluetooth/BUILD.gn @@ -93,6 +93,8 @@ component("bluetooth") { "bluetooth_remote_gatt_descriptor_android.h", "bluetooth_remote_gatt_service_android.cc", "bluetooth_remote_gatt_service_android.h", + "bluetooth_remote_gatt_service_win.cc", + "bluetooth_remote_gatt_service_win.h", "bluetooth_rfcomm_channel_mac.h", "bluetooth_rfcomm_channel_mac.mm", "bluetooth_service_record_win.cc", diff --git a/device/bluetooth/bluetooth.gyp b/device/bluetooth/bluetooth.gyp index db58e76..8aaad96 100644 --- a/device/bluetooth/bluetooth.gyp +++ b/device/bluetooth/bluetooth.gyp @@ -95,6 +95,8 @@ 'bluetooth_remote_gatt_descriptor_android.h', 'bluetooth_remote_gatt_service_android.cc', 'bluetooth_remote_gatt_service_android.h', + 'bluetooth_remote_gatt_service_win.cc', + 'bluetooth_remote_gatt_service_win.h', 'bluetooth_rfcomm_channel_mac.mm', 'bluetooth_rfcomm_channel_mac.h', 'bluetooth_service_record_win.cc', diff --git a/device/bluetooth/bluetooth_adapter.cc b/device/bluetooth/bluetooth_adapter.cc index 2f90428..390bb93 100644 --- a/device/bluetooth/bluetooth_adapter.cc +++ b/device/bluetooth/bluetooth_adapter.cc @@ -13,6 +13,9 @@ #include "device/bluetooth/bluetooth_device.h" #include "device/bluetooth/bluetooth_discovery_session.h" #include "device/bluetooth/bluetooth_discovery_session_outcome.h" +#include "device/bluetooth/bluetooth_gatt_characteristic.h" +#include "device/bluetooth/bluetooth_gatt_descriptor.h" +#include "device/bluetooth/bluetooth_gatt_service.h" namespace device { @@ -155,6 +158,99 @@ BluetoothDevice::PairingDelegate* BluetoothAdapter::DefaultPairingDelegate() { return pairing_delegates_.front().first; } +void BluetoothAdapter::NotifyGattServiceAdded(BluetoothGattService* service) { + DCHECK_EQ(service->GetDevice()->GetAdapter(), this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattServiceAdded(this, service->GetDevice(), service)); +} + +void BluetoothAdapter::NotifyGattServiceRemoved(BluetoothGattService* service) { + DCHECK_EQ(service->GetDevice()->GetAdapter(), this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattServiceRemoved(this, service->GetDevice(), service)); +} + +void BluetoothAdapter::NotifyGattServiceChanged(BluetoothGattService* service) { + DCHECK_EQ(service->GetDevice()->GetAdapter(), this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattServiceChanged(this, service)); +} + +void BluetoothAdapter::NotifyGattServicesDiscovered(BluetoothDevice* device) { + DCHECK(device->GetAdapter() == this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattServicesDiscovered(this, device)); +} + +void BluetoothAdapter::NotifyGattDiscoveryComplete( + BluetoothGattService* service) { + DCHECK_EQ(service->GetDevice()->GetAdapter(), this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattDiscoveryCompleteForService(this, service)); +} + +void BluetoothAdapter::NotifyGattCharacteristicAdded( + BluetoothGattCharacteristic* characteristic) { + DCHECK_EQ(characteristic->GetService()->GetDevice()->GetAdapter(), this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattCharacteristicAdded(this, characteristic)); +} + +void BluetoothAdapter::NotifyGattCharacteristicRemoved( + BluetoothGattCharacteristic* characteristic) { + DCHECK_EQ(characteristic->GetService()->GetDevice()->GetAdapter(), this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattCharacteristicRemoved(this, characteristic)); +} + +void BluetoothAdapter::NotifyGattDescriptorAdded( + BluetoothGattDescriptor* descriptor) { + DCHECK_EQ( + descriptor->GetCharacteristic()->GetService()->GetDevice()->GetAdapter(), + this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattDescriptorAdded(this, descriptor)); +} + +void BluetoothAdapter::NotifyGattDescriptorRemoved( + BluetoothGattDescriptor* descriptor) { + DCHECK_EQ( + descriptor->GetCharacteristic()->GetService()->GetDevice()->GetAdapter(), + this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattDescriptorRemoved(this, descriptor)); +} + +void BluetoothAdapter::NotifyGattCharacteristicValueChanged( + BluetoothGattCharacteristic* characteristic, + const std::vector<uint8_t>& value) { + DCHECK_EQ(characteristic->GetService()->GetDevice()->GetAdapter(), this); + + FOR_EACH_OBSERVER( + BluetoothAdapter::Observer, observers_, + GattCharacteristicValueChanged(this, characteristic, value)); +} + +void BluetoothAdapter::NotifyGattDescriptorValueChanged( + BluetoothGattDescriptor* descriptor, + const std::vector<uint8_t>& value) { + DCHECK_EQ( + descriptor->GetCharacteristic()->GetService()->GetDevice()->GetAdapter(), + this); + + FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, + GattDescriptorValueChanged(this, descriptor, value)); +} + BluetoothAdapter::BluetoothAdapter() : weak_ptr_factory_(this) { } diff --git a/device/bluetooth/bluetooth_adapter.h b/device/bluetooth/bluetooth_adapter.h index e06b8bf..e099e32 100644 --- a/device/bluetooth/bluetooth_adapter.h +++ b/device/bluetooth/bluetooth_adapter.h @@ -398,6 +398,25 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapter const CreateAdvertisementCallback& callback, const CreateAdvertisementErrorCallback& error_callback) = 0; + // The following methods are used to send various GATT observer events to + // observers. + void NotifyGattServiceAdded(BluetoothGattService* service); + void NotifyGattServiceRemoved(BluetoothGattService* service); + void NotifyGattServiceChanged(BluetoothGattService* service); + void NotifyGattServicesDiscovered(BluetoothDevice* device); + void NotifyGattDiscoveryComplete(BluetoothGattService* service); + void NotifyGattCharacteristicAdded( + BluetoothGattCharacteristic* characteristic); + void NotifyGattCharacteristicRemoved( + BluetoothGattCharacteristic* characteristic); + void NotifyGattDescriptorAdded(BluetoothGattDescriptor* descriptor); + void NotifyGattDescriptorRemoved(BluetoothGattDescriptor* descriptor); + void NotifyGattCharacteristicValueChanged( + BluetoothGattCharacteristic* characteristic, + const std::vector<uint8_t>& value); + void NotifyGattDescriptorValueChanged(BluetoothGattDescriptor* descriptor, + const std::vector<uint8_t>& value); + protected: friend class base::RefCounted<BluetoothAdapter>; friend class BluetoothDiscoverySession; diff --git a/device/bluetooth/bluetooth_adapter_android.h b/device/bluetooth/bluetooth_adapter_android.h index 17ead5d..3612602 100644 --- a/device/bluetooth/bluetooth_adapter_android.h +++ b/device/bluetooth/bluetooth_adapter_android.h @@ -83,14 +83,6 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterAndroid final const CreateAdvertisementCallback& callback, const CreateAdvertisementErrorCallback& error_callback) override; - // Returns BluetoothAdapter Observers for use by Android platform - // implementation classes to send event notifications. Intentionally not - // exposed on the public base class BluetoothAdapter as it is an - // implementation detail. - base::ObserverList<device::BluetoothAdapter::Observer>& GetObservers() { - return observers_; - } - // Handles a scan error event by invalidating all discovery sessions. void OnScanFailed(JNIEnv* env, const base::android::JavaParamRef<jobject>& caller); diff --git a/device/bluetooth/bluetooth_adapter_bluez.cc b/device/bluetooth/bluetooth_adapter_bluez.cc index 89abe8e..141e2db 100644 --- a/device/bluetooth/bluetooth_adapter_bluez.cc +++ b/device/bluetooth/bluetooth_adapter_bluez.cc @@ -480,6 +480,7 @@ void BluetoothAdapterBlueZ::DevicePropertyChanged( } if (property_name == properties->gatt_services.name()) { + device_bluez->SetGattServicesDiscoveryComplete(true); NotifyGattServicesDiscovered(device_bluez); } @@ -911,120 +912,6 @@ void BluetoothAdapterBlueZ::NotifyDeviceAddressChanged( DeviceAddressChanged(this, device, old_address)); } -void BluetoothAdapterBlueZ::NotifyGattServiceAdded( - BluetoothRemoteGattServiceBlueZ* service) { - DCHECK_EQ(service->GetAdapter(), this); - DCHECK_EQ(static_cast<BluetoothDeviceBlueZ*>(service->GetDevice())->adapter_, - this); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - GattServiceAdded(this, service->GetDevice(), service)); -} - -void BluetoothAdapterBlueZ::NotifyGattServiceRemoved( - BluetoothRemoteGattServiceBlueZ* service) { - DCHECK_EQ(service->GetAdapter(), this); - DCHECK_EQ(static_cast<BluetoothDeviceBlueZ*>(service->GetDevice())->adapter_, - this); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - GattServiceRemoved(this, service->GetDevice(), service)); -} - -void BluetoothAdapterBlueZ::NotifyGattServiceChanged( - BluetoothRemoteGattServiceBlueZ* service) { - DCHECK_EQ(service->GetAdapter(), this); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - GattServiceChanged(this, service)); -} - -void BluetoothAdapterBlueZ::NotifyGattServicesDiscovered( - BluetoothDeviceBlueZ* device) { - DCHECK(device->adapter_ == this); - - device->SetGattServicesDiscoveryComplete(true); - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - GattServicesDiscovered(this, device)); -} - -void BluetoothAdapterBlueZ::NotifyGattDiscoveryComplete( - BluetoothRemoteGattServiceBlueZ* service) { - DCHECK_EQ(service->GetAdapter(), this); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - GattDiscoveryCompleteForService(this, service)); -} - -void BluetoothAdapterBlueZ::NotifyGattCharacteristicAdded( - BluetoothRemoteGattCharacteristicBlueZ* characteristic) { - DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>( - characteristic->GetService()) - ->GetAdapter(), - this); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - GattCharacteristicAdded(this, characteristic)); -} - -void BluetoothAdapterBlueZ::NotifyGattCharacteristicRemoved( - BluetoothRemoteGattCharacteristicBlueZ* characteristic) { - DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>( - characteristic->GetService()) - ->GetAdapter(), - this); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - GattCharacteristicRemoved(this, characteristic)); -} - -void BluetoothAdapterBlueZ::NotifyGattDescriptorAdded( - BluetoothRemoteGattDescriptorBlueZ* descriptor) { - DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>( - descriptor->GetCharacteristic()->GetService()) - ->GetAdapter(), - this); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - GattDescriptorAdded(this, descriptor)); -} - -void BluetoothAdapterBlueZ::NotifyGattDescriptorRemoved( - BluetoothRemoteGattDescriptorBlueZ* descriptor) { - DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>( - descriptor->GetCharacteristic()->GetService()) - ->GetAdapter(), - this); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - GattDescriptorRemoved(this, descriptor)); -} - -void BluetoothAdapterBlueZ::NotifyGattCharacteristicValueChanged( - BluetoothRemoteGattCharacteristicBlueZ* characteristic, - const std::vector<uint8_t>& value) { - DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>( - characteristic->GetService()) - ->GetAdapter(), - this); - - FOR_EACH_OBSERVER( - BluetoothAdapter::Observer, observers_, - GattCharacteristicValueChanged(this, characteristic, value)); -} - -void BluetoothAdapterBlueZ::NotifyGattDescriptorValueChanged( - BluetoothRemoteGattDescriptorBlueZ* descriptor, - const std::vector<uint8_t>& value) { - DCHECK_EQ(static_cast<BluetoothRemoteGattServiceBlueZ*>( - descriptor->GetCharacteristic()->GetService()) - ->GetAdapter(), - this); - - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, observers_, - GattDescriptorValueChanged(this, descriptor, value)); -} - void BluetoothAdapterBlueZ::UseProfile( const BluetoothUUID& uuid, const dbus::ObjectPath& device_path, diff --git a/device/bluetooth/bluetooth_adapter_bluez.h b/device/bluetooth/bluetooth_adapter_bluez.h index f766372..e2a07ff 100644 --- a/device/bluetooth/bluetooth_adapter_bluez.h +++ b/device/bluetooth/bluetooth_adapter_bluez.h @@ -125,28 +125,6 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothAdapterBlueZ void NotifyDeviceAddressChanged(BluetoothDeviceBlueZ* device, const std::string& old_address); - // The following methods are used to send various GATT observer events to - // observers. - void NotifyGattServiceAdded(BluetoothRemoteGattServiceBlueZ* service); - void NotifyGattServiceRemoved(BluetoothRemoteGattServiceBlueZ* service); - void NotifyGattServiceChanged(BluetoothRemoteGattServiceBlueZ* service); - void NotifyGattServicesDiscovered(BluetoothDeviceBlueZ* device); - void NotifyGattDiscoveryComplete(BluetoothRemoteGattServiceBlueZ* service); - void NotifyGattCharacteristicAdded( - BluetoothRemoteGattCharacteristicBlueZ* characteristic); - void NotifyGattCharacteristicRemoved( - BluetoothRemoteGattCharacteristicBlueZ* characteristic); - void NotifyGattDescriptorAdded( - BluetoothRemoteGattDescriptorBlueZ* descriptor); - void NotifyGattDescriptorRemoved( - BluetoothRemoteGattDescriptorBlueZ* descriptor); - void NotifyGattCharacteristicValueChanged( - BluetoothRemoteGattCharacteristicBlueZ* characteristic, - const std::vector<uint8_t>& value); - void NotifyGattDescriptorValueChanged( - BluetoothRemoteGattDescriptorBlueZ* descriptor, - const std::vector<uint8_t>& value); - // Returns the object path of the adapter. const dbus::ObjectPath& object_path() const { return object_path_; } diff --git a/device/bluetooth/bluetooth_device.h b/device/bluetooth/bluetooth_device.h index 17c5fda..2bf6f35 100644 --- a/device/bluetooth/bluetooth_device.h +++ b/device/bluetooth/bluetooth_device.h @@ -457,6 +457,9 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDevice { // empty string. static std::string CanonicalizeAddress(const std::string& address); + // Return associated BluetoothAdapter. + BluetoothAdapter* GetAdapter() { return adapter_; } + protected: // BluetoothGattConnection is a friend to call Add/RemoveGattConnection. friend BluetoothGattConnection; diff --git a/device/bluetooth/bluetooth_device_android.cc b/device/bluetooth/bluetooth_device_android.cc index 253680b..27fdbaf 100644 --- a/device/bluetooth/bluetooth_device_android.cc +++ b/device/bluetooth/bluetooth_device_android.cc @@ -245,8 +245,7 @@ void BluetoothDeviceAndroid::OnGattServicesDiscovered( JNIEnv* env, const JavaParamRef<jobject>& jcaller) { SetGattServicesDiscoveryComplete(true); - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, GetAdapter()->GetObservers(), - GattServicesDiscovered(GetAdapter(), this)); + adapter_->NotifyGattServicesDiscovered(this); } void BluetoothDeviceAndroid::CreateGattRemoteService( @@ -262,13 +261,13 @@ void BluetoothDeviceAndroid::CreateGattRemoteService( return; BluetoothDevice::GattServiceMap::iterator service_iterator = - gatt_services_.set(instance_id_string, - BluetoothRemoteGattServiceAndroid::Create( - GetAdapter(), this, bluetooth_gatt_service_wrapper, - instance_id_string, j_device_.obj())); + gatt_services_.set( + instance_id_string, + BluetoothRemoteGattServiceAndroid::Create( + GetAndroidAdapter(), this, bluetooth_gatt_service_wrapper, + instance_id_string, j_device_.obj())); - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, GetAdapter()->GetObservers(), - GattServiceAdded(adapter_, this, service_iterator->second)); + adapter_->NotifyGattServiceAdded(service_iterator->second); } BluetoothDeviceAndroid::BluetoothDeviceAndroid(BluetoothAdapterAndroid* adapter) diff --git a/device/bluetooth/bluetooth_device_android.h b/device/bluetooth/bluetooth_device_android.h index 95f7aad..2fc634d 100644 --- a/device/bluetooth/bluetooth_device_android.h +++ b/device/bluetooth/bluetooth_device_android.h @@ -42,7 +42,7 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceAndroid final base::android::ScopedJavaLocalRef<jobject> GetJavaObject(); // Get owning BluetoothAdapter cast to BluetoothAdapterAndroid. - BluetoothAdapterAndroid* GetAdapter() { + BluetoothAdapterAndroid* GetAndroidAdapter() { return static_cast<BluetoothAdapterAndroid*>(adapter_); } diff --git a/device/bluetooth/bluetooth_device_unittest.cc b/device/bluetooth/bluetooth_device_unittest.cc index 4fc30e4..6d956c0 100644 --- a/device/bluetooth/bluetooth_device_unittest.cc +++ b/device/bluetooth/bluetooth_device_unittest.cc @@ -18,6 +18,8 @@ #include "device/bluetooth/test/bluetooth_test_android.h" #elif defined(OS_MACOSX) #include "device/bluetooth/test/bluetooth_test_mac.h" +#elif defined(OS_WIN) +#include "device/bluetooth/test/bluetooth_test_win.h" #endif namespace device { @@ -69,7 +71,7 @@ TEST(BluetoothDeviceTest, CanonicalizeAddressFormat_RejectsInvalidFormats) { } } -#if defined(OS_ANDROID) || defined(OS_MACOSX) +#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) // Verifies basic device properties, e.g. GetAddress, GetName, ... TEST_F(BluetoothTest, LowEnergyDeviceProperties) { if (!PlatformSupportsLowEnergy()) { @@ -80,7 +82,10 @@ TEST_F(BluetoothTest, LowEnergyDeviceProperties) { StartLowEnergyDiscoverySession(); BluetoothDevice* device = DiscoverLowEnergyDevice(1); ASSERT_TRUE(device); +// Bluetooth class information for BLE device is not available on Windows. +#ifndef OS_WIN EXPECT_EQ(0x1F00u, device->GetBluetoothClass()); +#endif EXPECT_EQ(kTestDeviceAddress1, device->GetAddress()); EXPECT_EQ(BluetoothDevice::VENDOR_ID_UNKNOWN, device->GetVendorIDSource()); EXPECT_EQ(0, device->GetVendorID()); @@ -92,9 +97,9 @@ TEST_F(BluetoothTest, LowEnergyDeviceProperties) { EXPECT_TRUE(ContainsValue(uuids, BluetoothUUID(kTestUUIDGenericAccess))); EXPECT_TRUE(ContainsValue(uuids, BluetoothUUID(kTestUUIDGenericAttribute))); } -#endif // defined(OS_ANDROID) || defined(OS_MACOSX) +#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) -#if defined(OS_ANDROID) || defined(OS_MACOSX) +#if defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) // Device with no advertised Service UUIDs. TEST_F(BluetoothTest, LowEnergyDeviceNoUUIDs) { if (!PlatformSupportsLowEnergy()) { @@ -108,7 +113,7 @@ TEST_F(BluetoothTest, LowEnergyDeviceNoUUIDs) { BluetoothDevice::UUIDList uuids = device->GetUUIDs(); EXPECT_EQ(0u, uuids.size()); } -#endif // defined(OS_ANDROID) || defined(OS_MACOSX) +#endif // defined(OS_ANDROID) || defined(OS_MACOSX) || defined(OS_WIN) // TODO(scheib): Test with a device with no name. http://crbug.com/506415 // BluetoothDevice::GetAddressWithLocalizedDeviceTypeName() will run, which @@ -467,8 +472,12 @@ TEST_F(BluetoothTest, BluetoothGattConnection_ErrorAfterConnection) { } #endif // defined(OS_ANDROID) -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) || defined(OS_WIN) TEST_F(BluetoothTest, GattServices_ObserversCalls) { + if (!PlatformSupportsLowEnergy()) { + LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; + return; + } InitWithFakeAdapter(); StartLowEnergyDiscoverySession(); BluetoothDevice* device = DiscoverLowEnergyDevice(3); @@ -487,10 +496,14 @@ TEST_F(BluetoothTest, GattServices_ObserversCalls) { EXPECT_EQ(1, observer.gatt_services_discovered_count()); EXPECT_EQ(2, observer.gatt_service_added_count()); } -#endif // defined(OS_ANDROID) +#endif // defined(OS_ANDROID) || defined(OS_WIN) -#if defined(OS_ANDROID) +#if defined(OS_ANDROID) || defined(OS_WIN) TEST_F(BluetoothTest, GetGattServices_and_GetGattService) { + if (!PlatformSupportsLowEnergy()) { + LOG(WARNING) << "Low Energy Bluetooth unavailable, skipping unit test."; + return; + } InitWithFakeAdapter(); StartLowEnergyDiscoverySession(); BluetoothDevice* device = DiscoverLowEnergyDevice(3); @@ -516,7 +529,7 @@ TEST_F(BluetoothTest, GetGattServices_and_GetGattService) { EXPECT_TRUE(device->GetGattService(service_id2)); EXPECT_TRUE(device->GetGattService(service_id3)); } -#endif // defined(OS_ANDROID) +#endif // defined(OS_ANDROID) || defined(OS_WIN) #if defined(OS_ANDROID) TEST_F(BluetoothTest, GetGattServices_DiscoveryError) { diff --git a/device/bluetooth/bluetooth_device_win.cc b/device/bluetooth/bluetooth_device_win.cc index 8678576..d63b9d0 100644 --- a/device/bluetooth/bluetooth_device_win.cc +++ b/device/bluetooth/bluetooth_device_win.cc @@ -12,6 +12,7 @@ #include "base/sequenced_task_runner.h" #include "base/strings/stringprintf.h" #include "device/bluetooth/bluetooth_adapter_win.h" +#include "device/bluetooth/bluetooth_remote_gatt_service_win.h" #include "device/bluetooth/bluetooth_service_record_win.h" #include "device/bluetooth/bluetooth_socket_thread.h" #include "device/bluetooth/bluetooth_socket_win.h" @@ -300,6 +301,84 @@ void BluetoothDeviceWin::UpdateServices( service_record_list_.push_back(service_record); uuids_.push_back(service_record->uuid()); } + + if (!device_state.is_bluetooth_classic()) + UpdateGattServices(device_state.service_record_states); +} + +bool BluetoothDeviceWin::IsGattServiceDiscovered(BluetoothUUID& uuid, + uint16_t attribute_handle) { + GattServiceMap::iterator it = gatt_services_.begin(); + for (; it != gatt_services_.end(); it++) { + uint16_t it_att_handle = + static_cast<BluetoothRemoteGattServiceWin*>(it->second) + ->GetAttributeHandle(); + BluetoothUUID it_uuid = it->second->GetUUID(); + if (attribute_handle == it_att_handle && uuid == it_uuid) { + return true; + } + } + return false; +} + +bool BluetoothDeviceWin::DoesGattServiceExist( + const ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>& + service_state, + BluetoothGattService* service) { + uint16_t attribute_handle = + static_cast<BluetoothRemoteGattServiceWin*>(service) + ->GetAttributeHandle(); + BluetoothUUID uuid = service->GetUUID(); + ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>::const_iterator it = + service_state.begin(); + for (; it != service_state.end(); ++it) { + if (attribute_handle == (*it)->attribute_handle && uuid == (*it)->gatt_uuid) + return true; + } + return false; +} + +void BluetoothDeviceWin::UpdateGattServices( + const ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>& + service_state) { + // First, remove no longer exist GATT service. + { + std::vector<std::string> to_be_removed_services; + for (const auto& gatt_service : gatt_services_) { + if (!DoesGattServiceExist(service_state, gatt_service.second)) { + to_be_removed_services.push_back(gatt_service.first); + } + } + for (const auto& service : to_be_removed_services) { + gatt_services_.erase(service); + } + // Update previously discovered services. + for (auto gatt_service : gatt_services_) { + static_cast<BluetoothRemoteGattServiceWin*>(gatt_service.second) + ->Update(); + } + } + + // Return if no new services have been added. + if (gatt_services_.size() == service_state.size()) + return; + + // Add new services. + for (ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>::const_iterator + it = service_state.begin(); + it != service_state.end(); ++it) { + if (!IsGattServiceDiscovered((*it)->gatt_uuid, (*it)->attribute_handle)) { + BluetoothRemoteGattServiceWin* primary_service = + new BluetoothRemoteGattServiceWin(this, (*it)->path, (*it)->gatt_uuid, + (*it)->attribute_handle, true, + nullptr, ui_task_runner_); + gatt_services_.add(primary_service->GetIdentifier(), + scoped_ptr<BluetoothGattService>(primary_service)); + adapter_->NotifyGattServiceAdded(primary_service); + } + } + + adapter_->NotifyGattServicesDiscovered(this); } } // namespace device diff --git a/device/bluetooth/bluetooth_device_win.h b/device/bluetooth/bluetooth_device_win.h index cd2106a..6166032 100644 --- a/device/bluetooth/bluetooth_device_win.h +++ b/device/bluetooth/bluetooth_device_win.h @@ -107,6 +107,22 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothDeviceWin : public BluetoothDevice { // Updates the services with services stored in |device_state|. void UpdateServices(const BluetoothTaskManagerWin::DeviceState& device_state); + // Checks if GATT service with |uuid| and |attribute_handle| has already been + // discovered. + bool IsGattServiceDiscovered(BluetoothUUID& uuid, uint16_t attribute_handle); + + // Checks if |service| still exist on device according to newly discovered + // |service_state|. + bool DoesGattServiceExist( + const ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>& + service_state, + BluetoothGattService* service); + + // Updates the GATT services with the services stored in |service_state|. + void UpdateGattServices( + const ScopedVector<BluetoothTaskManagerWin::ServiceRecordState>& + service_state); + scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; scoped_refptr<BluetoothSocketThread> socket_thread_; net::NetLog* net_log_; diff --git a/device/bluetooth/bluetooth_low_energy_win_fake.cc b/device/bluetooth/bluetooth_low_energy_win_fake.cc index 6db6444..6750323 100644 --- a/device/bluetooth/bluetooth_low_energy_win_fake.cc +++ b/device/bluetooth/bluetooth_low_energy_win_fake.cc @@ -152,6 +152,14 @@ BLEGattService* BluetoothLowEnergyWrapperFake::SimulateBLEGattService( return service; } +BLEDevice* BluetoothLowEnergyWrapperFake::GetSimulatedBLEDevice( + std::string device_address) { + BLEDevicesMap::iterator it_d = simulated_devices_.find(device_address); + if (it_d == simulated_devices_.end()) + return nullptr; + return it_d->second.get(); +} + USHORT BluetoothLowEnergyWrapperFake::GenerateAUniqueAttributeHandle( std::string device_address) { scoped_ptr<std::set<USHORT>>& set_of_ushort = @@ -200,7 +208,7 @@ BluetoothLowEnergyWrapperFake::ExtractDeviceAddressFromDevicePath( base::string16 path) { std::size_t found = path.find('/'); if (found != base::string16::npos) { - return path.substr(0, found - 1); + return path.substr(0, found); } return path; } diff --git a/device/bluetooth/bluetooth_low_energy_win_fake.h b/device/bluetooth/bluetooth_low_energy_win_fake.h index d2a9ca2..a4da0c7 100644 --- a/device/bluetooth/bluetooth_low_energy_win_fake.h +++ b/device/bluetooth/bluetooth_low_energy_win_fake.h @@ -81,6 +81,7 @@ class BluetoothLowEnergyWrapperFake : public BluetoothLowEnergyWrapper { BLEDevice* SimulateBLEDevice(std::string device_name, BLUETOOTH_ADDRESS device_address); + BLEDevice* GetSimulatedBLEDevice(std::string device_address); BLEGattService* SimulateBLEGattService(BLEDevice* device, std::string uuid); private: diff --git a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc index f3ab385..d8d0299 100644 --- a/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc +++ b/device/bluetooth/bluetooth_remote_gatt_characteristic_android.cc @@ -208,8 +208,7 @@ void BluetoothRemoteGattCharacteristicAndroid::OnChanged( const JavaParamRef<jobject>& jcaller, const JavaParamRef<jbyteArray>& value) { base::android::JavaByteArrayToByteVector(env, value, &value_); - FOR_EACH_OBSERVER(BluetoothAdapter::Observer, adapter_->GetObservers(), - GattCharacteristicValueChanged(adapter_, this, value_)); + adapter_->NotifyGattCharacteristicValueChanged(this, value_); } void BluetoothRemoteGattCharacteristicAndroid::OnRead( diff --git a/device/bluetooth/bluetooth_remote_gatt_service_win.cc b/device/bluetooth/bluetooth_remote_gatt_service_win.cc new file mode 100644 index 0000000..0c93588 --- /dev/null +++ b/device/bluetooth/bluetooth_remote_gatt_service_win.cc @@ -0,0 +1,113 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "device/bluetooth/bluetooth_remote_gatt_service_win.h" + +namespace device { +BluetoothRemoteGattServiceWin::BluetoothRemoteGattServiceWin( + BluetoothDeviceWin* device, + base::FilePath service_path, + BluetoothUUID service_uuid, + uint16_t service_attribute_handle, + bool is_primary, + BluetoothRemoteGattServiceWin* parent_service, + scoped_refptr<base::SequencedTaskRunner>& ui_task_runner) + : service_path_(service_path), + device_(device), + service_uuid_(service_uuid), + service_attribute_handle_(service_attribute_handle), + is_primary_(is_primary), + parent_service_(parent_service), + ui_task_runner_(ui_task_runner) { + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); + DCHECK(!service_path_.empty()); + DCHECK(service_uuid_.IsValid()); + DCHECK(service_attribute_handle_); + DCHECK(device_); + if (!is_primary_) + DCHECK(parent_service_); + Update(); +} + +BluetoothRemoteGattServiceWin::~BluetoothRemoteGattServiceWin() {} + +std::string BluetoothRemoteGattServiceWin::GetIdentifier() const { + std::string identifier = + service_uuid_.value() + "_" + std::to_string(service_attribute_handle_); + if (is_primary_) + return device_->GetIdentifier() + "/" + identifier; + else + return parent_service_->GetIdentifier() + "/" + identifier; +} + +BluetoothUUID BluetoothRemoteGattServiceWin::GetUUID() const { + return const_cast<BluetoothUUID&>(service_uuid_); +} + +bool BluetoothRemoteGattServiceWin::IsLocal() const { + return false; +} + +bool BluetoothRemoteGattServiceWin::IsPrimary() const { + return is_primary_; +} + +BluetoothDevice* BluetoothRemoteGattServiceWin::GetDevice() const { + return device_; +} + +std::vector<BluetoothGattCharacteristic*> +BluetoothRemoteGattServiceWin::GetCharacteristics() const { + NOTIMPLEMENTED(); + return std::vector<BluetoothGattCharacteristic*>(); +} + +std::vector<BluetoothGattService*> +BluetoothRemoteGattServiceWin::GetIncludedServices() const { + NOTIMPLEMENTED(); + return std::vector<BluetoothGattService*>(); +} + +BluetoothGattCharacteristic* BluetoothRemoteGattServiceWin::GetCharacteristic( + const std::string& identifier) const { + NOTIMPLEMENTED(); + return nullptr; +} + +bool BluetoothRemoteGattServiceWin::AddCharacteristic( + device::BluetoothGattCharacteristic* characteristic) { + NOTIMPLEMENTED(); + return false; +} + +bool BluetoothRemoteGattServiceWin::AddIncludedService( + device::BluetoothGattService* service) { + NOTIMPLEMENTED(); + return false; +} + +void BluetoothRemoteGattServiceWin::Register( + const base::Closure& callback, + const ErrorCallback& error_callback) { + NOTIMPLEMENTED(); + error_callback.Run(); +} + +void BluetoothRemoteGattServiceWin::Unregister( + const base::Closure& callback, + const ErrorCallback& error_callback) { + NOTIMPLEMENTED(); + error_callback.Run(); +} + +void BluetoothRemoteGattServiceWin::Update() { + DCHECK(ui_task_runner_->RunsTasksOnCurrentThread()); + NOTIMPLEMENTED(); +} + +uint16_t BluetoothRemoteGattServiceWin::GetAttributeHandle() { + return service_attribute_handle_; +} + +} // namespace device.
\ No newline at end of file diff --git a/device/bluetooth/bluetooth_remote_gatt_service_win.h b/device/bluetooth/bluetooth_remote_gatt_service_win.h new file mode 100644 index 0000000..218bc90 --- /dev/null +++ b/device/bluetooth/bluetooth_remote_gatt_service_win.h @@ -0,0 +1,63 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_WIN_H_ +#define DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_WIN_H_ + +#include "base/files/file.h" +#include "device/bluetooth/bluetooth_device_win.h" +#include "device/bluetooth/bluetooth_gatt_service.h" + +namespace device { + +// The BluetoothRemoteGattServiceWin class implements BluetoothGattService +// for remote GATT services on Windows 8 and later. +class DEVICE_BLUETOOTH_EXPORT BluetoothRemoteGattServiceWin + : public BluetoothGattService { + public: + BluetoothRemoteGattServiceWin( + BluetoothDeviceWin* device, + base::FilePath service_path, + BluetoothUUID service_uuid, + uint16_t service_attribute_handle, + bool is_primary, + BluetoothRemoteGattServiceWin* parent_service, + scoped_refptr<base::SequencedTaskRunner>& ui_task_runner); + ~BluetoothRemoteGattServiceWin() override; + + // Override BluetoothGattService interfaces. + std::string GetIdentifier() const override; + BluetoothUUID GetUUID() const override; + bool IsLocal() const override; + bool IsPrimary() const override; + BluetoothDevice* GetDevice() const override; + std::vector<BluetoothGattCharacteristic*> GetCharacteristics() const override; + std::vector<BluetoothGattService*> GetIncludedServices() const override; + BluetoothGattCharacteristic* GetCharacteristic( + const std::string& identifier) const override; + bool AddCharacteristic(BluetoothGattCharacteristic* characteristic) override; + bool AddIncludedService(BluetoothGattService* service) override; + void Register(const base::Closure& callback, + const ErrorCallback& error_callback) override; + void Unregister(const base::Closure& callback, + const ErrorCallback& error_callback) override; + + // Update included services and characteristics. + void Update(); + uint16_t GetAttributeHandle(); + + private: + BluetoothDeviceWin* device_; + base::FilePath service_path_; + BluetoothUUID service_uuid_; + uint16_t service_attribute_handle_; + bool is_primary_; + BluetoothRemoteGattServiceWin* parent_service_; + scoped_refptr<base::SequencedTaskRunner> ui_task_runner_; + + DISALLOW_COPY_AND_ASSIGN(BluetoothRemoteGattServiceWin); +}; + +} // namespace device. +#endif // DEVICE_BLUETOOTH_BLUETOOTH_REMOTE_GATT_SERVICE_WIN_H_ diff --git a/device/bluetooth/bluetooth_task_manager_win.cc b/device/bluetooth/bluetooth_task_manager_win.cc index 0419637..1f9364d 100644 --- a/device/bluetooth/bluetooth_task_manager_win.cc +++ b/device/bluetooth/bluetooth_task_manager_win.cc @@ -534,8 +534,11 @@ bool BluetoothTaskManagerWin::DiscoverServices( } else { if (!DiscoverLowEnergyDeviceServices(device->path, service_record_states)) { - return SearchForGattServiceDevicePaths(device->address, - service_record_states); + return false; + } + if (!SearchForGattServiceDevicePaths(device->address, + service_record_states)) { + return false; } } } diff --git a/device/bluetooth/test/bluetooth_test_win.cc b/device/bluetooth/test/bluetooth_test_win.cc index 2bbaeee..7a8f8f8 100644 --- a/device/bluetooth/test/bluetooth_test_win.cc +++ b/device/bluetooth/test/bluetooth_test_win.cc @@ -128,4 +128,30 @@ BluetoothDevice* BluetoothTestWin::DiscoverLowEnergyDevice(int device_ordinal) { return nullptr; } + +void BluetoothTestWin::SimulateGattConnection(BluetoothDevice* device) { + bluetooth_task_runner_->RunPendingTasks(); + ui_task_runner_->RunPendingTasks(); + + // Clear records caused by CreateGattConnection since we do not support it on + // Windows. + gatt_discovery_attempts_++; + expected_success_callback_calls_--; + unexpected_error_callback_ = false; +} + +void BluetoothTestWin::SimulateGattServicesDiscovered( + BluetoothDevice* device, + const std::vector<std::string>& uuids) { + win::BLEDevice* simulated_device = + fake_bt_le_wrapper_->GetSimulatedBLEDevice(device->GetAddress()); + CHECK(simulated_device); + + for (auto uuid : uuids) { + fake_bt_le_wrapper_->SimulateBLEGattService(simulated_device, uuid); + } + + bluetooth_task_runner_->RunPendingTasks(); + ui_task_runner_->RunPendingTasks(); +} } diff --git a/device/bluetooth/test/bluetooth_test_win.h b/device/bluetooth/test/bluetooth_test_win.h index 2fea2ac..eeeb068 100644 --- a/device/bluetooth/test/bluetooth_test_win.h +++ b/device/bluetooth/test/bluetooth_test_win.h @@ -30,6 +30,10 @@ class BluetoothTestWin : public BluetoothTestBase { bool DenyPermission() override; void StartLowEnergyDiscoverySession() override; BluetoothDevice* DiscoverLowEnergyDevice(int device_ordinal) override; + void SimulateGattConnection(BluetoothDevice* device) override; + void SimulateGattServicesDiscovered( + BluetoothDevice* device, + const std::vector<std::string>& uuids) override; private: scoped_refptr<base::TestSimpleTaskRunner> ui_task_runner_; |