summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorOleksandr Matasov <ast.or.maar@gmail.com>2013-11-11 15:10:02 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-11-12 13:11:54 +0100
commitaf030bfbf86d807bed9511326699c82ccc9d9adb (patch)
treedbf5b0ca440540fe57eea0b571e460273537a53b
parenta096dfe555762ed4cee747c99c274bd8d912fe66 (diff)
Added new API for device "connected" status
The feature allows to know whether QBluetoothLocalDevice is currently connected to any other device using connectedDevices() method. Change-Id: I4d1a19ebb0b42efd1fc5d5f0f9e7816aa956fbf4 Reviewed-by: Fabian Bumberger <fbumberger@rim.com> Reviewed-by: Alex Blasche <alexander.blasche@digia.com> Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
-rw-r--r--src/bluetooth/qbluetoothlocaldevice.cpp21
-rw-r--r--src/bluetooth/qbluetoothlocaldevice.h3
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_bluez.cpp118
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_p.cpp5
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_p.h15
-rw-r--r--src/bluetooth/qbluetoothlocaldevice_qnx.cpp6
6 files changed, 167 insertions, 1 deletions
diff --git a/src/bluetooth/qbluetoothlocaldevice.cpp b/src/bluetooth/qbluetoothlocaldevice.cpp
index 9661adcb..fa9057a1 100644
--- a/src/bluetooth/qbluetoothlocaldevice.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice.cpp
@@ -188,6 +188,27 @@ bool QBluetoothLocalDevice::isValid() const
*/
/*!
+ \fn void QBluetoothLocalDevice::deviceConnected(const QBluetoothAddress &address)
+ \since 5.3
+
+ A device with \a address is connected with this device.
+*/
+
+/*!
+ \fn void QBluetoothLocalDevice::deviceDisconnected(const QBluetoothAddress &address)
+ \since 5.3
+
+ A device with \a address is disconnected from this device.
+*/
+
+/*!
+ \fn QList<QBluetoothAddress> connectedDevices() const
+ \since 5.3
+
+ Returns the list of connected devices.
+*/
+
+/*!
\fn QBluetoothLocalDevice::pairingStatus(const QBluetoothAddress &address) const
Returns the current bluetooth pairing status of \a address, if it's unpaired, paired, or paired and authorized.
diff --git a/src/bluetooth/qbluetoothlocaldevice.h b/src/bluetooth/qbluetoothlocaldevice.h
index 713b5037..33010e9c 100644
--- a/src/bluetooth/qbluetoothlocaldevice.h
+++ b/src/bluetooth/qbluetoothlocaldevice.h
@@ -91,6 +91,7 @@ public:
void setHostMode(QBluetoothLocalDevice::HostMode mode);
HostMode hostMode() const;
+ QList<QBluetoothAddress> connectedDevices() const;
void powerOn();
@@ -104,6 +105,8 @@ public Q_SLOTS:
Q_SIGNALS:
void hostModeStateChanged(QBluetoothLocalDevice::HostMode state);
+ void deviceConnected(const QBluetoothAddress &address) const;
+ void deviceDisconnected(const QBluetoothAddress &address) const;
void pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing);
void pairingDisplayPinCode(const QBluetoothAddress &address, QString pin);
diff --git a/src/bluetooth/qbluetoothlocaldevice_bluez.cpp b/src/bluetooth/qbluetoothlocaldevice_bluez.cpp
index 62df930a..846639fc 100644
--- a/src/bluetooth/qbluetoothlocaldevice_bluez.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_bluez.cpp
@@ -55,6 +55,11 @@ QT_BEGIN_NAMESPACE
static const QLatin1String agentPath("/qt/agent");
+inline uint qHash(const QBluetoothAddress &address)
+{
+ return ::qHash(address.toUInt64());
+}
+
QBluetoothLocalDevice::QBluetoothLocalDevice(QObject *parent) :
QObject(parent), d_ptr(new QBluetoothLocalDevicePrivate(this))
{
@@ -155,6 +160,11 @@ QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const
return HostPoweredOff;
}
+QList<QBluetoothAddress> QBluetoothLocalDevice::connectedDevices() const
+{
+ return d_ptr->connectedDevices();
+}
+
QList<QBluetoothHostInfo> QBluetoothLocalDevice::allDevices()
{
QList<QBluetoothHostInfo> localDevices;
@@ -335,9 +345,17 @@ 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), localAddress(address), pendingHostModeChange(-1), msgConnection(0), q_ptr(q), connectedCached(false)
{
initializeAdapter();
+ connectDeviceChanges();
+}
+
+void QBluetoothLocalDevicePrivate::connectDeviceChanges()
+{
+ connect(adapter, SIGNAL(PropertyChanged(QString,QDBusVariant)), SLOT(PropertyChanged(QString,QDBusVariant)));
+ connect(adapter, SIGNAL(DeviceCreated(QDBusObjectPath)), SLOT(_q_deviceCreated(QDBusObjectPath)));
+ connect(adapter, SIGNAL(DeviceRemoved(QDBusObjectPath)), SLOT(_q_deviceRemoved(QDBusObjectPath)));
}
QBluetoothLocalDevicePrivate::~QBluetoothLocalDevicePrivate()
@@ -345,6 +363,7 @@ QBluetoothLocalDevicePrivate::~QBluetoothLocalDevicePrivate()
delete msgConnection;
delete adapter;
delete agent;
+ qDeleteAll(devices);
}
void QBluetoothLocalDevicePrivate::initializeAdapter()
@@ -412,6 +431,103 @@ void QBluetoothLocalDevicePrivate::RequestConfirmation(const QDBusObjectPath &in
return;
}
+void QBluetoothLocalDevicePrivate::_q_deviceCreated(const QDBusObjectPath &device)
+{
+ OrgBluezDeviceInterface *deviceInterface =
+ new OrgBluezDeviceInterface(QLatin1String("org.bluez"), device.path(), QDBusConnection::systemBus());
+ connect(deviceInterface, SIGNAL(PropertyChanged(QString,QDBusVariant)), SLOT(_q_devicePropertyChanged(QString,QDBusVariant)));
+ devices << deviceInterface;
+ QDBusPendingReply<QVariantMap> properties = deviceInterface->asyncCall(QLatin1String("GetProperties"));
+
+ properties.waitForFinished();
+ if (!properties.isValid()) {
+ qCritical() << "Unable to get device properties from: " << device.path();
+ return;
+ }
+ const QBluetoothAddress address = QBluetoothAddress(properties.value().value(QLatin1String("Address")).toString());
+ const bool connected = properties.value().value(QLatin1String("Connected")).toBool();
+
+ if (connectedCached) {
+ if (connected)
+ connectedDevicesSet.insert(address);
+ else
+ connectedDevicesSet.remove(address);
+ }
+ if (connected)
+ emit q_ptr->deviceConnected(address);
+ else
+ emit q_ptr->deviceDisconnected(address);
+}
+
+void QBluetoothLocalDevicePrivate::_q_deviceRemoved(const QDBusObjectPath &device)
+{
+ foreach (OrgBluezDeviceInterface *deviceInterface, devices) {
+ if (deviceInterface->path() == device.path()) {
+ devices.remove(deviceInterface);
+ delete deviceInterface; //deviceDisconnected is already emitted by _q_devicePropertyChanged
+ break;
+ }
+ }
+}
+
+void QBluetoothLocalDevicePrivate::_q_devicePropertyChanged(const QString &property, const QDBusVariant &value)
+{
+ OrgBluezDeviceInterface *deviceInterface = qobject_cast<OrgBluezDeviceInterface*>(sender());
+ if (deviceInterface && property == QLatin1String("Connected")) {
+ QDBusPendingReply<QVariantMap> propertiesReply = deviceInterface->GetProperties();
+ propertiesReply.waitForFinished();
+ if (propertiesReply.isError()) {
+ qWarning() << propertiesReply.error().message();
+ return;
+ }
+ const QVariantMap properties = propertiesReply.value();
+ const QBluetoothAddress address = QBluetoothAddress(properties.value(QLatin1String("Address")).toString());
+ const bool connected = value.variant().toBool();
+
+ if (connectedCached) {
+ if (connected)
+ connectedDevicesSet.insert(address);
+ else
+ connectedDevicesSet.remove(address);
+ }
+ if (connected)
+ emit q_ptr->deviceConnected(address);
+ else
+ emit q_ptr->deviceDisconnected(address);
+ }
+}
+
+void QBluetoothLocalDevicePrivate::createCache()
+{
+ QDBusPendingReply<QList<QDBusObjectPath> > reply = adapter->ListDevices();
+ reply.waitForFinished();
+ if (reply.isError()) {
+ qWarning() << reply.error().message();
+ return;
+ }
+ foreach (const QDBusObjectPath &device, reply.value()) {
+ OrgBluezDeviceInterface deviceInterface(QLatin1String("org.bluez"), device.path(), QDBusConnection::systemBus());
+
+ QDBusPendingReply<QVariantMap> properties = deviceInterface.asyncCall(QLatin1String("GetProperties"));
+ properties.waitForFinished();
+ if (!properties.isValid()) {
+ qWarning() << "Unable to get properties for device " << device.path();
+ return;
+ }
+
+ if (properties.value().value(QLatin1String("Connected")).toBool())
+ connectedDevicesSet.insert(QBluetoothAddress(properties.value().value(QLatin1String("Address")).toString()));
+ }
+ connectedCached = true;
+}
+
+QList<QBluetoothAddress> QBluetoothLocalDevicePrivate::connectedDevices() const
+{
+ if (!connectedCached)
+ const_cast<QBluetoothLocalDevicePrivate *>(this)->createCache();
+ return connectedDevicesSet.toList();
+}
+
void QBluetoothLocalDevice::pairingConfirmation(bool confirmation)
{
if(!d_ptr ||
diff --git a/src/bluetooth/qbluetoothlocaldevice_p.cpp b/src/bluetooth/qbluetoothlocaldevice_p.cpp
index 411863cb..d40e6473 100644
--- a/src/bluetooth/qbluetoothlocaldevice_p.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_p.cpp
@@ -79,6 +79,11 @@ QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const
return HostPoweredOff;
}
+QList<QBluetoothAddress> QBluetoothLocalDevice::connectedDevices() const
+{
+ return QList<QBluetoothAddress>();
+}
+
QList<QBluetoothHostInfo> QBluetoothLocalDevice::allDevices()
{
QList<QBluetoothHostInfo> localDevices;
diff --git a/src/bluetooth/qbluetoothlocaldevice_p.h b/src/bluetooth/qbluetoothlocaldevice_p.h
index 0f2aaca8..7d5ed926 100644
--- a/src/bluetooth/qbluetoothlocaldevice_p.h
+++ b/src/bluetooth/qbluetoothlocaldevice_p.h
@@ -51,9 +51,11 @@
#include <QDBusContext>
#include <QDBusObjectPath>
#include <QDBusMessage>
+#include <QSet>
class OrgBluezAdapterInterface;
class OrgBluezAgentAdaptor;
+class OrgBluezDeviceInterface;
QT_BEGIN_NAMESPACE
class QDBusPendingCallWatcher;
@@ -78,8 +80,13 @@ public:
QBluetoothLocalDevicePrivate(QBluetoothLocalDevice *q, QBluetoothAddress localAddress = QBluetoothAddress());
~QBluetoothLocalDevicePrivate();
+ QSet<OrgBluezDeviceInterface *> devices;
+ QSet<QBluetoothAddress> connectedDevicesSet;
OrgBluezAdapterInterface *adapter;
OrgBluezAgentAdaptor *agent;
+
+ QList<QBluetoothAddress> connectedDevices() const;
+
QString agent_path;
QBluetoothAddress localAddress;
QBluetoothAddress address;
@@ -101,14 +108,22 @@ public Q_SLOTS: // METHODS
void pairingCompleted(QDBusPendingCallWatcher*);
void PropertyChanged(QString,QDBusVariant);
+ void _q_deviceCreated(const QDBusObjectPath &device);
+ void _q_deviceRemoved(const QDBusObjectPath &device);
+ void _q_devicePropertyChanged(const QString &property, const QDBusVariant &value);
bool isValid() const;
private:
+ void createCache();
+ void connectDeviceChanges();
+
QDBusMessage msgConfirmation;
QDBusConnection *msgConnection;
QBluetoothLocalDevice *q_ptr;
+ bool connectedCached;
+
void initializeAdapter();
};
diff --git a/src/bluetooth/qbluetoothlocaldevice_qnx.cpp b/src/bluetooth/qbluetoothlocaldevice_qnx.cpp
index 780639f6..d1460b6a 100644
--- a/src/bluetooth/qbluetoothlocaldevice_qnx.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice_qnx.cpp
@@ -93,6 +93,12 @@ QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const
return this->d_ptr->hostMode();
}
+QList<QBluetoothAddress> QBluetoothLocalDevice::connectedDevices() const
+{
+ qWarning() << Q_FUNC_INFO << " is not implemented for QNX backend yet.";
+ return QList<QBluetoothAddress>(); //TODO: implement
+}
+
QList<QBluetoothHostInfo> QBluetoothLocalDevice::allDevices()
{
//We only have one device