Solid

fakemanager.cpp
1/*
2 SPDX-FileCopyrightText: 2006 Michaƫl Larouche <michael.larouche@kdemail.net>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
5*/
6#include "fakemanager.h"
7
8#include "fakedevice.h"
9
10// Qt includes
11#include <QDebug>
12#include <QDomDocument>
13#include <QDomElement>
14#include <QDomNode>
15#include <QFile>
16#include <QString>
17#ifdef HAVE_DBUS
18#include <QDBusConnection>
19#endif
20
21using namespace Solid::Backends::Fake;
22
23class FakeManager::Private
24{
25public:
26 QMap<QString, FakeDevice *> loadedDevices;
28 QString xmlFile;
29 QSet<Solid::DeviceInterface::Type> supportedInterfaces;
30};
31
32FakeManager::FakeManager(QObject *parent, const QString &xmlFile)
33 : Solid::Ifaces::DeviceManager(parent)
34 , d(new Private)
35{
36 QString machineXmlFile = xmlFile;
37 d->xmlFile = machineXmlFile;
38
39#ifdef HAVE_DBUS
40 QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/kde/solid/fakehw"), this, QDBusConnection::ExportNonScriptableSlots);
41#endif
42
43 parseMachineFile();
44
45 // clang-format off
46 d->supportedInterfaces << Solid::DeviceInterface::GenericInterface
47 << Solid::DeviceInterface::Processor
48 << Solid::DeviceInterface::Block
49 << Solid::DeviceInterface::StorageAccess
50 << Solid::DeviceInterface::StorageDrive
51 << Solid::DeviceInterface::OpticalDrive
52 << Solid::DeviceInterface::StorageVolume
53 << Solid::DeviceInterface::OpticalDisc
54 << Solid::DeviceInterface::Camera
55 << Solid::DeviceInterface::PortableMediaPlayer
56 << Solid::DeviceInterface::Battery
57 << Solid::DeviceInterface::NetworkShare;
58 // clang-format on
59}
60
61FakeManager::~FakeManager()
62{
63#ifdef HAVE_DBUS
64 QDBusConnection::sessionBus().unregisterObject(QStringLiteral("/org/kde/solid/fakehw"), QDBusConnection::UnregisterTree);
65#endif
66 qDeleteAll(d->loadedDevices);
67 delete d;
68}
69
71{
72 return QStringLiteral("/org/kde/solid/fakehw");
73}
74
76{
77 return d->supportedInterfaces;
78}
79
81{
82 QStringList deviceUdiList;
83
84 for (const FakeDevice *device : std::as_const(d->loadedDevices)) {
85 deviceUdiList.append(device->udi());
86 }
87
88 return deviceUdiList;
89}
90
92{
93 if (!parentUdi.isEmpty()) {
94 QStringList found = findDeviceStringMatch(QStringLiteral("parent"), parentUdi);
95
96 if (type == Solid::DeviceInterface::Unknown) {
97 return found;
98 }
99
100 QStringList result;
101
104
105 for (; it != end; ++it) {
106 FakeDevice *device = d->loadedDevices[*it];
107
108 if (device->queryDeviceInterface(type)) {
109 result << *it;
110 }
111 }
112
113 return result;
114 } else if (type != Solid::DeviceInterface::Unknown) {
115 return findDeviceByDeviceInterface(type);
116 } else {
117 return allDevices();
118 }
119}
120
122{
123 if (d->loadedDevices.contains(udi)) {
124 return new FakeDevice(*d->loadedDevices[udi]);
125 }
126
127 return nullptr;
128}
129
130FakeDevice *FakeManager::findDevice(const QString &udi)
131{
132 return d->loadedDevices.value(udi);
133}
134
135QStringList FakeManager::findDeviceStringMatch(const QString &key, const QString &value)
136{
137 QStringList result;
138 for (const FakeDevice *device : std::as_const(d->loadedDevices)) {
139 if (device->property(key).toString() == value) {
140 result.append(device->udi());
141 }
142 }
143
144 return result;
145}
146
147QStringList FakeManager::findDeviceByDeviceInterface(Solid::DeviceInterface::Type type)
148{
149 QStringList result;
150 for (const FakeDevice *device : std::as_const(d->loadedDevices)) {
151 if (device->queryDeviceInterface(type)) {
152 result.append(device->udi());
153 }
154 }
155
156 return result;
157}
158
159void FakeManager::plug(const QString &udi)
160{
161 if (d->hiddenDevices.contains(udi)) {
162 QMap<QString, QVariant> properties = d->hiddenDevices.take(udi);
163 d->loadedDevices[udi] = new FakeDevice(udi, properties);
164 Q_EMIT deviceAdded(udi);
165 }
166}
167
168void FakeManager::unplug(const QString &udi)
169{
170 if (d->loadedDevices.contains(udi)) {
171 FakeDevice *dev = d->loadedDevices.take(udi);
172 d->hiddenDevices[udi] = dev->allProperties();
174 delete dev;
175 }
176}
177
178void FakeManager::parseMachineFile()
179{
180 QFile machineFile(d->xmlFile);
181 if (!machineFile.open(QIODevice::ReadOnly)) {
182 qWarning() << Q_FUNC_INFO << "Error while opening " << d->xmlFile;
183 return;
184 }
185
186 QDomDocument fakeDocument;
187 if (!fakeDocument.setContent(&machineFile)) {
188 qWarning() << Q_FUNC_INFO << "Error while creating the QDomDocument.";
189 machineFile.close();
190 return;
191 }
192 machineFile.close();
193
194 qDebug() << Q_FUNC_INFO << "Parsing fake computer XML: " << d->xmlFile;
195 QDomElement mainElement = fakeDocument.documentElement();
196 QDomNode node = mainElement.firstChild();
197 while (!node.isNull()) {
198 QDomElement tempElement = node.toElement();
199 if (!tempElement.isNull() && tempElement.tagName() == QLatin1String("device")) {
200 FakeDevice *tempDevice = parseDeviceElement(tempElement);
201 if (tempDevice) {
202 Q_ASSERT(!d->loadedDevices.contains(tempDevice->udi()));
203 d->loadedDevices.insert(tempDevice->udi(), tempDevice);
204 Q_EMIT deviceAdded(tempDevice->udi());
205 }
206 }
207
208 node = node.nextSibling();
209 }
210}
211
212FakeDevice *FakeManager::parseDeviceElement(const QDomElement &deviceElement)
213{
214 FakeDevice *device = nullptr;
215 QMap<QString, QVariant> propertyMap;
216 QString udi = deviceElement.attribute(QStringLiteral("udi"));
217
218 QDomNode propertyNode = deviceElement.firstChild();
219 while (!propertyNode.isNull()) {
220 QDomElement propertyElement = propertyNode.toElement();
221 if (!propertyElement.isNull() && propertyElement.tagName() == QLatin1String("property")) {
222 QString propertyKey;
223 QVariant propertyValue;
224
225 propertyKey = propertyElement.attribute(QStringLiteral("key"));
226 propertyValue = QVariant(propertyElement.text());
227
228 propertyMap.insert(propertyKey, propertyValue);
229 }
230
231 propertyNode = propertyNode.nextSibling();
232 }
233
234 if (!propertyMap.isEmpty()) {
235 device = new FakeDevice(udi, propertyMap);
236 }
237
238 return device;
239}
240
241#include "moc_fakemanager.cpp"
QStringList devicesFromQuery(const QString &parentUdi, Solid::DeviceInterface::Type type) override
Retrieves the Universal Device Identifier (UDI) of all the devices matching the given constraints (pa...
QObject * createDevice(const QString &udi) override
Instantiates a new Device object from this backend given its UDI.
QStringList allDevices() override
Return the list of UDI of all available devices.
QString udiPrefix() const override
Retrieves the prefix used for the UDIs off all the devices reported by the device manager.
QSet< Solid::DeviceInterface::Type > supportedInterfaces() const override
Retrieves a set of interfaces the backend supports.
Type
This enum type defines the type of device interface that a Device can have.
This class specifies the interface a backend will have to implement in order to be used in the system...
void deviceAdded(const QString &udi)
This signal is emitted when a new device appears in the system.
void deviceRemoved(const QString &udi)
This signal is emitted when a device disappears from the system.
KGuiItem properties()
bool registerObject(const QString &path, QObject *object, RegisterOptions options)
QDBusConnection sessionBus()
void unregisterObject(const QString &path, UnregisterMode mode)
QDomElement documentElement() const const
ParseResult setContent(QAnyStringView text, ParseOptions options)
QString attribute(const QString &name, const QString &defValue) const const
QString tagName() const const
QString text() const const
QDomNode firstChild() const const
bool isNull() const const
QDomNode nextSibling() const const
QDomElement toElement() const const
void append(QList< T > &&value)
const_iterator constBegin() const const
const_iterator constEnd() const const
bool contains(const Key &key) const const
iterator insert(const Key &key, const T &value)
bool isEmpty() const const
T take(const Key &key)
T value(const Key &key, const T &defaultValue) const const
Q_EMITQ_EMIT
bool isEmpty() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Dec 6 2024 12:07:11 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.