6#include <QtBluetooth/qbluetoothaddress.h>
7#include <QtBluetooth/qbluetoothdevicediscoveryagent.h>
8#include <QtBluetooth/private/qohosbluetoothaccess_p.h>
10#include <QtCore/qloggingcategory.h>
22 const QtOhosBluetooth::DiscoveryResult &device)
24 const QBluetoothAddress address(QString::fromStdString(device.deviceId));
25 if (address.isNull()) {
27 QT_BT_OHOS,
"%s: ignoring the device with an unexpected address: '%s'", Q_FUNC_INFO,
28 device.deviceId.c_str());
32 QBluetoothDeviceInfo deviceInfo(
33 address, QString::fromStdString(device.deviceName), device.classOfDevice);
34 deviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::BaseRateCoreConfiguration);
40 const std::vector<QtOhosBluetooth::DiscoveryResult> &discoveredDevices)
42 std::vector<QBluetoothDeviceInfo> foundDevicesInfos;
43 foundDevicesInfos.reserve(discoveredDevices.size());
45 for (
const auto &discoveredDevice : discoveredDevices) {
46 auto optDeviceInfo = tryMakeDeviceInfo(discoveredDevice);
50 optDeviceInfo->setRssi(discoveredDevice.rssi);
52 foundDevicesInfos.push_back(std::move(*optDeviceInfo));
55 return foundDevicesInfos;
59 const std::vector<QtOhosBluetooth::DiscoveryResult> &pairedDevices)
61 std::vector<QBluetoothDeviceInfo> pairedDevicesInfos;
62 pairedDevicesInfos.reserve(pairedDevices.size());
64 for (
const auto &pairedDevice : pairedDevices) {
65 auto optDeviceInfo = tryMakeDeviceInfo(pairedDevice);
69 optDeviceInfo->setCached(
true);
71 pairedDevicesInfos.push_back(std::move(*optDeviceInfo));
74 return pairedDevicesInfos;
78 QBluetoothDeviceInfo &existingDevice,
const QBluetoothDeviceInfo &newDevice)
80 QBluetoothDeviceInfo::Fields updatedFields = QBluetoothDeviceInfo::Field::None;
82 if (!newDevice.isCached() && existingDevice.rssi() != newDevice.rssi()) {
83 existingDevice.setRssi(newDevice.rssi());
84 updatedFields.setFlag(QBluetoothDeviceInfo::Field::RSSI);
87 if (existingDevice.isCached() && !newDevice.isCached())
88 existingDevice.setCached(
false);
90 if (existingDevice.name().isEmpty() && !newDevice.name().isEmpty())
91 existingDevice.setName(newDevice.name());
98QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(
99 const QBluetoothAddress &deviceAdapter, QBluetoothDeviceDiscoveryAgent *parent)
100 : lowEnergySearchTimeout(-1)
103 if (!deviceAdapter.isNull()) {
106 "%s: HarmonyOS does not support device adapter setting. Ignoring device adapter.",
108 lastError = QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError;
109 errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Device adapter setting not supported");
114 m_discoveryAgentProxy = QtOhosBluetooth::QOhosBluetoothDeviceDiscoveryAgentProxy::instance();
117 m_discoveryAgentProxy.get(), &QtOhosBluetooth::QOhosBluetoothDeviceDiscoveryAgentProxy::discoveryStopped,
120 reportDiscoveryStopped(DiscoveryStopReason::Finished);
124 m_discoveryAgentProxy.get(), &QtOhosBluetooth::QOhosBluetoothDeviceDiscoveryAgentProxy::discoveryStartFailed,
127 if (!m_discoveryRequested)
130 clearDiscoveryState();
131 lastError = QBluetoothDeviceDiscoveryAgent::InputOutputError;
132 errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Unable to start the device discovery");
137 m_discoveryAgentProxy.get(), &QtOhosBluetooth::QOhosBluetoothDeviceDiscoveryAgentProxy::discoveryStopFailed,
140 if (!m_discoveryRequested)
143 clearDiscoveryState();
144 lastError = QBluetoothDeviceDiscoveryAgent::UnknownError;
145 errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Timed out waiting for device discovery to stop");
150 m_discoveryAgentProxy.get(), &QtOhosBluetooth::QOhosBluetoothDeviceDiscoveryAgentProxy::bluetoothPoweredOff,
153 reportDiscoveryStopped(DiscoveryStopReason::BluetoothPoweredOff);
157 m_discoveryAgentProxy.get(), &QtOhosBluetooth::QOhosBluetoothDeviceDiscoveryAgentProxy::missingPermission,
160 if (!m_discoveryRequested)
163 clearDiscoveryState();
164 lastError = QBluetoothDeviceDiscoveryAgent::MissingPermissionsError;
165 errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Missing permissions for device discovery");
170 m_discoveryAgentProxy.get(), &QtOhosBluetooth::QOhosBluetoothDeviceDiscoveryAgentProxy::bluetoothDevicesFound,
172 [
this](
const std::vector<QtOhosBluetooth::DiscoveryResult> &alreadyDiscoveredDevices) {
173 if (!m_discoveryRequested)
176 reportDiscoveredDevices(processFoundDevices(alreadyDiscoveredDevices));
180QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate()
182 if (m_discoveryRequested && m_discoveryAgentProxy)
183 m_discoveryAgentProxy->stopBluetoothDiscovery();
186bool QBluetoothDeviceDiscoveryAgentPrivate::isActive()
const
194 return m_discoveryRequested;
197QBluetoothDeviceDiscoveryAgent::DiscoveryMethods QBluetoothDeviceDiscoveryAgent::supportedDiscoveryMethods()
199 return QBluetoothDeviceDiscoveryAgent::ClassicMethod;
202void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods)
204 requestedMethods = methods;
206 if (!m_discoveryAgentProxy) {
207 lastError = QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError;
208 errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Device adapter setting not supported");
209 clearDiscoveryState();
214 auto accessProxy = QtOhosBluetooth::QOhosBluetoothAccessProxy::instance();
215 if (accessProxy->tryGetBluetoothState() != QtOhosBluetooth::QOhosBluetoothAccessProxy::BluetoothState::STATE_ON) {
216 lastError = QBluetoothDeviceDiscoveryAgent::PoweredOffError;
217 errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Local bluetooth device is powered off");
218 clearDiscoveryState();
223 if (m_pendingCancel) {
224 m_pendingStart =
true;
228 lastError = QBluetoothDeviceDiscoveryAgent::NoError;
230 discoveredDevices.clear();
232 m_discoveryRequested =
true;
234 if (m_discoveryAgentProxy->isForeignDiscoveryOngoing()) {
235 m_pendingStart =
true;
236 m_discoveryAgentProxy->stopBluetoothDiscovery();
240 reportPairedDevicesAsync();
242 m_discoveryAgentProxy->startBluetoothDiscovery();
245void QBluetoothDeviceDiscoveryAgentPrivate::stop()
247 if (!m_discoveryAgentProxy) {
248 lastError = QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError;
249 errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Device adapter setting not supported");
250 clearDiscoveryState();
255 m_pendingCancel =
true;
256 m_pendingStart =
false;
257 m_discoveryAgentProxy->stopBluetoothDiscovery();
260void QBluetoothDeviceDiscoveryAgentPrivate::reportDiscoveryStopped(DiscoveryStopReason reason)
262 if (!m_discoveryRequested)
265 if (m_pendingStart) {
266 m_pendingStart =
false;
267 m_pendingCancel =
false;
268 start(requestedMethods);
269 }
else if (m_pendingCancel) {
270 m_discoveryRequested =
false;
271 m_pendingCancel =
false;
272 Q_EMIT q_ptr->canceled();
273 }
else if (reason == DiscoveryStopReason::BluetoothPoweredOff) {
274 m_discoveryRequested =
false;
275 lastError = QBluetoothDeviceDiscoveryAgent::PoweredOffError;
276 errorString = QBluetoothDeviceDiscoveryAgent::tr(
"Local bluetooth device is powered off");
279 m_discoveryRequested =
false;
280 Q_EMIT q_ptr->finished();
284void QBluetoothDeviceDiscoveryAgentPrivate::reportPairedDevicesAsync()
286 QMetaObject::invokeMethod(
289 if (!m_discoveryRequested)
292 reportDiscoveredDevices(processPairedDevices(m_discoveryAgentProxy->getPairedDevices()));
294 Qt::QueuedConnection);
297void QBluetoothDeviceDiscoveryAgentPrivate::reportDiscoveredDevices(
298 const std::vector<QBluetoothDeviceInfo> &bluetoothDevicesInfos)
300 for (
const auto &device : bluetoothDevicesInfos) {
301 auto alreadyDiscoveredDevice = std::find_if(
302 discoveredDevices.begin(), discoveredDevices.end(),
303 [&](
const auto &alreadyDiscoveredDevice) {
304 return alreadyDiscoveredDevice.address() == device.address();
307 if (alreadyDiscoveredDevice != discoveredDevices.end()) {
308 const auto updatedFields = updateDeviceInfoIfNeeded(*alreadyDiscoveredDevice, device);
309 if (updatedFields != QBluetoothDeviceInfo::Field::None)
310 Q_EMIT q_ptr->deviceUpdated(*alreadyDiscoveredDevice, updatedFields);
312 discoveredDevices.append(device);
313 Q_EMIT q_ptr->deviceDiscovered(device);
318void QBluetoothDeviceDiscoveryAgentPrivate::clearDiscoveryState()
320 m_discoveryRequested =
false;
321 m_pendingStart =
false;
322 m_pendingCancel =
false;
325void QBluetoothDeviceDiscoveryAgentPrivate::emitAsyncError()
327 QMetaObject::invokeMethod(
329 [
this, reportedError = lastError]() {
330 Q_EMIT q_ptr->errorOccurred(reportedError);
332 Qt::QueuedConnection);
std::vector< QBluetoothDeviceInfo > processPairedDevices(const std::vector< QtOhosBluetooth::DiscoveryResult > &pairedDevices)
std::vector< QBluetoothDeviceInfo > processFoundDevices(const std::vector< QtOhosBluetooth::DiscoveryResult > &discoveredDevices)
std::optional< QBluetoothDeviceInfo > tryMakeDeviceInfo(const QtOhosBluetooth::DiscoveryResult &device)
QBluetoothDeviceInfo::Fields updateDeviceInfoIfNeeded(QBluetoothDeviceInfo &existingDevice, const QBluetoothDeviceInfo &newDevice)
QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(lcQIORing)