summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2021-12-17 17:55:06 +0100
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2022-01-28 17:15:05 +0000
commit43ff62dcc9102cfa682da884591d1bdda3ca86da (patch)
treec4a0ab6124e62221dfaefc502a01101de3ce7396
parent7a7b4da687a4ed7db6735130a02f35ff7d159f93 (diff)
Windows Bluetooth: replace deprecated methods (part 1)
Replace deprecated BluetoothDevice::RfcommServices() call with its async version. This requires to move a part of the method to a new callback. As a drive-by: fixed the check for finishDiscovery() condition. Previously it could be skipped if some of the COM operations failed and we returned early. Now the check is wrapped into a QScopeGuard, so it is always executed. Task-number: QTBUG-94001 Change-Id: I2238e9aa64747503916672f023d7bd036ec9d37a Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Juha Vuolle <juha.vuolle@insta.fi> (cherry picked from commit 12aa9a228dcd8d4edd8cb273ef303598234a2d4c) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp94
1 files changed, 81 insertions, 13 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
index 11ad88aa..6a091095 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
@@ -148,6 +148,9 @@ private:
HRESULT onBluetoothLEDeviceFound(ComPtr<IBluetoothLEDevice> device, PairingCheck pairingCheck);
HRESULT onBluetoothLEDeviceFound(ComPtr<IBluetoothLEDevice> device);
HRESULT onBluetoothLEAdvertisementReceived(IBluetoothLEAdvertisementReceivedEventArgs *args);
+ HRESULT onRfcommServicesReceived(IAsyncOperation<Rfcomm::RfcommDeviceServicesResult *> *op,
+ AsyncStatus status, UINT64 address, UINT32 classOfDeviceInt,
+ const QString &btName);
void decrementPairedDevicesAndCheckFinished();
@@ -537,12 +540,22 @@ void QWinRTBluetoothDeviceDiscoveryWorker::leBluetoothInfoFromAddressAsync(quint
HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onPairedClassicBluetoothDeviceFoundAsync(IAsyncOperation<BluetoothDevice *> *op, AsyncStatus status)
{
- --m_pendingPairedDevices;
+ HRESULT hr;
+ // Need to decrement m_pendingPairedDevices and perform the check if some
+ // operation fails. Otherwise it will be done in the callback.
+ auto guard = qScopeGuard([this, &hr]() {
+ if (FAILED(hr)) {
+ qCWarning(QT_BT_WINDOWS) << "Failed to request Rfcomm services";
+ decrementPairedDevicesAndCheckFinished();
+ }
+ });
+ Q_UNUSED(guard); // to suppress warning
+
if (status != AsyncStatus::Completed)
return S_OK;
ComPtr<IBluetoothDevice> device;
- HRESULT hr = op->GetResults(&device);
+ hr = op->GetResults(&device);
EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain bluetooth device",
QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
return S_OK);
@@ -571,15 +584,71 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onPairedClassicBluetoothDeviceFoun
EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain raw value of device class",
QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
return S_OK);
- IVectorView <Rfcomm::RfcommDeviceService *> *deviceServices;
- hr = device->get_RfcommServices(&deviceServices);
- if (hr == E_ACCESSDENIED) {
- qCWarning(QT_BT_WINDOWS) << "Could not obtain device services. Please check you have "
- "permission to access the device.";
+
+ ComPtr<IBluetoothDevice3> device3;
+ hr = device.As(&device3);
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain bluetooth device3 interface",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
+
+ ComPtr<IAsyncOperation<Rfcomm::RfcommDeviceServicesResult *>> deviceServicesOperation;
+ hr = device3->GetRfcommServicesAsync(&deviceServicesOperation);
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Async Rfcomm services request failed",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
+
+ QPointer<QWinRTBluetoothDeviceDiscoveryWorker> thisPointer(this);
+ hr = deviceServicesOperation->put_Completed(
+ Callback<IAsyncOperationCompletedHandler<Rfcomm::RfcommDeviceServicesResult *>>(
+ [thisPointer, address, btName, classOfDeviceInt](
+ IAsyncOperation<Rfcomm::RfcommDeviceServicesResult *> *op,
+ AsyncStatus status) {
+ if (thisPointer) {
+ thisPointer->onRfcommServicesReceived(op, status, address,
+ classOfDeviceInt, btName);
+ }
+ return S_OK;
+ }).Get());
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not add Rfcomm services discovery callback",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
+
+ return S_OK;
+}
+
+HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onRfcommServicesReceived(
+ IAsyncOperation<Rfcomm::RfcommDeviceServicesResult *> *op, AsyncStatus status,
+ UINT64 address, UINT32 classOfDeviceInt, const QString &btName)
+{
+ // need to perform the check even if some of the operations fails
+ auto guard = qScopeGuard([this]() {
+ decrementPairedDevicesAndCheckFinished();
+ });
+ Q_UNUSED(guard); // to suppress warning
+
+ if (status != Completed)
+ return S_OK;
+
+ ComPtr<Rfcomm::IRfcommDeviceServicesResult> servicesResult;
+ HRESULT hr = op->GetResults(&servicesResult);
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain device services",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
+
+ BluetoothError error;
+ hr = servicesResult->get_Error(&error);
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain error code",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
+ if (error != BluetoothError_Success) {
+ qCWarning(QT_BT_WINDOWS) << "Obtain device services completed with BluetoothErrot"
+ << static_cast<int>(error);
} else {
- EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain device services",
- QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
- return S_OK);
+ IVectorView<Rfcomm::RfcommDeviceService *> *deviceServices;
+ hr = servicesResult->get_Services(&deviceServices);
+ EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain services list",
+ QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
+ return S_OK);
uint serviceCount;
hr = deviceServices->get_Size(&serviceCount);
EMIT_WORKER_ERROR_AND_RETURN_IF_FAILED("Could not obtain service list size",
@@ -606,7 +675,7 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onPairedClassicBluetoothDeviceFoun
}
qCDebug(QT_BT_WINDOWS) << "Discovered BT device: " << QString::number(address) << btName
- << "Num UUIDs" << uuids.count();
+ << "Num UUIDs" << uuids.count();
QBluetoothDeviceInfo info(QBluetoothAddress(address), btName, classOfDeviceInt);
info.setCoreConfigurations(QBluetoothDeviceInfo::BaseRateCoreConfiguration);
@@ -616,8 +685,7 @@ HRESULT QWinRTBluetoothDeviceDiscoveryWorker::onPairedClassicBluetoothDeviceFoun
QMetaObject::invokeMethod(this, "deviceFound", Qt::AutoConnection,
Q_ARG(QBluetoothDeviceInfo, info));
}
- if (!m_pendingPairedDevices && !(requestedModes & QBluetoothDeviceDiscoveryAgent::LowEnergyMethod))
- finishDiscovery();
+
return S_OK;
}