diff options
-rw-r--r-- | src/bluetooth/qbluetoothlocaldevice.cpp | 10 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothlocaldevice_bluez.cpp | 56 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothlocaldevice_p.h | 3 |
3 files changed, 62 insertions, 7 deletions
diff --git a/src/bluetooth/qbluetoothlocaldevice.cpp b/src/bluetooth/qbluetoothlocaldevice.cpp index 14140846..6560e135 100644 --- a/src/bluetooth/qbluetoothlocaldevice.cpp +++ b/src/bluetooth/qbluetoothlocaldevice.cpp @@ -125,8 +125,16 @@ QBluetoothLocalDevice::~QBluetoothLocalDevice() } /*! - Returns true if the QBluetoothLocalDevice represents an available local Bluetooth device; + Returns \c true if the QBluetoothLocalDevice represents an available local Bluetooth device; otherwise return false. + + If the local Bluetooth adapter represented by an instance of this class + is removed from the system (e.g. removal of the underlying Bluetooth dongle) + then this instance will become invalid. An already invalid QBluetoothLocalDevice instance + remains invalid even if the same Bluetooth adapter is returned to + the system. + + \sa allDevices() */ bool QBluetoothLocalDevice::isValid() const { diff --git a/src/bluetooth/qbluetoothlocaldevice_bluez.cpp b/src/bluetooth/qbluetoothlocaldevice_bluez.cpp index ac694f34..d2c8ac1d 100644 --- a/src/bluetooth/qbluetoothlocaldevice_bluez.cpp +++ b/src/bluetooth/qbluetoothlocaldevice_bluez.cpp @@ -218,7 +218,7 @@ static inline OrgBluezDeviceInterface *getDevice(const QBluetoothAddress &addres void QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pairing pairing) { - if (address.isNull()) { + if (!isValid() || address.isNull()) { QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection, Q_ARG(QBluetoothLocalDevice::Error, QBluetoothLocalDevice::PairingError)); return; @@ -347,7 +347,8 @@ QBluetoothLocalDevice::Pairing QBluetoothLocalDevice::pairingStatus(const QBluet } QBluetoothLocalDevicePrivate::QBluetoothLocalDevicePrivate(QBluetoothLocalDevice *q, QBluetoothAddress address) - : adapter(0), agent(0), localAddress(address), pendingHostModeChange(-1), msgConnection(0), q_ptr(q) + : adapter(0), agent(0), manager(0), + localAddress(address), pendingHostModeChange(-1), msgConnection(0), q_ptr(q) { initializeAdapter(); connectDeviceChanges(); @@ -368,6 +369,7 @@ QBluetoothLocalDevicePrivate::~QBluetoothLocalDevicePrivate() delete msgConnection; delete adapter; delete agent; + delete manager; qDeleteAll(devices); } @@ -376,17 +378,19 @@ void QBluetoothLocalDevicePrivate::initializeAdapter() if (adapter) return; - OrgBluezManagerInterface manager(QLatin1String("org.bluez"), QLatin1String("/"), QDBusConnection::systemBus()); + QScopedPointer<OrgBluezManagerInterface> man(new OrgBluezManagerInterface( + QStringLiteral("org.bluez"), QStringLiteral("/"), + QDBusConnection::systemBus())); if (localAddress == QBluetoothAddress()) { - QDBusPendingReply<QDBusObjectPath> reply = manager.DefaultAdapter(); + QDBusPendingReply<QDBusObjectPath> reply = man->DefaultAdapter(); reply.waitForFinished(); if (reply.isError()) return; adapter = new OrgBluezAdapterInterface(QLatin1String("org.bluez"), reply.value().path(), QDBusConnection::systemBus()); } else { - QDBusPendingReply<QList<QDBusObjectPath> > reply = manager.ListAdapters(); + QDBusPendingReply<QList<QDBusObjectPath> > reply = man->ListAdapters(); reply.waitForFinished(); if (reply.isError()) return; @@ -396,8 +400,10 @@ void QBluetoothLocalDevicePrivate::initializeAdapter() QDBusPendingReply<QVariantMap> reply = tmpAdapter->GetProperties(); reply.waitForFinished(); - if (reply.isError()) + if (reply.isError()) { + delete tmpAdapter; continue; + } QBluetoothAddress path_address(reply.value().value(QLatin1String("Address")).toString()); @@ -410,6 +416,11 @@ void QBluetoothLocalDevicePrivate::initializeAdapter() } } + // monitor case when local adapter is removed + manager = man.take(); + connect(manager, SIGNAL(AdapterRemoved(QDBusObjectPath)), + this, SLOT(adapterRemoved(QDBusObjectPath))); + currentMode = static_cast<QBluetoothLocalDevice::HostMode>(-1); if (adapter) { connect(adapter, SIGNAL(PropertyChanged(QString,QDBusVariant)), SLOT(PropertyChanged(QString,QDBusVariant))); @@ -425,6 +436,39 @@ bool QBluetoothLocalDevicePrivate::isValid() const return adapter; } +// Bluez 4 +void QBluetoothLocalDevicePrivate::adapterRemoved(const QDBusObjectPath &devicePath) +{ + if (!adapter ) + return; + + if (adapter->path() != devicePath.path()) + return; + + qCDebug(QT_BT_BLUEZ) << "Adapter" << devicePath.path() + << "was removed. Invalidating object."; + // the current adapter was removed + delete adapter; + adapter = 0; + manager->deleteLater(); + manager = 0; + + // stop all pairing related activities + if (agent) { + QDBusConnection::systemBus().unregisterObject(agent_path); + delete agent; + agent = 0; + } + + delete msgConnection; + msgConnection = 0; + + // stop all connectivity monitoring + qDeleteAll(devices); + devices.clear(); + connectedDevicesSet.clear(); +} + void QBluetoothLocalDevicePrivate::RequestConfirmation(const QDBusObjectPath &in0, uint in1) { Q_UNUSED(in0); diff --git a/src/bluetooth/qbluetoothlocaldevice_p.h b/src/bluetooth/qbluetoothlocaldevice_p.h index f00c33bf..66eb366c 100644 --- a/src/bluetooth/qbluetoothlocaldevice_p.h +++ b/src/bluetooth/qbluetoothlocaldevice_p.h @@ -56,6 +56,7 @@ class OrgBluezAdapterInterface; class OrgBluezAgentAdaptor; class OrgBluezDeviceInterface; +class OrgBluezManagerInterface; QT_BEGIN_NAMESPACE class QDBusPendingCallWatcher; @@ -130,6 +131,7 @@ public: QSet<QBluetoothAddress> connectedDevicesSet; OrgBluezAdapterInterface *adapter; OrgBluezAgentAdaptor *agent; + OrgBluezManagerInterface *manager; QList<QBluetoothAddress> connectedDevices() const; @@ -158,6 +160,7 @@ public Q_SLOTS: // METHODS void _q_deviceRemoved(const QDBusObjectPath &device); void _q_devicePropertyChanged(const QString &property, const QDBusVariant &value); bool isValid() const; + void adapterRemoved(const QDBusObjectPath &device); private: void createCache(); |