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 \class RemoteDeviceManager
19 \inmodule QtBluetooth
20 \internal
21
22 Convenience wrapper around org.bluez.Device1 management.
23 Very simple and not thread safe.
24*/
25RemoteDeviceManager::RemoteDeviceManager(
26 const QBluetoothAddress &address, QObject *parent)
27 : QObject(parent), localAddress(address)
28{
29 initializeBluez5();
30
31 bool ok = false;
32 adapterPath = findAdapterForAddress(address, &ok);
33 if (!ok || adapterPath.isEmpty()) {
34 qCWarning(QT_BT_BLUEZ) << "Cannot initialize RemoteDeviceManager";
35 }
36}
37
38bool RemoteDeviceManager::scheduleJob(JobType job, const QList<QBluetoothAddress> &remoteDevices)
39{
40 if (adapterPath.isEmpty())
41 return false;
42
43 for (const auto& remote : remoteDevices)
44 jobQueue.push_back(std::make_pair(job, remote));
45
46 QTimer::singleShot(0, this, [this](){ runQueue(); });
47 return true;
48}
49
50void RemoteDeviceManager::runQueue()
51{
52 if (jobInProgress || adapterPath.isEmpty())
53 return;
54
55 if (jobQueue.empty())
56 return;
57
58 jobInProgress = true;
59 switch (jobQueue.front().first) {
60 case JobType::JobDisconnectDevice:
61 disconnectDevice(jobQueue.front().second);
62 break;
63 default:
64 break;
65 }
66}
67
68void RemoteDeviceManager::prepareNextJob()
69{
70 Q_ASSERT(!jobQueue.empty());
71
72 jobQueue.pop_front();
73 jobInProgress = false;
74
75 qCDebug(QT_BT_BLUEZ) << "RemoteDeviceManager job queue status:" << jobQueue.empty();
76 if (jobQueue.empty())
77 emit finished();
78 else
79 runQueue();
80}
81
82void RemoteDeviceManager::disconnectDevice(const QBluetoothAddress &remote)
83{
84 // collect initial set of information
85 OrgFreedesktopDBusObjectManagerInterface managerBluez5(
86 QStringLiteral("org.bluez"),
87 QStringLiteral("/"),
88 QDBusConnection::systemBus(), this);
89 QDBusPendingReply<ManagedObjectList> reply = managerBluez5.GetManagedObjects();
90 reply.waitForFinished();
91 if (reply.isError()) {
92 QTimer::singleShot(0, this, [this](){ prepareNextJob(); });
93 return;
94 }
95
96 bool jobStarted = false;
97 ManagedObjectList managedObjectList = reply.value();
98 for (auto it = managedObjectList.constBegin(); it != managedObjectList.constEnd(); ++it) {
99 const QDBusObjectPath &path = it.key();
100 const InterfaceList &ifaceList = it.value();
101
102 for (auto jt = ifaceList.constBegin(); jt != ifaceList.constEnd(); ++jt) {
103 const QString &iface = jt.key();
104
105 if (path.path().indexOf(adapterPath) != 0)
106 continue; //devices whose path doesn't start with same path we skip
107
108 if (iface != QStringLiteral("org.bluez.Device1"))
109 continue;
110
111 const QBluetoothAddress foundAddress(ifaceList.value(iface).value(QStringLiteral("Address")).toString());
112 if (foundAddress != remote)
113 continue;
114
115 // found the correct Device1 path
116 OrgBluezDevice1Interface* device1 = new OrgBluezDevice1Interface(QStringLiteral("org.bluez"),
117 path.path(),
118 QDBusConnection::systemBus(),
119 this);
120 QDBusPendingReply<> asyncReply = device1->Disconnect();
121 QDBusPendingCallWatcher* watcher = new QDBusPendingCallWatcher(asyncReply, this);
122 const auto watcherFinished = [this, device1](QDBusPendingCallWatcher* call) {
123 call->deleteLater();
124 device1->deleteLater();
125 prepareNextJob();
126 };
127 connect(watcher, &QDBusPendingCallWatcher::finished, this, watcherFinished);
128 jobStarted = true;
129 break;
130 }
131 }
132
133 if (!jobStarted) {
134 qCDebug(QT_BT_BLUEZ) << "RemoteDeviceManager JobDisconnectDevice failed";
135 QTimer::singleShot(0, this, [this](){ prepareNextJob(); });
136 }
137}
138
139QT_END_NAMESPACE
140
141#include "moc_remotedevicemanager_p.cpp"
QMap< QDBusObjectPath, InterfaceList > ManagedObjectList