1 /*
2 SPDX-FileCopyrightText: 2019 David Edmundson <davidedmundson@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5 */
6
7 #include "sessionmanagement.h"
8
9 #include "sessionmanagementbackend.h"
10
11 #include <KAuthorized>
12 #include <KConfigGroup>
13 #include <KSharedConfig>
14
15 #include "kscreenlocker_interface.h"
16 #include "ksmserver_interface.h"
17 #include "logoutprompt_interface.h"
18 #include "screenlocker_interface.h"
19 #include "shutdown_interface.h"
20
21 // add a constructor with the service names and paths pre-populated
22 class LogoutPromptIface : public OrgKdeLogoutPromptInterface
23 {
24 Q_OBJECT
25 public:
LogoutPromptIface()26 LogoutPromptIface()
27 : OrgKdeLogoutPromptInterface(QStringLiteral("org.kde.LogoutPrompt"), QStringLiteral("/LogoutPrompt"), QDBusConnection::sessionBus())
28 {
29 }
30 };
31
32 class ShutdownIface : public OrgKdeShutdownInterface
33 {
34 Q_OBJECT
35 public:
ShutdownIface()36 ShutdownIface()
37 : OrgKdeShutdownInterface(QStringLiteral("org.kde.Shutdown"), QStringLiteral("/Shutdown"), QDBusConnection::sessionBus())
38 {
39 }
40 };
41
SessionManagement(QObject * parent)42 SessionManagement::SessionManagement(QObject *parent)
43 : QObject(parent)
44 {
45 auto backend = SessionBackend::self();
46 connect(backend, &SessionBackend::stateChanged, this, &SessionManagement::stateChanged);
47 connect(backend, &SessionBackend::canShutdownChanged, this, &SessionManagement::canShutdownChanged);
48 connect(backend, &SessionBackend::canRebootChanged, this, &SessionManagement::canRebootChanged);
49 connect(backend, &SessionBackend::canSuspendChanged, this, &SessionManagement::canSuspendChanged);
50 connect(backend, &SessionBackend::canHybridSuspendChanged, this, &SessionManagement::canHybridSuspendChanged);
51 connect(backend, &SessionBackend::canHibernateChanged, this, &SessionManagement::canHibernateChanged);
52 connect(backend, &SessionBackend::aboutToSuspend, this, &SessionManagement::aboutToSuspend);
53 connect(backend, &SessionBackend::resumingFromSuspend, this, &SessionManagement::resumingFromSuspend);
54 }
55
canShutdown() const56 bool SessionManagement::canShutdown() const
57 {
58 return canLogout() && SessionBackend::self()->canShutdown();
59 }
60
canReboot() const61 bool SessionManagement::canReboot() const
62 {
63 return canLogout() && SessionBackend::self()->canReboot();
64 }
65
canLogout() const66 bool SessionManagement::canLogout() const
67 {
68 // checking both is for compatibility with old kiosk configs
69 // authorizeAction is the "correct" one
70 return KAuthorized::authorizeAction(QStringLiteral("logout")) && KAuthorized::authorize(QStringLiteral("logout"));
71 }
72
canSuspend() const73 bool SessionManagement::canSuspend() const
74 {
75 return SessionBackend::self()->canSuspend();
76 }
77
canHybridSuspend() const78 bool SessionManagement::canHybridSuspend() const
79 {
80 return SessionBackend::self()->canHybridSuspend();
81 }
82
canHibernate() const83 bool SessionManagement::canHibernate() const
84 {
85 return SessionBackend::self()->canHibernate();
86 }
87
canSwitchUser() const88 bool SessionManagement::canSwitchUser() const
89 {
90 return KAuthorized::authorizeAction(QStringLiteral("start_new_session"));
91 }
92
canLock() const93 bool SessionManagement::canLock() const
94 {
95 return KAuthorized::authorizeAction(QStringLiteral("lock_screen"));
96 }
97
canSaveSession() const98 bool SessionManagement::canSaveSession() const
99 {
100 const KConfigGroup c(KSharedConfig::openConfig(QStringLiteral("ksmserverrc")), "General");
101 return canLogout() && c.readEntry("loginMode") == QLatin1String("restoreSavedSession");
102 }
103
state() const104 SessionManagement::State SessionManagement::state() const
105 {
106 return SessionBackend::self()->state();
107 }
108
requestShutdown(ConfirmationMode confirmationMode)109 void SessionManagement::requestShutdown(ConfirmationMode confirmationMode)
110 {
111 if (!canShutdown()) {
112 return;
113 }
114 bool confirm = confirmationMode == ConfirmationMode::ForcePrompt;
115 if (confirmationMode == ConfirmationMode::Default) {
116 confirm = SessionBackend::self()->confirmLogout();
117 }
118 if (confirm) {
119 LogoutPromptIface iface;
120 iface.promptShutDown().waitForFinished();
121 } else {
122 ShutdownIface iface;
123 iface.logoutAndShutdown().waitForFinished();
124 }
125 }
126
requestReboot(ConfirmationMode confirmationMode)127 void SessionManagement::requestReboot(ConfirmationMode confirmationMode)
128 {
129 if (!canReboot()) {
130 return;
131 }
132 bool confirm = confirmationMode == ConfirmationMode::ForcePrompt;
133 if (confirmationMode == ConfirmationMode::Default) {
134 confirm = SessionBackend::self()->confirmLogout();
135 }
136 if (confirm) {
137 LogoutPromptIface iface;
138 iface.promptReboot().waitForFinished();
139 } else {
140 ShutdownIface iface;
141 iface.logoutAndReboot().waitForFinished();
142 }
143 }
144
requestLogout(ConfirmationMode confirmationMode)145 void SessionManagement::requestLogout(ConfirmationMode confirmationMode)
146 {
147 if (!canLogout()) {
148 return;
149 }
150 bool confirm = confirmationMode == ConfirmationMode::ForcePrompt;
151 if (confirmationMode == ConfirmationMode::Default) {
152 confirm = SessionBackend::self()->confirmLogout();
153 }
154 if (confirm) {
155 LogoutPromptIface iface;
156 iface.promptLogout().waitForFinished();
157 } else {
158 ShutdownIface iface;
159 iface.logout().waitForFinished();
160 }
161 }
162
suspend()163 void SessionManagement::suspend()
164 {
165 if (!canSuspend()) {
166 return;
167 }
168 SessionBackend::self()->suspend();
169 }
170
hybridSuspend()171 void SessionManagement::hybridSuspend()
172 {
173 if (!canHybridSuspend()) {
174 return;
175 }
176 SessionManagement::hybridSuspend();
177 }
178
hibernate()179 void SessionManagement::hibernate()
180 {
181 if (!canHibernate()) {
182 return;
183 }
184 SessionBackend::self()->hibernate();
185 }
186
lock()187 void SessionManagement::lock()
188 {
189 if (!canLock()) {
190 return;
191 }
192 OrgFreedesktopScreenSaverInterface iface(QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("/ScreenSaver"), QDBusConnection::sessionBus());
193 iface.Lock();
194 }
195
switchUser()196 void SessionManagement::switchUser()
197 {
198 if (!canSwitchUser()) {
199 return;
200 }
201 OrgKdeScreensaverInterface iface(QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("/ScreenSaver"), QDBusConnection::sessionBus());
202 iface.SwitchUser();
203 }
204
saveSession()205 void SessionManagement::saveSession()
206 {
207 if (!canSaveSession()) {
208 return;
209 }
210 OrgKdeKSMServerInterfaceInterface ksmserver(QStringLiteral("org.kde.ksmserver"), QStringLiteral("/KSMServer"), QDBusConnection::sessionBus());
211 ksmserver.saveCurrentSession();
212 }
213
214 #include "sessionmanagement.moc"
215