Changeset View
Changeset View
Standalone View
Standalone View
libs/bolt/manager.cpp
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | * Copyright (c) 2018 - 2019 Daniel Vrátil <dvratil@kde.org> | ||||
3 | * | ||||
4 | * This program is free software; you can redistribute it and/or | ||||
5 | * modify it under the terms of the GNU General Public License as | ||||
6 | * published by the Free Software Foundation; either version 2 of | ||||
7 | * the License or (at your option) version 3 or any later version | ||||
8 | * accepted by the membership of KDE e.V. (or its successor approved | ||||
9 | * by the membership of KDE e.V.), which shall act as a proxy | ||||
10 | * defined in Section 14 of version 3 of the license. | ||||
11 | * | ||||
12 | * This program is distributed in the hope that it will be useful, | ||||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
15 | * GNU General Public License for more details. | ||||
16 | * | ||||
17 | * You should have received a copy of the GNU General Public License | ||||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
19 | */ | ||||
20 | | ||||
21 | #include "manager.h" | ||||
22 | #include "device.h" | ||||
23 | #include "managerinterface.h" | ||||
24 | #include "dbushelper.h" | ||||
25 | #include "enum.h" | ||||
26 | #include "libkbolt_debug.h" | ||||
27 | | ||||
28 | using namespace Bolt; | ||||
29 | | ||||
30 | using ManagerInterface = org::freedesktop::bolt1::Manager; | ||||
31 | | ||||
32 | Manager::Manager(QObject *parent) | ||||
33 | : QObject(parent) | ||||
34 | , mInterface(std::make_unique<ManagerInterface>( | ||||
35 | DBusHelper::serviceName(), QStringLiteral("/org/freedesktop/bolt"), | ||||
36 | DBusHelper::connection())) | ||||
37 | { | ||||
38 | if (!mInterface->isValid()) { | ||||
39 | qCWarning(log_libkbolt, "Failed to connect to Bolt manager DBus interface: %s", | ||||
40 | qUtf8Printable(mInterface->lastError().message())); | ||||
41 | return; | ||||
42 | } | ||||
43 | | ||||
44 | connect(mInterface.get(), &ManagerInterface::DeviceAdded, | ||||
45 | this, [this](const QDBusObjectPath &path) { | ||||
46 | if (auto device = Device::create(path, this)) { | ||||
47 | mDevices.push_back(device); | ||||
48 | qCDebug(log_libkbolt, "New Thunderbolt device %s (%s) added, status=%s", | ||||
49 | qUtf8Printable(device->uid()), qUtf8Printable(device->name()), | ||||
50 | qUtf8Printable(statusToString(device->status()))); | ||||
51 | Q_EMIT deviceAdded(device); | ||||
52 | } | ||||
53 | }); | ||||
54 | connect(mInterface.get(), &ManagerInterface::DeviceRemoved, | ||||
55 | this, [this](const QDBusObjectPath &path) { | ||||
56 | if (auto device = this->device(path)) { | ||||
57 | mDevices.removeOne(device); | ||||
58 | qCDebug(log_libkbolt, "Thunderbolt Device %s (%s) removed", | ||||
59 | qUtf8Printable(device->uid()), qUtf8Printable(device->name())); | ||||
60 | Q_EMIT deviceRemoved(device); | ||||
61 | } | ||||
62 | }); | ||||
63 | | ||||
64 | const auto devicePaths = mInterface->ListDevices().argumentAt<0>(); | ||||
65 | for (const auto &devicePath : devicePaths) { | ||||
66 | if (auto device = Device::create(devicePath, this)) { | ||||
67 | qCDebug(log_libkbolt, "Discovered Thunderbolt device %s (%s), status=%s", | ||||
68 | qUtf8Printable(device->uid()), qUtf8Printable(device->name()), | ||||
69 | qUtf8Printable(statusToString(device->status()))); | ||||
70 | mDevices.push_back(device); | ||||
71 | } | ||||
72 | } | ||||
73 | } | ||||
74 | | ||||
75 | Manager::~Manager() = default; | ||||
76 | | ||||
77 | bool Manager::isAvailable() const | ||||
78 | { | ||||
79 | return mInterface.get() && mInterface->isValid(); | ||||
80 | } | ||||
81 | | ||||
82 | uint Manager::version() const | ||||
83 | { | ||||
84 | return mInterface->version(); | ||||
85 | } | ||||
86 | | ||||
87 | bool Manager::isProbing() const | ||||
88 | { | ||||
89 | return mInterface->probing(); | ||||
90 | } | ||||
91 | | ||||
92 | Policy Manager::defaultPolicy() const | ||||
93 | { | ||||
94 | const auto policy = mInterface->defaultPolicy(); | ||||
95 | if (!mInterface->isValid() || policy.isEmpty()) { | ||||
96 | return Policy::Unknown; | ||||
97 | } | ||||
98 | return policyFromString(policy); | ||||
99 | } | ||||
100 | | ||||
101 | Security Manager::securityLevel() const | ||||
102 | { | ||||
103 | const auto level = mInterface->securityLevel(); | ||||
104 | if (!mInterface->isValid() || level.isEmpty()) { | ||||
105 | return Security::Unknown; | ||||
106 | } | ||||
107 | return securityFromString(level); | ||||
108 | } | ||||
109 | | ||||
110 | AuthMode Manager::authMode() const | ||||
111 | { | ||||
112 | const auto mode = mInterface->authMode(); | ||||
113 | if (!mInterface->isValid() || mode.isEmpty()) { | ||||
114 | return AuthMode::Disabled; | ||||
115 | } | ||||
116 | return authModeFromString(mode); | ||||
117 | } | ||||
118 | | ||||
119 | void Manager::setAuthMode(AuthMode mode) | ||||
120 | { | ||||
121 | mInterface->setAuthMode(authModeToString(mode)); | ||||
122 | } | ||||
123 | | ||||
124 | QSharedPointer<Device> Manager::device(std::function<bool(const QSharedPointer<Device> &)> &&match) const | ||||
125 | { | ||||
126 | auto device = std::find_if(mDevices.cbegin(), mDevices.cend(), std::move(match)); | ||||
127 | return device == mDevices.cend() ? QSharedPointer<Device>() : *device; | ||||
128 | } | ||||
129 | | ||||
130 | QSharedPointer<Device> Manager::device(const QString &uid) const | ||||
131 | { | ||||
132 | return device([uid](const auto &device) { return device->uid() == uid; }); | ||||
133 | } | ||||
134 | | ||||
135 | QSharedPointer<Device> Manager::device(const QDBusObjectPath &path) const | ||||
136 | { | ||||
137 | return device([path](const auto &device) { return device->dbusPath() == path; }); | ||||
138 | } | ||||
139 | | ||||
140 | QList<QSharedPointer<Device>> Manager::devices() const | ||||
141 | { | ||||
142 | return mDevices; | ||||
143 | } | ||||
144 | | ||||
145 | void Manager::enrollDevice(const QString &uid, Policy policy, AuthFlags authFlags, | ||||
146 | std::function<void()> successCallback, | ||||
147 | std::function<void(const QString &)> errorCallback) | ||||
148 | { | ||||
149 | qCDebug(log_libkbolt, "Enrolling Thunderbolt device %s with policy %s and flags %s", | ||||
150 | qUtf8Printable(uid), qUtf8Printable(policyToString(policy)), | ||||
151 | qUtf8Printable(authFlagsToString(authFlags))); | ||||
152 | | ||||
153 | auto device = this->device(uid); | ||||
154 | if (device) { | ||||
155 | device->setStatusOverride(Status::Authorizing); | ||||
156 | } else { | ||||
157 | qCWarning(log_libkbolt, "Found no matching Thunderbolt device object for uid %s", | ||||
158 | qUtf8Printable(uid)); | ||||
159 | } | ||||
160 | | ||||
161 | DBusHelper::call<QString, QString, QString>(mInterface.get(), | ||||
162 | QStringLiteral("EnrollDevice"), uid, | ||||
163 | policyToString(policy), authFlagsToString(authFlags), | ||||
164 | [uid, device, policy, authFlags, cb = std::move(successCallback)]() { | ||||
165 | qCDebug(log_libkbolt, "Thunderbolt device %s was successfully enrolled", qUtf8Printable(uid)); | ||||
166 | if (device) { | ||||
167 | device->clearStatusOverride(); | ||||
168 | Q_EMIT device->storedChanged(true); | ||||
169 | Q_EMIT device->policyChanged(policy); | ||||
170 | Q_EMIT device->authFlagsChanged(authFlags); | ||||
171 | } | ||||
172 | if (cb) { | ||||
173 | cb(); | ||||
174 | } | ||||
175 | }, | ||||
176 | [this, uid, device, cb = std::move(errorCallback)](const QString &error) { | ||||
177 | qCWarning(log_libkbolt, "Failed to enroll Thunderbolt device %s: %s", | ||||
178 | qUtf8Printable(uid), qUtf8Printable(error)); | ||||
179 | if (device) { | ||||
180 | device->setStatusOverride(Status::AuthError); | ||||
181 | } | ||||
182 | if (cb) { | ||||
183 | cb(error); | ||||
184 | } | ||||
185 | }, | ||||
186 | this); | ||||
187 | } | ||||
188 | | ||||
189 | void Manager::forgetDevice(const QString &uid, | ||||
190 | std::function<void()> successCallback, | ||||
191 | std::function<void(const QString &)> errorCallback) | ||||
192 | { | ||||
193 | qCDebug(log_libkbolt, "Forgetting Thunderbolt device %s", qUtf8Printable(uid)); | ||||
194 | | ||||
195 | DBusHelper::call<QString>(mInterface.get(), | ||||
196 | QStringLiteral("ForgetDevice"), uid, | ||||
197 | [this, uid, cb = std::move(successCallback)]() { | ||||
198 | qCDebug(log_libkbolt, "Thunderbolt device %s was successfully forgotten", qUtf8Printable(uid)); | ||||
199 | if (auto device = this->device(uid)) { | ||||
200 | device->clearStatusOverride(); | ||||
201 | Q_EMIT device->storedChanged(false); | ||||
202 | Q_EMIT device->authFlagsChanged(Auth::None); | ||||
203 | Q_EMIT device->policyChanged(Policy::Auto); | ||||
204 | } | ||||
205 | if (cb) { | ||||
206 | cb(); | ||||
207 | } | ||||
208 | }, | ||||
209 | [this, uid, cb = std::move(errorCallback)](const QString &error) { | ||||
210 | qCWarning(log_libkbolt, "Failed to forget Thunderbolt device %s: %s", | ||||
211 | qUtf8Printable(uid), qUtf8Printable(error)); | ||||
212 | if (auto device = this->device(uid)) { | ||||
213 | device->setStatusOverride(Status::AuthError); | ||||
214 | } | ||||
215 | if (cb) { | ||||
216 | cb(error); | ||||
217 | } | ||||
218 | }, | ||||
219 | this); | ||||
220 | } |