Solid

upowerdevice.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 "upowerdevice.h"
9#include "upower.h"
10#include "upowerbattery.h"
11#include "upowerdeviceinterface.h"
12#include "upowergenericinterface.h"
13
14#include <solid/device.h>
15#include <solid/genericinterface.h>
16
17#include <QDBusConnection>
18#include <QDBusReply>
19#include <QStringList>
20
21using namespace Solid::Backends::UPower;
22
23UPowerDevice::UPowerDevice(const QString &udi)
24 : Solid::Ifaces::Device()
25 , m_udi(udi)
26{
27 QDBusConnection::systemBus().connect(QStringLiteral(UP_DBUS_SERVICE),
28 m_udi,
29 QStringLiteral("org.freedesktop.DBus.Properties"),
30 QStringLiteral("PropertiesChanged"),
31 this,
32 SLOT(onPropertiesChanged(QString, QVariantMap, QStringList)));
33
34 // TODO port this to Solid::Power, we can't link against kdelibs4support for this signal
35 // older upower versions not affected
36 QDBusConnection::systemBus().connect(QStringLiteral("org.freedesktop.login1"), //
37 QStringLiteral("/org/freedesktop/login1"),
38 QStringLiteral("org.freedesktop.login1.Manager"),
39 QStringLiteral("PrepareForSleep"),
40 this,
41 SLOT(login1Resuming(bool)));
42}
43
44UPowerDevice::~UPowerDevice()
45{
46}
47
48QObject *UPowerDevice::createDeviceInterface(const Solid::DeviceInterface::Type &type)
49{
50 if (!queryDeviceInterface(type)) {
51 return nullptr;
52 }
53
54 DeviceInterface *iface = nullptr;
55 switch (type) {
56 case Solid::DeviceInterface::GenericInterface:
57 iface = new GenericInterface(this);
58 break;
59 case Solid::DeviceInterface::Battery:
60 iface = new Battery(this);
61 break;
62 default:
63 break;
64 }
65 return iface;
66}
67
68bool UPowerDevice::queryDeviceInterface(const Solid::DeviceInterface::Type &type) const
69{
70 const UpDeviceKind uptype = static_cast<UpDeviceKind>(prop(QStringLiteral("Type")).toUInt());
71 switch (type) {
72 case Solid::DeviceInterface::GenericInterface:
73 return true;
74 case Solid::DeviceInterface::Battery:
75 switch (uptype) {
76 case UP_DEVICE_KIND_BATTERY:
77 case UP_DEVICE_KIND_UPS:
78 case UP_DEVICE_KIND_MOUSE:
79 case UP_DEVICE_KIND_KEYBOARD:
80 case UP_DEVICE_KIND_PDA:
81 case UP_DEVICE_KIND_PHONE:
82 case UP_DEVICE_KIND_TABLET:
83 case UP_DEVICE_KIND_GAMING_INPUT:
84 case UP_DEVICE_KIND_SPEAKERS:
85 case UP_DEVICE_KIND_HEADSET:
86 case UP_DEVICE_KIND_HEADPHONES:
87 case UP_DEVICE_KIND_BLUETOOTH_GENERIC:
88 case UP_DEVICE_KIND_TOUCHPAD:
89 return true;
90 case UP_DEVICE_KIND_UNKNOWN:
91 // There is currently no "Bluetooth battery" type, so check if it comes from Bluez
92 if (prop(QStringLiteral("NativePath")).toString().startsWith(QLatin1String("/org/bluez/"))) {
93 return true;
94 }
95 return false;
96 case UP_DEVICE_KIND_LINE_POWER:
97 case UP_DEVICE_KIND_MONITOR:
98 case UP_DEVICE_KIND_MEDIA_PLAYER:
99 case UP_DEVICE_KIND_COMPUTER:
100 case UP_DEVICE_KIND_LAST:
101 return false;
102 }
103 Q_FALLTHROUGH();
104 default:
105 return false;
106 }
107}
108
109QStringList UPowerDevice::emblems() const
110{
111 return QStringList();
112}
113
114QString UPowerDevice::description() const
115{
116 if (queryDeviceInterface(Solid::DeviceInterface::Battery)) {
117 return tr("%1 Battery", "%1 is battery technology").arg(batteryTechnology());
118 } else {
119 QString result = prop(QStringLiteral("Model")).toString();
120 if (result.isEmpty()) {
121 return vendor();
122 }
123 return result;
124 }
125}
126
127QString UPowerDevice::batteryTechnology() const
128{
129 const UpDeviceTechnology tech = static_cast<UpDeviceTechnology>(prop(QStringLiteral("Technology")).toUInt());
130 switch (tech) {
131 case UP_DEVICE_TECHNOLOGY_UNKNOWN:
132 return tr("Unknown", "battery technology");
133 case UP_DEVICE_TECHNOLOGY_LITHIUM_ION:
134 return tr("Lithium Ion", "battery technology");
135 case UP_DEVICE_TECHNOLOGY_LITHIUM_POLYMER:
136 return tr("Lithium Polymer", "battery technology");
137 case UP_DEVICE_TECHNOLOGY_LITHIUM_IRON_PHOSPHATE:
138 return tr("Lithium Iron Phosphate", "battery technology");
139 case UP_DEVICE_TECHNOLOGY_LEAD_ACID:
140 return tr("Lead Acid", "battery technology");
141 case UP_DEVICE_TECHNOLOGY_NICKEL_CADMIUM:
142 return tr("Nickel Cadmium", "battery technology");
143 case UP_DEVICE_TECHNOLOGY_NICKEL_METAL_HYDRIDE:
144 return tr("Nickel Metal Hydride", "battery technology");
145 case UP_DEVICE_TECHNOLOGY_LAST:
146 return tr("Unknown", "battery technology");
147 }
148 return tr("Unknown", "battery technology");
149}
150
151QString UPowerDevice::icon() const
152{
153 if (queryDeviceInterface(Solid::DeviceInterface::Battery)) {
154 return QStringLiteral("battery");
155 } else {
156 return QString();
157 }
158}
159
160QString UPowerDevice::product() const
161{
162 QString result = prop(QStringLiteral("Model")).toString();
163
164 if (result.isEmpty()) {
165 result = description();
166 }
167
168 return result;
169}
170
171QString UPowerDevice::vendor() const
172{
173 return prop(QStringLiteral("Vendor")).toString();
174}
175
176QString UPowerDevice::udi() const
177{
178 return m_udi;
179}
180
181QString UPowerDevice::parentUdi() const
182{
183 return QStringLiteral(UP_UDI_PREFIX);
184}
185
186void UPowerDevice::checkCache(const QString &key) const
187{
188 if (m_cache.contains(key) || m_negativeCache.contains(key)) {
189 return;
190 }
191
192 loadCache();
193
194 if (m_cache.contains(key)) {
195 return;
196 }
197
198 QDBusMessage call =
199 QDBusMessage::createMethodCall(QStringLiteral(UP_DBUS_SERVICE), m_udi, QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("Get"));
200 call.setArguments({QStringLiteral(UP_DBUS_INTERFACE_DEVICE), key});
202
203 if (reply.isValid()) {
204 m_cache[key] = reply.value();
205 } else {
206 m_negativeCache.append(key);
207 }
208}
209
210QVariant UPowerDevice::prop(const QString &key) const
211{
212 checkCache(key);
213 return m_cache.value(key);
214}
215
216bool UPowerDevice::propertyExists(const QString &key) const
217{
218 checkCache(key);
219 return m_cache.contains(key);
220}
221
222void UPowerDevice::loadCache() const
223{
224 QDBusMessage call =
225 QDBusMessage::createMethodCall(QStringLiteral(UP_DBUS_SERVICE), m_udi, QStringLiteral("org.freedesktop.DBus.Properties"), QStringLiteral("GetAll"));
226 call.setArguments({QStringLiteral(UP_DBUS_INTERFACE_DEVICE)});
228
229 if (reply.isValid()) {
230 m_cache = reply.value();
231 m_cacheComplete = true;
232 } else {
233 m_cache.clear();
234 }
235}
236
237QMap<QString, QVariant> UPowerDevice::allProperties() const
238{
239 if (!m_cacheComplete) {
240 loadCache();
241 }
242
243 return m_cache;
244}
245
246void UPowerDevice::onPropertiesChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps)
247{
248 if (ifaceName != QStringLiteral(UP_DBUS_INTERFACE_DEVICE))
249 return;
250
251 QMap<QString, int> changeMap;
252 for (auto it = changedProps.begin(); it != changedProps.end(); ++it) {
253 m_cache[it.key()] = it.value();
254 m_negativeCache.removeOne(it.key());
255 changeMap.insert(it.key(), Solid::GenericInterface::PropertyModified);
256 }
257 for (const auto &propName : invalidatedProps) {
258 m_cache.remove(propName);
259 m_negativeCache.removeOne(propName);
260 changeMap.insert(propName, Solid::GenericInterface::PropertyModified);
261 m_cacheComplete = false;
262 }
263 Q_EMIT propertyChanged(changeMap);
264}
265
266void UPowerDevice::login1Resuming(bool active)
267{
268 // Nothing to do when going into sleep
269 if (active)
270 return;
271
272 QMap<QString, int> changeMap;
273 for (auto it = m_cache.begin(); it != m_cache.end(); ++it) {
274 if (it.value().isValid()) {
275 changeMap.insert(it.key(), Solid::GenericInterface::PropertyModified);
276 }
277 }
278 m_cache.clear();
279 m_negativeCache.clear();
280 m_cacheComplete = false;
281 Q_EMIT propertyChanged(changeMap);
282}
283
284#include "moc_upowerdevice.cpp"
Type
This enum type defines the type of device interface that a Device can have.
This class allows applications to deal with devices available in the underlying system.
char * toString(const EngineQuery &query)
QDBusMessage call(const QDBusMessage &message, QDBus::CallMode mode, int timeout) const const
bool connect(const QString &service, const QString &path, const QString &interface, const QString &name, QObject *receiver, const char *slot)
QDBusConnection systemBus()
QDBusMessage createMethodCall(const QString &service, const QString &path, const QString &interface, const QString &method)
void setArguments(const QList< QVariant > &arguments)
bool isValid() const const
void append(QList< T > &&value)
void clear()
bool removeOne(const AT &t)
iterator insert(const Key &key, const T &value)
Q_EMITQ_EMIT
QString tr(const char *sourceText, const char *disambiguation, int n)
QString arg(Args &&... args) const const
bool isEmpty() const const
bool contains(QLatin1StringView str, Qt::CaseSensitivity cs) const const
QString toString() const const
uint toUInt(bool *ok) const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Sat Dec 21 2024 17:03:23 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.