File indexing completed on 2024-05-19 05:37:52

0001 /*
0002     SPDX-FileCopyrightText: 2011 Sebastian Kügler <sebas@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include <QDBusConnection>
0008 #include <QDBusInterface>
0009 #include <QDBusMessage>
0010 #include <QDBusPendingReply>
0011 
0012 #include <KAuthorized>
0013 
0014 // kde-workspace/libs
0015 #include <sessionmanagement.h>
0016 
0017 #include <krunner_interface.h>
0018 
0019 #include "powermanagementjob.h"
0020 
0021 PowerManagementJob::PowerManagementJob(const QString &operation, QMap<QString, QVariant> &parameters, QObject *parent)
0022     : ServiceJob(parent->objectName(), operation, parameters, parent)
0023     , m_session(new SessionManagement(this))
0024 {
0025 }
0026 
0027 PowerManagementJob::~PowerManagementJob()
0028 {
0029 }
0030 
0031 static void callWhenFinished(const QDBusPendingCall &pending, std::function<void(bool)> func, QObject *parent)
0032 {
0033     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pending, parent);
0034     QObject::connect(watcher, &QDBusPendingCallWatcher::finished, parent, [func](QDBusPendingCallWatcher *watcher) {
0035         watcher->deleteLater();
0036         func(!watcher->isError());
0037     });
0038 }
0039 
0040 void PowerManagementJob::start()
0041 {
0042     const QString operation = operationName();
0043     // qDebug() << "starting operation  ... " << operation;
0044 
0045     if (operation == QLatin1String("lockScreen")) {
0046         if (m_session->canLock()) {
0047             m_session->lock();
0048             setResult(true);
0049             return;
0050         }
0051         qDebug() << "operation denied " << operation;
0052         setResult(false);
0053         return;
0054     } else if (operation == QLatin1String("suspend") || operation == QLatin1String("suspendToRam")) {
0055         if (m_session->canSuspend()) {
0056             m_session->suspend();
0057             setResult(true);
0058         } else {
0059             setResult(false);
0060         }
0061         return;
0062     } else if (operation == QLatin1String("suspendToDisk")) {
0063         if (m_session->canHibernate()) {
0064             m_session->hibernate();
0065             setResult(true);
0066         } else {
0067             setResult(false);
0068         }
0069         return;
0070     } else if (operation == QLatin1String("suspendHybrid")) {
0071         if (m_session->canHybridSuspend()) {
0072             m_session->hybridSuspend();
0073             setResult(true);
0074         } else {
0075             setResult(false);
0076         }
0077         return;
0078     } else if (operation == QLatin1String("requestShutDown")) {
0079         if (m_session->canShutdown()) {
0080             m_session->requestShutdown();
0081             setResult(true);
0082         } else {
0083             setResult(false);
0084         }
0085         return;
0086     } else if (operation == QLatin1String("switchUser")) {
0087         if (m_session->canSwitchUser()) {
0088             m_session->switchUser();
0089             setResult(true);
0090         }
0091         setResult(false);
0092         return;
0093     } else if (operation == QLatin1String("beginSuppressingSleep")) {
0094         if (m_sleepInhibitionCookie != -1) { // an inhibition request is already active; don't trigger another one
0095             setResult(true);
0096             return;
0097         }
0098         QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
0099                                                           QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
0100                                                           QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
0101                                                           QStringLiteral("Inhibit"));
0102         msg << QCoreApplication::applicationName() << parameters().value(QStringLiteral("reason")).toString();
0103         QDBusReply<uint> reply = QDBusConnection::sessionBus().call(msg);
0104         m_sleepInhibitionCookie = reply.isValid() ? reply.value() : -1;
0105         setResult(reply.isValid());
0106         return;
0107     } else if (operation == QLatin1String("stopSuppressingSleep")) {
0108         QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
0109                                                           QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
0110                                                           QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
0111                                                           QStringLiteral("UnInhibit"));
0112         msg << m_sleepInhibitionCookie;
0113         QDBusReply<void> reply = QDBusConnection::sessionBus().call(msg);
0114         m_sleepInhibitionCookie = reply.isValid() ? -1 : m_sleepInhibitionCookie; // reset cookie if the stop request was successful
0115         setResult(reply.isValid());
0116         return;
0117     } else if (operation == QLatin1String("beginSuppressingScreenPowerManagement")) {
0118         if (m_lockInhibitionCookie != -1) { // an inhibition request is already active; don't trigger another one
0119             setResult(true);
0120             return;
0121         }
0122         QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.ScreenSaver"),
0123                                                           QStringLiteral("/ScreenSaver"),
0124                                                           QStringLiteral("org.freedesktop.ScreenSaver"),
0125                                                           QStringLiteral("Inhibit"));
0126         msg << QCoreApplication::applicationName() << parameters().value(QStringLiteral("reason")).toString();
0127         QDBusReply<uint> reply = QDBusConnection::sessionBus().call(msg);
0128         m_lockInhibitionCookie = reply.isValid() ? reply.value() : -1;
0129         setResult(reply.isValid());
0130         return;
0131     } else if (operation == QLatin1String("stopSuppressingScreenPowerManagement")) {
0132         QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.ScreenSaver"),
0133                                                           QStringLiteral("/ScreenSaver"),
0134                                                           QStringLiteral("org.freedesktop.ScreenSaver"),
0135                                                           QStringLiteral("UnInhibit"));
0136         msg << m_lockInhibitionCookie;
0137         QDBusReply<uint> reply = QDBusConnection::sessionBus().call(msg);
0138         m_lockInhibitionCookie = reply.isValid() ? -1 : m_lockInhibitionCookie; // reset cookie if the stop request was successful
0139         setResult(reply.isValid());
0140         return;
0141     } else if (operation == QLatin1String("setBrightness")) {
0142         auto pending = setScreenBrightness(parameters().value(QStringLiteral("brightness")).toInt(), parameters().value(QStringLiteral("silent")).toBool());
0143         callWhenFinished(
0144             pending,
0145             [this](bool success) {
0146                 setResult(success);
0147             },
0148             this);
0149         return;
0150     } else if (operation == QLatin1String("setKeyboardBrightness")) {
0151         auto pending = setKeyboardBrightness(parameters().value(QStringLiteral("brightness")).toInt(), parameters().value(QStringLiteral("silent")).toBool());
0152         callWhenFinished(
0153             pending,
0154             [this](bool success) {
0155                 setResult(success);
0156             },
0157             this);
0158         return;
0159     } else if (operation == QLatin1String("setPowerProfile")) {
0160         auto pending = setPowerProfile(parameters().value(QStringLiteral("profile")).toString());
0161         callWhenFinished(
0162             pending,
0163             [this](bool success) {
0164                 setResult(success);
0165             },
0166             this);
0167         return;
0168     }
0169 
0170     qDebug() << "don't know what to do with " << operation;
0171     setResult(false);
0172 }
0173 
0174 QDBusPendingCall PowerManagementJob::setScreenBrightness(int value, bool silent)
0175 {
0176     QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.Solid.PowerManagement"),
0177                                                       QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"),
0178                                                       QStringLiteral("org.kde.Solid.PowerManagement.Actions.BrightnessControl"),
0179                                                       silent ? "setBrightnessSilent" : "setBrightness");
0180     msg << value;
0181     return QDBusConnection::sessionBus().asyncCall(msg);
0182 }
0183 
0184 QDBusPendingCall PowerManagementJob::setKeyboardBrightness(int value, bool silent)
0185 {
0186     QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.Solid.PowerManagement"),
0187                                                       QStringLiteral("/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl"),
0188                                                       QStringLiteral("org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl"),
0189                                                       silent ? "setKeyboardBrightnessSilent" : "setKeyboardBrightness");
0190     msg << value;
0191     return QDBusConnection::sessionBus().asyncCall(msg);
0192 }
0193 
0194 QDBusPendingCall PowerManagementJob::setPowerProfile(const QString &value)
0195 {
0196     QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.Solid.PowerManagement"),
0197                                                       QStringLiteral("/org/kde/Solid/PowerManagement/Actions/PowerProfile"),
0198                                                       QStringLiteral("org.kde.Solid.PowerManagement.Actions.PowerProfile"),
0199                                                       QStringLiteral("setProfile"));
0200     msg << value;
0201     return QDBusConnection::sessionBus().asyncCall(msg);
0202 }