diff options
author | Teemu Holappa <teemu.holappa@qt.io> | 2017-02-27 10:24:53 +0200 |
---|---|---|
committer | Teemu Holappa <teemu.holappa@qt.io> | 2017-05-03 06:32:17 +0000 |
commit | 48fb704e64300387f99c4192436728858c8aa4f8 (patch) | |
tree | 1891c25100a6cdf0f1260c0c5ca1f469887828c8 /src/bluetoothsettings/bluez | |
parent | 314de829065a3fa411b8fed90ff1289b000e229b (diff) |
Fix issue when no Bluetooth device is available
Added async scan of the bluetooth adapter.
Done some cleanup to the public class.
Task-number: QTBUG-57676
Change-Id: Ia845f2f8c18fb8272160167482e5124c0b43fee7
Reviewed-by: Mikko Gronoff <mikko.gronoff@qt.io>
Reviewed-by: Samuli Piippo <samuli.piippo@qt.io>
Diffstat (limited to 'src/bluetoothsettings/bluez')
-rw-r--r-- | src/bluetoothsettings/bluez/bluetoothdevice_p.cpp | 219 | ||||
-rw-r--r-- | src/bluetoothsettings/bluez/bluetoothdevice_p.h | 46 | ||||
-rw-r--r-- | src/bluetoothsettings/bluez/bluez.pri | 4 |
3 files changed, 235 insertions, 34 deletions
diff --git a/src/bluetoothsettings/bluez/bluetoothdevice_p.cpp b/src/bluetoothsettings/bluez/bluetoothdevice_p.cpp index d5e6288..28ed605 100644 --- a/src/bluetoothsettings/bluez/bluetoothdevice_p.cpp +++ b/src/bluetoothsettings/bluez/bluetoothdevice_p.cpp @@ -26,26 +26,209 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ +#include "discoverymodel.h" #include "bluetoothdevice_p.h" #include "datatypes.h" #include "objectmanager_interface.cpp" #include "moc_objectmanager_interface.cpp" #include "device1_interface.h" +BluetoothDevicePrivate::BluetoothDevicePrivate(BluetoothDevice *parent) : QObject(parent) + ,q_ptr(parent) + ,m_localDevice(Q_NULLPTR) + ,m_powered(false) + ,m_scanning(false) + ,m_adapter(QStringLiteral("")) + ,m_deviceModel(new DiscoveryModel(this)) +{ + qDBusRegisterMetaType<InterfaceList>(); + qDBusRegisterMetaType<ManagedObjectList>(); + + m_manager = new OrgFreedesktopDBusObjectManagerInterface(QStringLiteral("org.bluez"), + QStringLiteral("/"), + QDBusConnection::systemBus(), this); + QDBusPendingReply<ManagedObjectList> reply = m_manager->GetManagedObjects(); + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, &QDBusPendingCallWatcher::finished, + this, &BluetoothDevicePrivate::getManagedObjectsFinished, Qt::QueuedConnection); +} -BluetoothDevicePrivate::BluetoothDevicePrivate(const QString& address, QObject *parent) - :QObject(parent) - ,m_address(address) +void BluetoothDevicePrivate::deviceStateChanged(QBluetoothLocalDevice::HostMode state) { + Q_Q(BluetoothDevice); + m_powered = state != QBluetoothLocalDevice::HostPoweredOff; + emit q->poweredChanged(); +} +bool BluetoothDevicePrivate::powered() const +{ + return m_powered; } -OrgBluezDevice1Interface* BluetoothDevicePrivate::findDevice() +void BluetoothDevicePrivate::setPowered(const bool& aPowered) { - OrgFreedesktopDBusObjectManagerInterface manager(QStringLiteral("org.bluez"), - QStringLiteral("/"), - QDBusConnection::systemBus()); - QDBusPendingReply<ManagedObjectList> reply = manager.GetManagedObjects(); + if (aPowered) { + m_localDevice->powerOn(); + } + else { + m_localDevice->setHostMode(QBluetoothLocalDevice::HostPoweredOff); + } +} + +DiscoveryModel* BluetoothDevicePrivate::deviceModel() const +{ + return m_deviceModel; +} + +void BluetoothDevicePrivate::scanFinished() +{ + Q_Q(BluetoothDevice); + m_scanning = false; + emit q->scanningChanged(); + updateConnectionStatuses(); +} + +bool BluetoothDevicePrivate::scanning() const +{ + return m_scanning; +} + +void BluetoothDevicePrivate::setScanning(const bool& aScan) +{ + Q_Q(BluetoothDevice); + if (m_scanning && !aScan) { + m_deviceModel->stopScanning(); + } + else if (aScan && !m_scanning) { + m_deviceModel->scanDevices(); + } + m_scanning = aScan; + emit q->scanningChanged(); +} + +bool BluetoothDevicePrivate::available() const +{ + return (!m_adapter.isEmpty()); +} + +void BluetoothDevicePrivate::updateConnectionStatuses() +{ + QList<QBluetoothAddress> connectedDevices = + m_localDevice->connectedDevices(); + + foreach (QBluetoothAddress addr, connectedDevices) { + m_deviceModel->setConnected(addr.toString(), true); + } +} + +void BluetoothDevicePrivate::requestPairing(const QString& address) +{ + QBluetoothAddress addr(address); + if (m_localDevice) { + m_localDevice->requestPairing(addr, QBluetoothLocalDevice::Paired); + connect(m_localDevice, &QBluetoothLocalDevice::pairingDisplayConfirmation, this, &BluetoothDevicePrivate::pairingDisplayConfirmation); + + connect(m_localDevice, &QBluetoothLocalDevice::pairingDisplayPinCode, this, &BluetoothDevicePrivate::pairingDisplayPinCode); + + connect(m_localDevice, &QBluetoothLocalDevice::pairingFinished, this, &BluetoothDevicePrivate::pairingFinished); + } +} + +void BluetoothDevicePrivate::requestConnect(const QString &address) +{ + OrgBluezDevice1Interface *dev = findPeerDevice(address); + if (dev) { + dev->Connect(); + dev->deleteLater(); + } +} + +void BluetoothDevicePrivate::requestDisconnect(const QString& address) +{ + OrgBluezDevice1Interface *dev = findPeerDevice(address); + if (dev) { + dev->Disconnect(); + dev->deleteLater(); + } +} + +void BluetoothDevicePrivate::pairingDisplayConfirmation(const QBluetoothAddress & address, QString pin) +{ + Q_UNUSED(address); + Q_UNUSED(pin); +} + +void BluetoothDevicePrivate::pairingDisplayPinCode(const QBluetoothAddress & address, QString pin) +{ + Q_UNUSED(address); + Q_UNUSED(pin); +} + +void BluetoothDevicePrivate::pairingFinished(const QBluetoothAddress & address, QBluetoothLocalDevice::Pairing pairing) +{ + if (pairing == QBluetoothLocalDevice::Paired) { + requestConnect(address.toString()); + } +} + +void BluetoothDevicePrivate::deviceConnected(const QBluetoothAddress & address) +{ + m_deviceModel->setConnected(address.toString(), true); +} + +void BluetoothDevicePrivate::deviceDisconnected(const QBluetoothAddress & address) +{ + m_deviceModel->setConnected(address.toString(), false); +} + +void BluetoothDevicePrivate::getManagedObjectsFinished(QDBusPendingCallWatcher *watcher) +{ + Q_Q(BluetoothDevice); + + QDBusPendingReply<ManagedObjectList> reply = *watcher; + watcher->deleteLater(); + if (reply.isError()) { + return; + } + + //Find adapter + ManagedObjectList managedObjectList = reply.value(); + for (ManagedObjectList::const_iterator it = managedObjectList.constBegin(); it != managedObjectList.constEnd(); ++it) { + const InterfaceList &ifaceList = it.value(); + for (InterfaceList::const_iterator jt = ifaceList.constBegin(); jt != ifaceList.constEnd(); ++jt) { + const QString &iface = jt.key(); + const QVariantMap &ifaceValues = jt.value(); + + if (iface == QStringLiteral("org.bluez.Adapter1")) { + m_adapter = ifaceValues[QStringLiteral("Address")].toString(); + break; + } + } + } + + if (!m_adapter.isEmpty()) { + m_localDevice = new QBluetoothLocalDevice(this); + m_powered = m_localDevice->hostMode() != QBluetoothLocalDevice::HostPoweredOff; + + connect(m_localDevice, &QBluetoothLocalDevice::hostModeStateChanged, this, &BluetoothDevicePrivate::deviceStateChanged); + connect(m_localDevice, &QBluetoothLocalDevice::deviceConnected, this, &BluetoothDevicePrivate::deviceConnected); + connect(m_localDevice, &QBluetoothLocalDevice::deviceDisconnected, this, &BluetoothDevicePrivate::deviceDisconnected); + connect(m_deviceModel, &DiscoveryModel::scanFinished, this, &BluetoothDevicePrivate::scanFinished); + + if (m_powered) { + emit q->poweredChanged(); + m_deviceModel->scanDevices(); + m_scanning = true; + emit q->scanningChanged(); + } + + emit q->availabilityChanged(); + } +} + +OrgBluezDevice1Interface* BluetoothDevicePrivate::findPeerDevice(const QString &address) +{ + QDBusPendingReply<ManagedObjectList> reply = m_manager->GetManagedObjects(); reply.waitForFinished(); if (reply.isError()) { qWarning() << "Failed to get objects"; @@ -61,7 +244,7 @@ OrgBluezDevice1Interface* BluetoothDevicePrivate::findDevice() const QString &iface = jt.key(); const QVariantMap &ifaceValues = jt.value(); if (iface == QStringLiteral("org.bluez.Device1")) { - if (ifaceValues[QStringLiteral("Address")] == m_address) { + if (ifaceValues[QStringLiteral("Address")] == address) { OrgBluezDevice1Interface *devIf = new OrgBluezDevice1Interface(QStringLiteral("org.bluez"), path.path(), QDBusConnection::systemBus()); return devIf; } @@ -70,21 +253,3 @@ OrgBluezDevice1Interface* BluetoothDevicePrivate::findDevice() } return NULL; } - -void BluetoothDevicePrivate::connectDevice() -{ - OrgBluezDevice1Interface *dev = findDevice(); - if (dev) { - dev->Connect(); - dev->deleteLater(); - } -} - -void BluetoothDevicePrivate::disconnectDevice() -{ - OrgBluezDevice1Interface *dev = findDevice(); - if (dev) { - dev->Disconnect(); - dev->deleteLater(); - } -} diff --git a/src/bluetoothsettings/bluez/bluetoothdevice_p.h b/src/bluetoothsettings/bluez/bluetoothdevice_p.h index f6892e3..432a7e7 100644 --- a/src/bluetoothsettings/bluez/bluetoothdevice_p.h +++ b/src/bluetoothsettings/bluez/bluetoothdevice_p.h @@ -41,19 +41,55 @@ // #include <QObject> +#include <QBluetoothLocalDevice> +#include <QtDBus> +#include "bluetoothdevice.h" class OrgBluezDevice1Interface; +class OrgFreedesktopDBusObjectManagerInterface; class BluetoothDevicePrivate : public QObject { + Q_OBJECT + Q_DECLARE_PUBLIC(BluetoothDevice) public: - explicit BluetoothDevicePrivate(const QString& address, QObject *parent = Q_NULLPTR); - void connectDevice(); - void disconnectDevice(); + BluetoothDevice *q_ptr; + BluetoothDevicePrivate(BluetoothDevice *parent); + bool powered() const; + void setPowered(const bool& aPowered); + bool scanning() const; + bool available() const; + void setScanning(const bool& aScan); + void requestPairing(const QString& address); + void requestConnect(const QString& address); + void requestDisconnect(const QString& address); + DiscoveryModel* deviceModel() const; + +public Q_SLOTS: + void deviceStateChanged(QBluetoothLocalDevice::HostMode state); + void scanFinished(); + //These are not yet signaled + //See bug https://bugreports.qt.io/browse/QTBUG-38401 + void pairingDisplayConfirmation(const QBluetoothAddress & address, QString pin); + void pairingDisplayPinCode(const QBluetoothAddress & address, QString pin); + void pairingFinished(const QBluetoothAddress & address, QBluetoothLocalDevice::Pairing pairing); + void deviceConnected(const QBluetoothAddress & address); + void deviceDisconnected(const QBluetoothAddress & address); + void getManagedObjectsFinished(QDBusPendingCallWatcher *watcher); + +private: + void updateConnectionStatuses(); + OrgBluezDevice1Interface* findPeerDevice(const QString& address); private: - OrgBluezDevice1Interface* findDevice(); - QString m_address; + QBluetoothLocalDevice* m_localDevice; + bool m_powered; + bool m_scanning; + QString m_adapter; + DiscoveryModel *m_deviceModel; + OrgFreedesktopDBusObjectManagerInterface *m_manager; }; + + #endif // BLUETOOTHDEVICE__P_H diff --git a/src/bluetoothsettings/bluez/bluez.pri b/src/bluetoothsettings/bluez/bluez.pri index ea4929c..b8d39fd 100644 --- a/src/bluetoothsettings/bluez/bluez.pri +++ b/src/bluetoothsettings/bluez/bluez.pri @@ -5,11 +5,11 @@ INCLUDEPATH += $${PWD}/bluez DBUS_INTERFACES = \ $${PWD}/objectmanager.xml \ - $${PWD}/device1.xml \ + $${PWD}/device1.xml HEADERS += \ $$PWD/bluetoothdevice_p.h \ - $$PWD/datatypes.h + $$PWD/datatypes.h \ SOURCES += \ $$PWD/bluetoothdevice_p.cpp |