Commit cd0149af authored by Reilly Grant's avatar Reilly Grant Committed by Commit Bot

[Bluetooth WinRT] Explicitly open GATT service for shared access

It appears that GetCharacteristicsAsync() will implicitly open a GATT
service for exclusive access. We don't want this so this change adds an
explicit OpenAsync() call to choose shared access. The test fakes are
updated to only support shared access.

Bug: 968816
Change-Id: I30af95fe428fad075ae8cbddd3075979a834e65f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1637192Reviewed-by: default avatarOvidio de Jesús Ruiz-Henríquez <odejesush@chromium.org>
Commit-Queue: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/master@{#665005}
parent 9eb5df8c
...@@ -37,12 +37,23 @@ using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: ...@@ -37,12 +37,23 @@ using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceService; GattDeviceService;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceServicesResult; GattDeviceServicesResult;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattOpenStatus;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattOpenStatus_AlreadyOpened;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattOpenStatus_Success;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattSharingMode;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattSharingMode_SharedReadAndWrite;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattCharacteristic3; IGattCharacteristic3;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattCharacteristicsResult; IGattCharacteristicsResult;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattDescriptorsResult; IGattDescriptorsResult;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattDeviceService;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattDeviceService3; IGattDeviceService3;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
...@@ -196,15 +207,6 @@ void BluetoothGattDiscovererWinrt::OnGetGattServices( ...@@ -196,15 +207,6 @@ void BluetoothGattDiscovererWinrt::OnGetGattServices(
num_services_ = gatt_services_.size(); num_services_ = gatt_services_.size();
for (const auto& gatt_service : gatt_services_) { for (const auto& gatt_service : gatt_services_) {
uint16_t service_attribute_handle;
hr = gatt_service->get_AttributeHandle(&service_attribute_handle);
if (FAILED(hr)) {
VLOG(2) << "Getting AttributeHandle failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(callback_).Run(false);
return;
}
ComPtr<IGattDeviceService3> gatt_service_3; ComPtr<IGattDeviceService3> gatt_service_3;
hr = gatt_service.As(&gatt_service_3); hr = gatt_service.As(&gatt_service_3);
if (FAILED(hr)) { if (FAILED(hr)) {
...@@ -214,31 +216,74 @@ void BluetoothGattDiscovererWinrt::OnGetGattServices( ...@@ -214,31 +216,74 @@ void BluetoothGattDiscovererWinrt::OnGetGattServices(
return; return;
} }
ComPtr<IAsyncOperation<GattCharacteristicsResult*>> get_characteristics_op; ComPtr<IAsyncOperation<GattOpenStatus>> open_op;
hr = gatt_service_3->GetCharacteristicsAsync(&get_characteristics_op); hr =
gatt_service_3->OpenAsync(GattSharingMode_SharedReadAndWrite, &open_op);
if (FAILED(hr)) { if (FAILED(hr)) {
VLOG(2) << "GattDeviceService::GetCharacteristicsAsync() failed: " VLOG(2) << "GattDeviceService::OpenAsync() failed: "
<< logging::SystemErrorCodeToString(hr); << logging::SystemErrorCodeToString(hr);
std::move(callback_).Run(false); std::move(callback_).Run(false);
return;
} }
hr = base::win::PostAsyncResults( hr = base::win::PostAsyncResults(
std::move(get_characteristics_op), std::move(open_op),
base::BindOnce(&BluetoothGattDiscovererWinrt::OnGetCharacteristics, base::BindOnce(&BluetoothGattDiscovererWinrt::OnServiceOpen,
weak_ptr_factory_.GetWeakPtr(), weak_ptr_factory_.GetWeakPtr(),
service_attribute_handle)); std::move(gatt_service)));
if (FAILED(hr)) {
VLOG(2) << "PostAsyncResults failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(callback_).Run(false);
}
} }
RunCallbackIfDone(); RunCallbackIfDone();
} }
void BluetoothGattDiscovererWinrt::OnServiceOpen(
ComPtr<IGattDeviceService> gatt_service,
GattOpenStatus status) {
if (status != GattOpenStatus_Success &&
status != GattOpenStatus_AlreadyOpened) {
VLOG(2) << "Failed to open GATT service: " << status;
std::move(callback_).Run(false);
return;
}
uint16_t service_attribute_handle;
HRESULT hr = gatt_service->get_AttributeHandle(&service_attribute_handle);
if (FAILED(hr)) {
VLOG(2) << "Getting AttributeHandle failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(callback_).Run(false);
return;
}
ComPtr<IGattDeviceService3> gatt_service_3;
hr = gatt_service.As(&gatt_service_3);
if (FAILED(hr)) {
VLOG(2) << "Obtaining IGattDeviceService3 failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(callback_).Run(false);
return;
}
ComPtr<IAsyncOperation<GattCharacteristicsResult*>> get_characteristics_op;
hr = gatt_service_3->GetCharacteristicsAsync(&get_characteristics_op);
if (FAILED(hr)) {
VLOG(2) << "GattDeviceService::GetCharacteristicsAsync() failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(callback_).Run(false);
return;
}
hr = base::win::PostAsyncResults(
std::move(get_characteristics_op),
base::BindOnce(&BluetoothGattDiscovererWinrt::OnGetCharacteristics,
weak_ptr_factory_.GetWeakPtr(), service_attribute_handle));
if (FAILED(hr)) {
VLOG(2) << "PostAsyncResults failed: "
<< logging::SystemErrorCodeToString(hr);
std::move(callback_).Run(false);
}
}
void BluetoothGattDiscovererWinrt::OnGetCharacteristics( void BluetoothGattDiscovererWinrt::OnGetCharacteristics(
uint16_t service_attribute_handle, uint16_t service_attribute_handle,
ComPtr<IGattCharacteristicsResult> characteristics_result) { ComPtr<IGattCharacteristicsResult> characteristics_result) {
......
...@@ -63,6 +63,13 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothGattDiscovererWinrt { ...@@ -63,6 +63,13 @@ class DEVICE_BLUETOOTH_EXPORT BluetoothGattDiscovererWinrt {
ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
IGattDeviceServicesResult> services_result); IGattDeviceServicesResult> services_result);
void OnServiceOpen(
Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::
GenericAttributeProfile::IGattDeviceService>
gatt_service,
ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattOpenStatus
status);
void OnGetCharacteristics( void OnGetCharacteristics(
uint16_t service_attribute_handle, uint16_t service_attribute_handle,
Microsoft::WRL::ComPtr< Microsoft::WRL::ComPtr<
......
...@@ -33,13 +33,19 @@ using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: ...@@ -33,13 +33,19 @@ using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattDeviceServicesResult; GattDeviceServicesResult;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattOpenStatus; using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::GattOpenStatus;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattOpenStatus_AlreadyOpened;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattOpenStatus_Success;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile:: using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattSharingMode; GattSharingMode;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::
GattSharingMode_SharedReadAndWrite;
using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattSession; using ABI::Windows::Devices::Bluetooth::GenericAttributeProfile::IGattSession;
using ABI::Windows::Devices::Enumeration::DeviceAccessStatus; using ABI::Windows::Devices::Enumeration::DeviceAccessStatus;
using ABI::Windows::Devices::Enumeration::IDeviceAccessInformation; using ABI::Windows::Devices::Enumeration::IDeviceAccessInformation;
using ABI::Windows::Foundation::Collections::IVectorView;
using ABI::Windows::Foundation::IAsyncOperation; using ABI::Windows::Foundation::IAsyncOperation;
using ABI::Windows::Foundation::Collections::IVectorView;
using Microsoft::WRL::ComPtr; using Microsoft::WRL::ComPtr;
using Microsoft::WRL::Make; using Microsoft::WRL::Make;
...@@ -109,11 +115,29 @@ HRESULT FakeGattDeviceServiceWinrt::RequestAccessAsync( ...@@ -109,11 +115,29 @@ HRESULT FakeGattDeviceServiceWinrt::RequestAccessAsync(
HRESULT FakeGattDeviceServiceWinrt::OpenAsync( HRESULT FakeGattDeviceServiceWinrt::OpenAsync(
GattSharingMode sharing_mode, GattSharingMode sharing_mode,
IAsyncOperation<GattOpenStatus>** operation) { IAsyncOperation<GattOpenStatus>** operation) {
return E_NOTIMPL; if (sharing_mode != GattSharingMode_SharedReadAndWrite)
return E_NOTIMPL;
GattOpenStatus status =
opened_ ? GattOpenStatus_AlreadyOpened : GattOpenStatus_Success;
opened_ = true;
auto async_op = Make<base::win::AsyncOperation<GattOpenStatus>>();
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(async_op->callback(), status));
*operation = async_op.Detach();
return S_OK;
} }
HRESULT FakeGattDeviceServiceWinrt::GetCharacteristicsAsync( HRESULT FakeGattDeviceServiceWinrt::GetCharacteristicsAsync(
IAsyncOperation<GattCharacteristicsResult*>** operation) { IAsyncOperation<GattCharacteristicsResult*>** operation) {
// It has been observed that this method will implicitly call
// OpenAsync(Exclusive) if the service has not been opened already. Catch
// calls to an unopened service as we do not want to take an exclusive lock
// on a service.
if (!opened_)
return E_NOTIMPL;
auto async_op = Make<base::win::AsyncOperation<GattCharacteristicsResult*>>(); auto async_op = Make<base::win::AsyncOperation<GattCharacteristicsResult*>>();
base::ThreadTaskRunnerHandle::Get()->PostTask( base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(async_op->callback(), FROM_HERE, base::BindOnce(async_op->callback(),
......
...@@ -121,6 +121,7 @@ class FakeGattDeviceServiceWinrt ...@@ -121,6 +121,7 @@ class FakeGattDeviceServiceWinrt
Microsoft::WRL::ComPtr<FakeBluetoothLEDeviceWinrt> fake_device_; Microsoft::WRL::ComPtr<FakeBluetoothLEDeviceWinrt> fake_device_;
GUID uuid_; GUID uuid_;
uint16_t attribute_handle_; uint16_t attribute_handle_;
bool opened_ = false;
std::vector<Microsoft::WRL::ComPtr<FakeGattCharacteristicWinrt>> std::vector<Microsoft::WRL::ComPtr<FakeGattCharacteristicWinrt>>
fake_characteristics_; fake_characteristics_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment