Solid

fakemanager.cpp
1 /*
2  SPDX-FileCopyrightText: 2006 MichaĆ«l Larouche <[email protected]>
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 QT_DBUS_LIB
18 #include <QDBusConnection>
19 #endif
20 
21 using namespace Solid::Backends::Fake;
22 
23 class FakeManager::Private
24 {
25 public:
26  QMap<QString, FakeDevice *> loadedDevices;
28  QString xmlFile;
30 };
31 
32 FakeManager::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 QT_DBUS_LIB
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 
61 FakeManager::~FakeManager()
62 {
63 #ifdef QT_DBUS_LIB
65 #endif
66  qDeleteAll(d->loadedDevices);
67  delete d;
68 }
69 
70 QString FakeManager::udiPrefix() const
71 {
72  return "/org/kde/solid/fakehw";
73 }
74 
75 QSet<Solid::DeviceInterface::Type> FakeManager::supportedInterfaces() const
76 {
77  return d->supportedInterfaces;
78 }
79 
80 QStringList FakeManager::allDevices()
81 {
82  QStringList deviceUdiList;
83 
84  for (const FakeDevice *device : qAsConst(d->loadedDevices)) {
85  deviceUdiList.append(device->udi());
86  }
87 
88  return deviceUdiList;
89 }
90 
91 QStringList FakeManager::devicesFromQuery(const QString &parentUdi, Solid::DeviceInterface::Type type)
92 {
93  if (!parentUdi.isEmpty()) {
94  QStringList found = findDeviceStringMatch(QLatin1String("parent"), parentUdi);
95 
96  if (type == Solid::DeviceInterface::Unknown) {
97  return found;
98  }
99 
100  QStringList result;
101 
103  QStringList::ConstIterator end = found.constEnd();
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 
121 QObject *FakeManager::createDevice(const QString &udi)
122 {
123  if (d->loadedDevices.contains(udi)) {
124  return new FakeDevice(*d->loadedDevices[udi]);
125  }
126 
127  return nullptr;
128 }
129 
130 FakeDevice *FakeManager::findDevice(const QString &udi)
131 {
132  return d->loadedDevices.value(udi);
133 }
134 
135 QStringList FakeManager::findDeviceStringMatch(const QString &key, const QString &value)
136 {
137  QStringList result;
138  for (const FakeDevice *device : qAsConst(d->loadedDevices)) {
139  if (device->property(key).toString() == value) {
140  result.append(device->udi());
141  }
142  }
143 
144  return result;
145 }
146 
147 QStringList FakeManager::findDeviceByDeviceInterface(Solid::DeviceInterface::Type type)
148 {
149  QStringList result;
150  for (const FakeDevice *device : qAsConst(d->loadedDevices)) {
151  if (device->queryDeviceInterface(type)) {
152  result.append(device->udi());
153  }
154  }
155 
156  return result;
157 }
158 
159 void 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 
168 void 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();
173  Q_EMIT deviceRemoved(udi);
174  delete dev;
175  }
176 }
177 
178 void 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 
212 FakeDevice *FakeManager::parseDeviceElement(const QDomElement &deviceElement)
213 {
214  FakeDevice *device = nullptr;
215  QMap<QString, QVariant> propertyMap;
216  QString udi = deviceElement.attribute("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("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 }
QObject * device(const QString &udi, const QString &type)
Retrieves an interface object to the specified device.
Definition: devices.cpp:196
QString attribute(const QString &name, const QString &defValue) const const
bool registerObject(const QString &path, QObject *object, QDBusConnection::RegisterOptions options)
This class specifies the interface a backend will have to implement in order to be used in the system...
Definition: devicemanager.h:28
QDBusConnection sessionBus()
QDomElement documentElement() const const
QDomNode nextSibling() const const
QDomElement toElement() const const
Type
This enum type defines the type of device interface that a Device can have.
void append(const T &value)
QVariant property(const char *name) const const
QString text() const const
bool isEmpty() const const
void deviceAdded(const QString &udi) const
Emitted when a new device matching the specified query arrives.
void unregisterObject(const QString &path, QDBusConnection::UnregisterMode mode)
virtual bool open(QIODevice::OpenMode mode) override
bool isNull() const const
QDomNode firstChild() const const
virtual void close() override
typedef ConstIterator
The single responsibility of this class is to create arguments valid for logind Inhibit call...
QMap::iterator insert(const Key &key, const T &value)
void deviceRemoved(const QString &udi) const
Emitted when a device matching the specified query disappears.
QSet< Solid::DeviceInterface::Type > supportedInterfaces() const override
Retrieves a set of interfaces the backend supports.
Definition: fakemanager.cpp:75
bool isEmpty() const const
QString tagName() const const
QList::const_iterator constEnd() const const
QList::const_iterator constBegin() const const
QObject * parent() const const
QString toString() const const
Q_EMITQ_EMIT
bool setContent(const QByteArray &data, bool namespaceProcessing, QString *errorMsg, int *errorLine, int *errorColumn)
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Sun Jun 20 2021 22:49:51 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.