summaryrefslogtreecommitdiff
path: root/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp')
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp82
1 files changed, 47 insertions, 35 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
index 263e1f13..c02eb5f3 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_winrt.cpp
@@ -231,9 +231,10 @@ class QWinRTBluetoothDeviceDiscoveryWorker : public QObject,
{
Q_OBJECT
public:
- explicit QWinRTBluetoothDeviceDiscoveryWorker();
+ QWinRTBluetoothDeviceDiscoveryWorker(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods,
+ int interval);
~QWinRTBluetoothDeviceDiscoveryWorker();
- void start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods);
+ void start();
void stop();
private:
@@ -243,6 +244,8 @@ private:
int watcherId);
void generateError(QBluetoothDeviceDiscoveryAgent::Error error, const char *msg = nullptr);
void invokeDeviceFoundWithDebug(const QBluetoothDeviceInfo &info);
+ void finishDiscovery();
+ bool isFinished() const;
// Bluetooth Classic handlers
void getClassicDeviceFromId(const winrt::hstring &id);
@@ -263,9 +266,6 @@ private:
Q_INVOKABLE void incrementPendingDevicesCount();
Q_INVOKABLE void decrementPendingDevicesCountAndCheckFinished();
-public slots:
- void finishDiscovery();
-
Q_SIGNALS:
void deviceFound(const QBluetoothDeviceInfo &info);
void deviceDataChanged(const QBluetoothAddress &address, QBluetoothDeviceInfo::Fields,
@@ -282,6 +282,8 @@ private slots:
const ServiceData &serviceData,
const QList<QBluetoothUuid> &uuids);
+ void stopAdvertisementWatcher();
+
private:
struct LEAdvertisingInfo {
QList<QBluetoothUuid> services;
@@ -303,6 +305,7 @@ private:
std::shared_ptr<AdvertisementWatcherWrapper> m_advertisementWatcher;
bool m_classicScanStarted = false;
bool m_lowEnergyScanStarted = false;
+ QTimer *m_leScanTimer = nullptr;
};
static void invokeIncrementPendingDevicesCount(QObject *context)
@@ -316,7 +319,9 @@ static void invokeDecrementPendingDevicesCountAndCheckFinished(QObject *context)
Qt::QueuedConnection);
}
-QWinRTBluetoothDeviceDiscoveryWorker::QWinRTBluetoothDeviceDiscoveryWorker()
+QWinRTBluetoothDeviceDiscoveryWorker::QWinRTBluetoothDeviceDiscoveryWorker(
+ QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods, int interval)
+ : requestedModes(methods)
{
qRegisterMetaType<QBluetoothDeviceInfo>();
qRegisterMetaType<QBluetoothDeviceInfo::Fields>();
@@ -328,6 +333,18 @@ QWinRTBluetoothDeviceDiscoveryWorker::QWinRTBluetoothDeviceDiscoveryWorker()
const auto leSelector = BluetoothLEDevice::GetDeviceSelectorFromPairingState(true);
m_lowEnergyWatcher = createDeviceWatcher(leSelector, LowEnergyWatcherId);
m_advertisementWatcher = createAdvertisementWatcher();
+
+ // Docs claim that a negative interval means that the backend handles it on its own
+ if (interval < 0)
+ interval = 40000;
+
+ if (interval != 0) {
+ m_leScanTimer = new QTimer(this);
+ m_leScanTimer->setSingleShot(true);
+ m_leScanTimer->setInterval(interval);
+ connect(m_leScanTimer, &QTimer::timeout, this,
+ &QWinRTBluetoothDeviceDiscoveryWorker::stopAdvertisementWatcher);
+ }
}
QWinRTBluetoothDeviceDiscoveryWorker::~QWinRTBluetoothDeviceDiscoveryWorker()
@@ -335,10 +352,8 @@ QWinRTBluetoothDeviceDiscoveryWorker::~QWinRTBluetoothDeviceDiscoveryWorker()
stop();
}
-void QWinRTBluetoothDeviceDiscoveryWorker::start(QBluetoothDeviceDiscoveryAgent::DiscoveryMethods methods)
+void QWinRTBluetoothDeviceDiscoveryWorker::start()
{
- requestedModes = methods;
-
if (requestedModes & QBluetoothDeviceDiscoveryAgent::ClassicMethod) {
if (m_classicWatcher && m_classicWatcher->init()) {
m_classicWatcher->start();
@@ -359,6 +374,8 @@ void QWinRTBluetoothDeviceDiscoveryWorker::start(QBluetoothDeviceDiscoveryAgent:
if (m_advertisementWatcher) {
m_advertisementWatcher->init();
m_advertisementWatcher->start();
+ if (m_leScanTimer)
+ m_leScanTimer->start();
} else {
generateError(QBluetoothDeviceDiscoveryAgent::Error::UnknownError,
"Could not start low energy advertisement watcher");
@@ -381,6 +398,14 @@ void QWinRTBluetoothDeviceDiscoveryWorker::finishDiscovery()
emit scanFinished();
}
+bool QWinRTBluetoothDeviceDiscoveryWorker::isFinished() const
+{
+ // If the interval is set to 0, we do not start a timer, and that means
+ // that we need to wait for the user to explicitly call stop()
+ return (m_pendingDevices == 0) && !m_lowEnergyScanStarted && !m_classicScanStarted
+ && (m_leScanTimer && !m_leScanTimer->isActive());
+}
+
void QWinRTBluetoothDeviceDiscoveryWorker::onBluetoothDeviceFound(winrt::hstring deviceId, int watcherId)
{
if (watcherId == ClassicWatcherId)
@@ -400,11 +425,8 @@ void QWinRTBluetoothDeviceDiscoveryWorker::onDeviceEnumerationCompleted(int watc
m_lowEnergyWatcher->stop();
m_lowEnergyScanStarted = false;
}
- // TODO - probably reconsider this condition later
- if (!m_lowEnergyScanStarted && !m_classicScanStarted && !m_pendingDevices
- && !(requestedModes & QBluetoothDeviceDiscoveryAgent::LowEnergyMethod)) {
+ if (isFinished())
finishDiscovery();
- }
}
// this function executes in main worker thread
@@ -480,6 +502,13 @@ void QWinRTBluetoothDeviceDiscoveryWorker::onAdvertisementDataReceived(
});
}
+void QWinRTBluetoothDeviceDiscoveryWorker::stopAdvertisementWatcher()
+{
+ m_advertisementWatcher->stop();
+ if (isFinished())
+ finishDiscovery();
+}
+
std::shared_ptr<QBluetoothDeviceWatcherWinRT>
QWinRTBluetoothDeviceDiscoveryWorker::createDeviceWatcher(winrt::hstring selector, int watcherId)
{
@@ -608,10 +637,9 @@ void QWinRTBluetoothDeviceDiscoveryWorker::incrementPendingDevicesCount()
void QWinRTBluetoothDeviceDiscoveryWorker::decrementPendingDevicesCountAndCheckFinished()
{
- if ((--m_pendingDevices == 0) && !m_classicScanStarted && !m_lowEnergyScanStarted
- && !(requestedModes & QBluetoothDeviceDiscoveryAgent::LowEnergyMethod)) {
+ --m_pendingDevices;
+ if (isFinished())
finishDiscovery();
- }
}
// this function executes in main worker thread
@@ -764,7 +792,8 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent
if (worker)
return;
- worker = std::make_shared<QWinRTBluetoothDeviceDiscoveryWorker>();
+ worker = std::make_shared<QWinRTBluetoothDeviceDiscoveryWorker>(methods,
+ lowEnergySearchTimeout);
discoveredDevices.clear();
connect(worker.get(), &QWinRTBluetoothDeviceDiscoveryWorker::deviceFound,
this, &QBluetoothDeviceDiscoveryAgentPrivate::registerDevice);
@@ -774,18 +803,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start(QBluetoothDeviceDiscoveryAgent
this, &QBluetoothDeviceDiscoveryAgentPrivate::onErrorOccured);
connect(worker.get(), &QWinRTBluetoothDeviceDiscoveryWorker::scanFinished,
this, &QBluetoothDeviceDiscoveryAgentPrivate::onScanFinished);
- worker->start(methods);
-
- if (lowEnergySearchTimeout > 0 && methods & QBluetoothDeviceDiscoveryAgent::LowEnergyMethod) { // otherwise no timeout and stop() required
- if (!leScanTimer) {
- leScanTimer = new QTimer(this);
- leScanTimer->setSingleShot(true);
- }
- connect(leScanTimer, &QTimer::timeout,
- worker.get(), &QWinRTBluetoothDeviceDiscoveryWorker::finishDiscovery);
- leScanTimer->setInterval(lowEnergySearchTimeout);
- leScanTimer->start();
- }
+ worker->start();
}
void QBluetoothDeviceDiscoveryAgentPrivate::stop()
@@ -796,8 +814,6 @@ void QBluetoothDeviceDiscoveryAgentPrivate::stop()
disconnectAndClearWorker();
emit q->canceled();
}
- if (leScanTimer)
- leScanTimer->stop();
}
void QBluetoothDeviceDiscoveryAgentPrivate::registerDevice(const QBluetoothDeviceInfo &info)
@@ -879,10 +895,6 @@ void QBluetoothDeviceDiscoveryAgentPrivate::disconnectAndClearWorker()
this, &QBluetoothDeviceDiscoveryAgentPrivate::updateDeviceData);
disconnect(worker.get(), &QWinRTBluetoothDeviceDiscoveryWorker::errorOccured,
this, &QBluetoothDeviceDiscoveryAgentPrivate::onErrorOccured);
- if (leScanTimer) {
- disconnect(leScanTimer, &QTimer::timeout,
- worker.get(), &QWinRTBluetoothDeviceDiscoveryWorker::finishDiscovery);
- }
worker = nullptr;
}