Solid

upowermanager.cpp
1/*
2 SPDX-FileCopyrightText: 2010 Michael Zanetti <mzanetti@kde.org>
3 SPDX-FileCopyrightText: 2010 Lukas Tinkl <ltinkl@redhat.com>
4
5 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL
6*/
7
8#include "upowermanager.h"
9#include "upower.h"
10#include "upowerdevice.h"
11
12#include <QDBusConnectionInterface>
13#include <QDBusMetaType>
14#include <QDBusReply>
15#include <QDebug>
16
17#include "../shared/rootdevice.h"
18
19using namespace Solid::Backends::UPower;
20using namespace Solid::Backends::Shared;
21
22UPowerManager::UPowerManager(QObject *parent)
23 : Solid::Ifaces::DeviceManager(parent)
24 , m_supportedInterfaces({Solid::DeviceInterface::GenericInterface, Solid::DeviceInterface::Battery})
25 , m_manager(QDBusConnection::systemBus())
26 , m_knownDevices(udiPrefix())
27{
28 qDBusRegisterMetaType<QList<QDBusObjectPath>>();
29 qDBusRegisterMetaType<QVariantMap>();
30
31 bool serviceFound = m_manager.isValid();
32 if (!serviceFound) {
33 // find out whether it will be activated automatically
34 QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DBus"), //
35 QStringLiteral("/org/freedesktop/DBus"),
36 QStringLiteral("org.freedesktop.DBus"),
37 QStringLiteral("ListActivatableNames"));
38
40 if (reply.isValid() && reply.value().contains(QStringLiteral(UP_DBUS_SERVICE))) {
41 QDBusConnection::systemBus().interface()->startService(QStringLiteral(UP_DBUS_SERVICE));
42 serviceFound = true;
43 }
44 }
45
46 if (serviceFound) {
47 connect(&m_manager, &UPower::DBusInterface::DeviceAdded, this, &UPowerManager::onDeviceAdded);
48 connect(&m_manager, &UPower::DBusInterface::DeviceRemoved, this, &UPowerManager::onDeviceRemoved);
49 }
50}
51
52UPowerManager::~UPowerManager()
53{
54}
55
56QObject *UPowerManager::createDevice(const QString &udi)
57{
58 if (udi == udiPrefix()) {
59 RootDevice *root = new RootDevice(udiPrefix());
60
61 root->setProduct(tr("Power Management"));
62 root->setDescription(tr("Batteries and other sources of power"));
63 root->setIcon(QStringLiteral("preferences-system-power-management"));
64
65 return root;
66
67 } else if (m_knownDevices.contains(udi) || allDevices().contains(udi)) {
68 return new UPowerDevice(udi);
69
70 } else {
71 return nullptr;
72 }
73}
74
75QStringList UPowerManager::devicesFromQuery(const QString &parentUdi, Solid::DeviceInterface::Type type)
76{
77 const QStringList allDev = allDevices();
78 QStringList result;
79
80 if (!parentUdi.isEmpty()) {
81 for (const QString &udi : allDev) {
82 if (udi == udiPrefix()) {
83 continue;
84 }
85
86 UPowerDevice device(udi);
87 if (device.queryDeviceInterface(type) && device.parentUdi() == parentUdi) {
88 result << udi;
89 }
90 }
91
92 return result;
93 } else if (type != Solid::DeviceInterface::Unknown) {
94 for (const QString &udi : allDev) {
95 if (udi == udiPrefix()) {
96 continue;
97 }
98
99 UPowerDevice device(udi);
100 if (device.queryDeviceInterface(type)) {
101 result << udi;
102 }
103 }
104
105 return result;
106 } else {
107 return allDev;
108 }
109}
110
111QStringList UPowerManager::allDevices()
112{
113 static bool initialized = false;
114 if (initialized)
115 return m_knownDevices;
116
117 auto reply = m_manager.EnumerateDevices();
118 reply.waitForFinished();
119
120 if (!reply.isValid()) {
121 qWarning() << Q_FUNC_INFO << " error: " << reply.error().name();
122 return QStringList();
123 }
124 const auto pathList = reply.value();
125
126 QStringList retList;
127 retList.reserve(pathList.size() + m_knownDevices.size());
128
129 for (const QDBusObjectPath &path : pathList) {
130 retList << path.path();
131 }
132 retList += m_knownDevices;
133
134 std::sort(retList.begin(), retList.end());
135 auto end = std::unique(retList.begin(), retList.end());
136 retList.erase(end, retList.end());
137
138 m_knownDevices = retList;
139 initialized = true;
140
141 return m_knownDevices;
142}
143
144QSet<Solid::DeviceInterface::Type> UPowerManager::supportedInterfaces() const
145{
146 return m_supportedInterfaces;
147}
148
149QString UPowerManager::udiPrefix() const
150{
151 return QStringLiteral(UP_UDI_PREFIX);
152}
153
154void UPowerManager::onDeviceAdded(const QDBusObjectPath &path)
155{
156 auto pathString = path.path();
157 if (m_knownDevices.indexOf(pathString) < 0)
158 m_knownDevices.append(pathString);
159
160 Q_EMIT deviceAdded(pathString);
161}
162
163void UPowerManager::onDeviceRemoved(const QDBusObjectPath &path)
164{
165 auto pathString = path.path();
166 auto index = m_knownDevices.indexOf(pathString);
167 if (index >= 0) {
168 m_knownDevices.removeAt(index);
169 Q_EMIT deviceRemoved(pathString);
170 }
171}
172
173#include "moc_upowermanager.cpp"
Type
This enum type defines the type of device interface that a Device can have.
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.
QString path(const QString &relativePath)
const QList< QKeySequence > & end()
QDBusMessage call(const QDBusMessage &message, QDBus::CallMode mode, int timeout) const const
QDBusConnectionInterface * interface() const const
QDBusConnection systemBus()
QDBusReply< void > startService(const QString &name)
QString name() const const
QDBusMessage createMethodCall(const QString &service, const QString &path, const QString &interface, const QString &method)
const QDBusError & error()
bool isValid() const const
void append(QList< T > &&value)
iterator begin()
iterator end()
iterator erase(const_iterator begin, const_iterator end)
void removeAt(qsizetype i)
void reserve(qsizetype size)
qsizetype size() const const
Q_EMITQ_EMIT
QString tr(const char *sourceText, const char *disambiguation, int n)
bool isEmpty() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
qsizetype indexOf(const QRegularExpression &re, qsizetype from) const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri Nov 1 2024 18:52:58 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.