File indexing completed on 2024-04-28 16:45:08

0001 /*
0002     SPDX-FileCopyrightText: 2012 Alejandro Fiestas Olivares <afiestas@kde.org>
0003     SPDX-FileCopyrightText: 2015 Daniel Vrátil <dvratil@redhat.com>
0004 
0005     SPDX-License-Identifier: GPL-2.0-or-later
0006 */
0007 
0008 #include "device.h"
0009 #include "freedesktop_interface.h"
0010 #include "kscreen_daemon_debug.h"
0011 
0012 Device *Device::m_instance = nullptr;
0013 
0014 Device *Device::self()
0015 {
0016     if (!Device::m_instance) {
0017         m_instance = new Device();
0018     }
0019 
0020     return m_instance;
0021 }
0022 
0023 void Device::destroy()
0024 {
0025     delete m_instance;
0026     m_instance = nullptr;
0027 }
0028 
0029 Device::Device(QObject *parent)
0030     : QObject(parent)
0031     , m_isReady(false)
0032     , m_isLaptop(false)
0033     , m_isLidClosed(false)
0034 {
0035     m_freedesktop = new OrgFreedesktopDBusPropertiesInterface(QStringLiteral("org.freedesktop.UPower"),
0036                                                               QStringLiteral("/org/freedesktop/UPower"),
0037                                                               QDBusConnection::systemBus(),
0038                                                               this);
0039     if (!m_freedesktop->isValid()) {
0040         qCWarning(KSCREEN_KDED) << "UPower not available, lid detection won't work";
0041         qCDebug(KSCREEN_KDED) << m_freedesktop->lastError().message();
0042     } else {
0043         QDBusConnection::systemBus().connect(QStringLiteral("org.freedesktop.UPower"),
0044                                              QStringLiteral("/org/freedesktop/UPower"),
0045                                              QStringLiteral("org.freedesktop.DBus.Properties"),
0046                                              QStringLiteral("PropertiesChanged"),
0047                                              this,
0048                                              SLOT(changed()));
0049         fetchIsLaptop();
0050     }
0051 
0052     m_suspendSession = new QDBusInterface(QStringLiteral("org.kde.Solid.PowerManagement"),
0053                                           QStringLiteral("/org/kde/Solid/PowerManagement/Actions/SuspendSession"),
0054                                           QStringLiteral("org.kde.Solid.PowerManagement.Actions.SuspendSession"),
0055                                           QDBusConnection::sessionBus(),
0056                                           this);
0057     if (m_suspendSession->isValid()) {
0058         connect(m_suspendSession, SIGNAL(resumingFromSuspend()), this, SIGNAL(resumingFromSuspend()));
0059         connect(m_suspendSession, SIGNAL(aboutToSuspend()), this, SIGNAL(aboutToSuspend()));
0060     } else {
0061         qCWarning(KSCREEN_KDED) << "PowerDevil SuspendSession action not available!";
0062         qCDebug(KSCREEN_KDED) << m_suspendSession->lastError().message();
0063     }
0064 
0065     fetchIsLaptop();
0066 }
0067 
0068 Device::~Device()
0069 {
0070 }
0071 
0072 void Device::changed()
0073 {
0074     fetchLidIsClosed();
0075 }
0076 
0077 void Device::setReady()
0078 {
0079     if (m_isReady) {
0080         return;
0081     }
0082 
0083     m_isReady = true;
0084     Q_EMIT ready();
0085 }
0086 
0087 bool Device::isReady() const
0088 {
0089     return m_isReady;
0090 }
0091 
0092 bool Device::isLaptop() const
0093 {
0094     return m_isLaptop;
0095 }
0096 
0097 bool Device::isLidClosed() const
0098 {
0099     return m_isLidClosed;
0100 }
0101 
0102 void Device::fetchIsLaptop()
0103 {
0104     QDBusPendingReply<QVariant> res = m_freedesktop->Get(QStringLiteral("org.freedesktop.UPower"), QStringLiteral("LidIsPresent"));
0105     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(res);
0106     connect(watcher, &QDBusPendingCallWatcher::finished, this, &Device::isLaptopFetched);
0107 }
0108 
0109 void Device::isLaptopFetched(QDBusPendingCallWatcher *watcher)
0110 {
0111     const QDBusPendingReply<QVariant> reply = *watcher;
0112     if (reply.isError()) {
0113         qCDebug(KSCREEN_KDED) << "Couldn't get if the device is a laptop: " << reply.error().message();
0114         setReady();
0115         return;
0116     }
0117 
0118     m_isLaptop = reply.value().toBool();
0119     watcher->deleteLater();
0120 
0121     if (!m_isLaptop) {
0122         setReady();
0123         return;
0124     }
0125 
0126     fetchLidIsClosed();
0127 }
0128 
0129 void Device::fetchLidIsClosed()
0130 {
0131     QDBusPendingReply<QVariant> res = m_freedesktop->Get(QStringLiteral("org.freedesktop.UPower"), QStringLiteral("LidIsClosed"));
0132     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(res);
0133     connect(watcher, &QDBusPendingCallWatcher::finished, this, &Device::isLidClosedFetched);
0134 }
0135 
0136 void Device::isLidClosedFetched(QDBusPendingCallWatcher *watcher)
0137 {
0138     const QDBusPendingReply<QVariant> reply = *watcher;
0139     if (reply.isError()) {
0140         qCDebug(KSCREEN_KDED) << "Couldn't get if the laptop has the lid closed: " << reply.error().message();
0141         return;
0142     }
0143 
0144     if (reply.argumentAt<0>() != m_isLidClosed) {
0145         m_isLidClosed = reply.value().toBool();
0146         if (m_isReady) {
0147             Q_EMIT lidClosedChanged(m_isLidClosed);
0148         }
0149     }
0150     watcher->deleteLater();
0151 
0152     setReady();
0153 }