1 /*
2     SPDX-FileCopyrightText: 2011 Sebastian Kügler <sebas@kde.org>
3 
4     SPDX-License-Identifier: LGPL-2.0-only
5 */
6 
7 #include <QDBusConnection>
8 #include <QDBusInterface>
9 #include <QDBusMessage>
10 #include <QDBusPendingReply>
11 
12 #include <KAuthorized>
13 
14 // kde-workspace/libs
15 #include <sessionmanagement.h>
16 
17 #include <krunner_interface.h>
18 
19 #include "powermanagementjob.h"
20 
PowerManagementJob(const QString & operation,QMap<QString,QVariant> & parameters,QObject * parent)21 PowerManagementJob::PowerManagementJob(const QString &operation, QMap<QString, QVariant> &parameters, QObject *parent)
22     : ServiceJob(parent->objectName(), operation, parameters, parent)
23     , m_session(new SessionManagement(this))
24 {
25 }
26 
~PowerManagementJob()27 PowerManagementJob::~PowerManagementJob()
28 {
29 }
30 
callWhenFinished(const QDBusPendingCall & pending,std::function<void (bool)> func,QObject * parent)31 static void callWhenFinished(const QDBusPendingCall &pending, std::function<void(bool)> func, QObject *parent)
32 {
33     QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(pending, parent);
34     QObject::connect(watcher, &QDBusPendingCallWatcher::finished, parent, [func](QDBusPendingCallWatcher *watcher) {
35         watcher->deleteLater();
36         func(!watcher->isError());
37     });
38 }
39 
start()40 void PowerManagementJob::start()
41 {
42     const QString operation = operationName();
43     // qDebug() << "starting operation  ... " << operation;
44 
45     if (operation == QLatin1String("lockScreen")) {
46         if (m_session->canLock()) {
47             m_session->lock();
48             setResult(true);
49             return;
50         }
51         qDebug() << "operation denied " << operation;
52         setResult(false);
53         return;
54     } else if (operation == QLatin1String("suspend") || operation == QLatin1String("suspendToRam")) {
55         if (m_session->canSuspend()) {
56             m_session->suspend();
57             setResult(true);
58         } else {
59             setResult(false);
60         }
61         return;
62     } else if (operation == QLatin1String("suspendToDisk")) {
63         if (m_session->canHibernate()) {
64             m_session->hibernate();
65             setResult(true);
66         } else {
67             setResult(false);
68         }
69         return;
70     } else if (operation == QLatin1String("suspendHybrid")) {
71         if (m_session->canHybridSuspend()) {
72             m_session->hybridSuspend();
73             setResult(true);
74         } else {
75             setResult(false);
76         }
77         return;
78     } else if (operation == QLatin1String("requestShutDown")) {
79         if (m_session->canShutdown()) {
80             m_session->requestShutdown();
81             setResult(true);
82         } else {
83             setResult(false);
84         }
85         return;
86     } else if (operation == QLatin1String("switchUser")) {
87         if (m_session->canSwitchUser()) {
88             m_session->switchUser();
89             setResult(true);
90         }
91         setResult(false);
92         return;
93     } else if (operation == QLatin1String("beginSuppressingSleep")) {
94         QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
95                                                           QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
96                                                           QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
97                                                           QStringLiteral("Inhibit"));
98         msg << QCoreApplication::applicationName() << parameters().value(QStringLiteral("reason")).toString();
99         QDBusReply<uint> reply = QDBusConnection::sessionBus().call(msg);
100         setResult(reply.isValid() ? reply.value() : -1);
101         return;
102     } else if (operation == QLatin1String("stopSuppressingSleep")) {
103         QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
104                                                           QStringLiteral("/org/freedesktop/PowerManagement/Inhibit"),
105                                                           QStringLiteral("org.freedesktop.PowerManagement.Inhibit"),
106                                                           QStringLiteral("UnInhibit"));
107         msg << parameters().value(QStringLiteral("cookie")).toUInt();
108         QDBusReply<void> reply = QDBusConnection::sessionBus().call(msg);
109         setResult(reply.isValid());
110         return;
111     } else if (operation == QLatin1String("beginSuppressingScreenPowerManagement")) {
112         QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.ScreenSaver"),
113                                                           QStringLiteral("/ScreenSaver"),
114                                                           QStringLiteral("org.freedesktop.ScreenSaver"),
115                                                           QStringLiteral("Inhibit"));
116         msg << QCoreApplication::applicationName() << parameters().value(QStringLiteral("reason")).toString();
117         QDBusReply<uint> reply = QDBusConnection::sessionBus().call(msg);
118         setResult(reply.isValid() ? reply.value() : -1);
119         return;
120     } else if (operation == QLatin1String("stopSuppressingScreenPowerManagement")) {
121         QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.ScreenSaver"),
122                                                           QStringLiteral("/ScreenSaver"),
123                                                           QStringLiteral("org.freedesktop.ScreenSaver"),
124                                                           QStringLiteral("UnInhibit"));
125         msg << parameters().value(QStringLiteral("cookie")).toUInt();
126         QDBusReply<uint> reply = QDBusConnection::sessionBus().call(msg);
127         setResult(reply.isValid());
128         return;
129     } else if (operation == QLatin1String("setBrightness")) {
130         auto pending = setScreenBrightness(parameters().value(QStringLiteral("brightness")).toInt(), parameters().value(QStringLiteral("silent")).toBool());
131         callWhenFinished(
132             pending,
133             [this] (bool success) {
134                 setResult(success);
135             },
136             this);
137         return;
138     } else if (operation == QLatin1String("setKeyboardBrightness")) {
139         auto pending = setKeyboardBrightness(parameters().value(QStringLiteral("brightness")).toInt(), parameters().value(QStringLiteral("silent")).toBool());
140         callWhenFinished(
141             pending,
142             [this] (bool success) {
143                 setResult(success);
144             },
145             this);
146         return;
147     } else if (operation == QLatin1String("setPowerProfile")) {
148         auto pending = setPowerProfile(parameters().value(QStringLiteral("profile")).toString());
149         callWhenFinished(
150             pending,
151             [this] (bool success) {
152                 setResult(success);
153             },
154             this);
155         return;
156     }
157 
158     qDebug() << "don't know what to do with " << operation;
159     setResult(false);
160 }
161 
setScreenBrightness(int value,bool silent)162 QDBusPendingCall PowerManagementJob::setScreenBrightness(int value, bool silent)
163 {
164     QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.Solid.PowerManagement"),
165                                                       QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"),
166                                                       QStringLiteral("org.kde.Solid.PowerManagement.Actions.BrightnessControl"),
167                                                       silent ? "setBrightnessSilent" : "setBrightness");
168     msg << value;
169     return QDBusConnection::sessionBus().asyncCall(msg);
170 }
171 
setKeyboardBrightness(int value,bool silent)172 QDBusPendingCall PowerManagementJob::setKeyboardBrightness(int value, bool silent)
173 {
174     QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.Solid.PowerManagement"),
175                                                       QStringLiteral("/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl"),
176                                                       QStringLiteral("org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl"),
177                                                       silent ? "setKeyboardBrightnessSilent" : "setKeyboardBrightness");
178     msg << value;
179     return QDBusConnection::sessionBus().asyncCall(msg);
180 }
181 
setPowerProfile(const QString & value)182 QDBusPendingCall PowerManagementJob::setPowerProfile(const QString &value)
183 {
184     QDBusMessage msg = QDBusMessage::createMethodCall(QStringLiteral("org.kde.Solid.PowerManagement"),
185                                                       QStringLiteral("/org/kde/Solid/PowerManagement/Actions/PowerProfile"),
186                                                       QStringLiteral("org.kde.Solid.PowerManagement.Actions.PowerProfile"),
187                                                       QStringLiteral("setProfile"));
188     msg << value;
189     return QDBusConnection::sessionBus().asyncCall(msg);
190 }
191