summaryrefslogtreecommitdiffstats
path: root/src/bluetoothsettings/bluez
diff options
context:
space:
mode:
authorTeemu Holappa <teemu.holappa@qt.io>2017-02-27 10:24:53 +0200
committerTeemu Holappa <teemu.holappa@qt.io>2017-05-03 06:32:17 +0000
commit48fb704e64300387f99c4192436728858c8aa4f8 (patch)
tree1891c25100a6cdf0f1260c0c5ca1f469887828c8 /src/bluetoothsettings/bluez
parent314de829065a3fa411b8fed90ff1289b000e229b (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.cpp219
-rw-r--r--src/bluetoothsettings/bluez/bluetoothdevice_p.h46
-rw-r--r--src/bluetoothsettings/bluez/bluez.pri4
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