Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
remotedevicemanager.cpp
Go to the documentation of this file.
1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include <QtCore/QLoggingCategory>
5
10
11QT_BEGIN_NAMESPACE
12
13Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ)
14
15using namespace QtBluetoothPrivate; // for D-Bus wrappers
16
17/*!
18 * Convenience wrapper around org.bluez.Device1 management
19 *
20 * Very simple and not thread safe.
21 */
22
23RemoteDeviceManager::RemoteDeviceManager(
24 const QBluetoothAddress &address, QObject *parent)
25 : QObject(parent), localAddress(address)
26{
27 initializeBluez5();
28
29 bool ok = false;
30 adapterPath = findAdapterForAddress(address, &ok);
31 if (!ok || adapterPath.isEmpty()) {
32 qCWarning(QT_BT_BLUEZ) << "Cannot initialize RemoteDeviceManager";
33 }
34}
35
36bool RemoteDeviceManager::scheduleJob(JobType job, const QList<QBluetoothAddress> &remoteDevices)
37{
38 if (adapterPath.isEmpty())
39 return false;
40
41 for (const auto& remote : remoteDevices)
42 jobQueue.push_back(std::make_pair(job, remote));
43
44 QTimer::singleShot(0, this, [this](){ runQueue(); });
45 return true;
46}
47
48void RemoteDeviceManager::runQueue()
49{
50 if (jobInProgress || adapterPath.isEmpty())
51 return;
52
53 if (jobQueue.empty())
54 return;
55
56 jobInProgress = true;
57 switch (jobQueue.front().first) {
58 case JobType::JobDisconnectDevice:
59 disconnectDevice(jobQueue.front().second);
60 break;
61 default:
62 break;
63 }
64}
65
66void RemoteDeviceManager::prepareNextJob()
67{
68 Q_ASSERT(!jobQueue.empty());
69
70 jobQueue.pop_front();
71 jobInProgress = false;
72
73 qCDebug(QT_BT_BLUEZ) << "RemoteDeviceManager job queue status:" << jobQueue.empty();
74 if (jobQueue.empty())
75 emit finished();
76 else
77 runQueue();
78}
79
80void RemoteDeviceManager::disconnectDevice(const QBluetoothAddress &remote)
81{
82 // collect initial set of information
83 OrgFreedesktopDBusObjectManagerInterface managerBluez5(
84 QStringLiteral("org.bluez"),
85 QStringLiteral("/"),
86 QDBusConnection::systemBus(), this);
87 QDBusPendingReply<ManagedObjectList> reply = managerBluez5.GetManagedObjects();
88 reply.waitForFinished();
89 if (reply.isError()) {
90 QTimer::singleShot(0, this, [this](){ prepareNextJob(); });
91 return;
92 }
93
94 bool jobStarted = false;
95 ManagedObjectList managedObjectList = reply.value();
96 for (auto it = managedObjectList.constBegin(); it != managedObjectList.constEnd(); ++it) {
97 const QDBusObjectPath &path = it.key();
98 const InterfaceList &ifaceList = it.value();
99
100 for (auto jt = ifaceList.constBegin(); jt != ifaceList.constEnd(); ++jt) {
101 const QString &iface = jt.key();
102
103 if (path.path().indexOf(adapterPath) != 0)
104 continue; //devices whose path doesn't start with same path we skip
105
106 if (iface != QStringLiteral("org.bluez.Device1"))
107 continue;
108
109 const QBluetoothAddress foundAddress(ifaceList.value(iface).value(QStringLiteral("Address")).toString());
110 if (foundAddress != remote)
111 continue;
112
113 // found the correct Device1 path
114 OrgBluezDevice1Interface* device1 = new OrgBluezDevice1Interface(QStringLiteral("org.bluez"),
115 path.path(),
116 QDBusConnection::systemBus(),
117 this);
118 QDBusPendingReply<> asyncReply = device1->Disconnect();
119 QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(asyncReply, this);
120 const auto watcherFinished = [this, device1](QDBusPendingCallWatcher* call) {
121 call->deleteLater();
122 device1->deleteLater();
123 prepareNextJob();
124 };
125 connect(watcher, &QDBusPendingCallWatcher::finished, this, watcherFinished);
126 jobStarted = true;
127 break;
128 }
129 }
130
131 if (!jobStarted) {
132 qCDebug(QT_BT_BLUEZ) << "RemoteDeviceManager JobDisconnectDevice failed";
133 QTimer::singleShot(0, this, [this](){ prepareNextJob(); });
134 }
135}
136
137QT_END_NAMESPACE
138
139#include "moc_remotedevicemanager_p.cpp"
QMap< QDBusObjectPath, InterfaceList > ManagedObjectList