File indexing completed on 2024-05-05 05:29:12

0001 /*
0002    SPDX-FileCopyrightText: 2019 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
0003 
0004    SPDX-License-Identifier: LGPL-3.0-or-later
0005  */
0006 
0007 #include "PowerManagementInterface.h"
0008 
0009 #include <KLocalizedString>
0010 
0011 #include <QDBusConnection>
0012 #include <QDBusMessage>
0013 #include <QDBusPendingCall>
0014 #include <QDBusPendingCallWatcher>
0015 #include <QDBusPendingReply>
0016 #include <QDBusUnixFileDescriptor>
0017 
0018 #include <QString>
0019 
0020 #include <QGuiApplication>
0021 
0022 #include "discover_debug.h"
0023 #include <QLoggingCategory>
0024 
0025 class PowerManagementInterfacePrivate
0026 {
0027 public:
0028     bool mPreventSleep = false;
0029 
0030     bool mInhibitedSleep = false;
0031 
0032     uint mInhibitSleepCookie = 0;
0033 
0034     QString m_reason;
0035 };
0036 
0037 PowerManagementInterface::PowerManagementInterface(QObject *parent)
0038     : QObject(parent)
0039     , d(std::make_unique<PowerManagementInterfacePrivate>())
0040 {
0041     auto sessionBus = QDBusConnection::sessionBus();
0042 
0043     sessionBus.connect(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
0044                        QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
0045                        QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
0046                        QStringLiteral("HasInhibitChanged"),
0047                        this,
0048                        SLOT(hostSleepInhibitChanged()));
0049 }
0050 
0051 PowerManagementInterface::~PowerManagementInterface() = default;
0052 
0053 bool PowerManagementInterface::preventSleep() const
0054 {
0055     return d->mPreventSleep;
0056 }
0057 
0058 bool PowerManagementInterface::sleepInhibited() const
0059 {
0060     return d->mInhibitedSleep;
0061 }
0062 
0063 void PowerManagementInterface::setPreventSleep(bool value)
0064 {
0065     if (d->mPreventSleep == value) {
0066         return;
0067     }
0068 
0069     if (value) {
0070         inhibitSleep();
0071         d->mPreventSleep = true;
0072     } else {
0073         uninhibitSleep();
0074         d->mPreventSleep = false;
0075     }
0076 
0077     Q_EMIT preventSleepChanged();
0078 }
0079 
0080 void PowerManagementInterface::retryInhibitingSleep()
0081 {
0082     if (d->mPreventSleep && !d->mInhibitedSleep) {
0083         inhibitSleep();
0084     }
0085 }
0086 
0087 void PowerManagementInterface::hostSleepInhibitChanged()
0088 {
0089 }
0090 
0091 void PowerManagementInterface::inhibitDBusCallFinished(QDBusPendingCallWatcher *aWatcher)
0092 {
0093     QDBusPendingReply<uint> reply = *aWatcher;
0094     if (reply.isError()) {
0095     } else {
0096         d->mInhibitSleepCookie = reply.argumentAt<0>();
0097         d->mInhibitedSleep = true;
0098 
0099         Q_EMIT sleepInhibitedChanged();
0100     }
0101     aWatcher->deleteLater();
0102 }
0103 
0104 void PowerManagementInterface::uninhibitDBusCallFinished(QDBusPendingCallWatcher *aWatcher)
0105 {
0106     QDBusPendingReply<> reply = *aWatcher;
0107     if (reply.isError()) {
0108         qCWarning(DISCOVER_LOG) << "PowerManagementInterface::uninhibitDBusCallFinished" << reply.error();
0109     } else {
0110         d->mInhibitedSleep = false;
0111 
0112         Q_EMIT sleepInhibitedChanged();
0113     }
0114     aWatcher->deleteLater();
0115 }
0116 
0117 void PowerManagementInterface::inhibitSleep()
0118 {
0119     auto sessionBus = QDBusConnection::sessionBus();
0120 
0121     auto inhibitCall = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
0122                                                       QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
0123                                                       QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
0124                                                       QStringLiteral("Inhibit"));
0125 
0126     inhibitCall.setArguments({{QGuiApplication::desktopFileName()}, {d->m_reason}});
0127 
0128     auto asyncReply = sessionBus.asyncCall(inhibitCall);
0129 
0130     auto replyWatcher = new QDBusPendingCallWatcher(asyncReply, this);
0131 
0132     QObject::connect(replyWatcher, &QDBusPendingCallWatcher::finished, this, &PowerManagementInterface::inhibitDBusCallFinished);
0133 }
0134 
0135 void PowerManagementInterface::uninhibitSleep()
0136 {
0137     auto sessionBus = QDBusConnection::sessionBus();
0138 
0139     auto uninhibitCall = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
0140                                                         QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
0141                                                         QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
0142                                                         QStringLiteral("UnInhibit"));
0143 
0144     uninhibitCall.setArguments({{d->mInhibitSleepCookie}});
0145 
0146     auto asyncReply = sessionBus.asyncCall(uninhibitCall);
0147 
0148     auto replyWatcher = new QDBusPendingCallWatcher(asyncReply, this);
0149 
0150     QObject::connect(replyWatcher, &QDBusPendingCallWatcher::finished, this, &PowerManagementInterface::uninhibitDBusCallFinished);
0151 }
0152 
0153 QString PowerManagementInterface::reason() const
0154 {
0155     return d->m_reason;
0156 }
0157 
0158 void PowerManagementInterface::setReason(const QString &reason)
0159 {
0160     d->m_reason = reason;
0161 }