File indexing completed on 2024-04-28 16:54:32

0001 /*
0002     SPDX-FileCopyrightText: 2019 David Edmundson <davidedmundson@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "sessionmanagement.h"
0008 
0009 #include "sessionmanagementbackend.h"
0010 
0011 #include <KAuthorized>
0012 #include <KConfigGroup>
0013 #include <KSharedConfig>
0014 
0015 #include "kscreenlocker_interface.h"
0016 #include "ksmserver_interface.h"
0017 #include "logoutprompt_interface.h"
0018 #include "screenlocker_interface.h"
0019 #include "shutdown_interface.h"
0020 
0021 // add a constructor with the service names and paths pre-populated
0022 class LogoutPromptIface : public OrgKdeLogoutPromptInterface
0023 {
0024     Q_OBJECT
0025 public:
0026     LogoutPromptIface()
0027         : OrgKdeLogoutPromptInterface(QStringLiteral("org.kde.LogoutPrompt"), QStringLiteral("/LogoutPrompt"), QDBusConnection::sessionBus())
0028     {
0029     }
0030 };
0031 
0032 class ShutdownIface : public OrgKdeShutdownInterface
0033 {
0034     Q_OBJECT
0035 public:
0036     ShutdownIface()
0037         : OrgKdeShutdownInterface(QStringLiteral("org.kde.Shutdown"), QStringLiteral("/Shutdown"), QDBusConnection::sessionBus())
0038     {
0039     }
0040 };
0041 
0042 SessionManagement::SessionManagement(QObject *parent)
0043     : QObject(parent)
0044 {
0045     auto backend = SessionBackend::self();
0046     connect(backend, &SessionBackend::stateChanged, this, &SessionManagement::stateChanged);
0047     connect(backend, &SessionBackend::canShutdownChanged, this, &SessionManagement::canShutdownChanged);
0048     connect(backend, &SessionBackend::canRebootChanged, this, &SessionManagement::canRebootChanged);
0049     connect(backend, &SessionBackend::canSuspendChanged, this, &SessionManagement::canSuspendChanged);
0050     connect(backend, &SessionBackend::canHybridSuspendChanged, this, &SessionManagement::canHybridSuspendChanged);
0051     connect(backend, &SessionBackend::canHibernateChanged, this, &SessionManagement::canHibernateChanged);
0052     connect(backend, &SessionBackend::aboutToSuspend, this, &SessionManagement::aboutToSuspend);
0053     connect(backend, &SessionBackend::resumingFromSuspend, this, &SessionManagement::resumingFromSuspend);
0054 }
0055 
0056 bool SessionManagement::canShutdown() const
0057 {
0058     return canLogout() && SessionBackend::self()->canShutdown();
0059 }
0060 
0061 bool SessionManagement::canReboot() const
0062 {
0063     return canLogout() && SessionBackend::self()->canReboot();
0064 }
0065 
0066 bool SessionManagement::canLogout() const
0067 {
0068     // checking both is for compatibility with old kiosk configs
0069     // authorizeAction is the "correct" one
0070     return KAuthorized::authorizeAction(QStringLiteral("logout")) && KAuthorized::authorize(QStringLiteral("logout"));
0071 }
0072 
0073 bool SessionManagement::canSuspend() const
0074 {
0075     return SessionBackend::self()->canSuspend();
0076 }
0077 
0078 bool SessionManagement::canHybridSuspend() const
0079 {
0080     return SessionBackend::self()->canHybridSuspend();
0081 }
0082 
0083 bool SessionManagement::canHibernate() const
0084 {
0085     return SessionBackend::self()->canHibernate();
0086 }
0087 
0088 bool SessionManagement::canSwitchUser() const
0089 {
0090     return KAuthorized::authorizeAction(QStringLiteral("start_new_session"));
0091 }
0092 
0093 bool SessionManagement::canLock() const
0094 {
0095     return KAuthorized::authorizeAction(QStringLiteral("lock_screen"));
0096 }
0097 
0098 bool SessionManagement::canSaveSession() const
0099 {
0100     const KConfigGroup c(KSharedConfig::openConfig(QStringLiteral("ksmserverrc")), "General");
0101     return canLogout() && c.readEntry("loginMode") == QLatin1String("restoreSavedSession");
0102 }
0103 
0104 SessionManagement::State SessionManagement::state() const
0105 {
0106     return SessionBackend::self()->state();
0107 }
0108 
0109 void SessionManagement::requestShutdown(ConfirmationMode confirmationMode)
0110 {
0111     if (!canShutdown()) {
0112         return;
0113     }
0114 
0115     if (qEnvironmentVariableIntValue("PLASMA_SESSION_GUI_TEST")) {
0116         qWarning() << "shutdown";
0117         return;
0118     }
0119 
0120     bool confirm = confirmationMode == ConfirmationMode::ForcePrompt;
0121     if (confirmationMode == ConfirmationMode::Default) {
0122         confirm = SessionBackend::self()->confirmLogout();
0123     }
0124     if (confirm) {
0125         LogoutPromptIface iface;
0126         iface.promptShutDown().waitForFinished();
0127     } else {
0128         ShutdownIface iface;
0129         iface.logoutAndShutdown().waitForFinished();
0130     }
0131 }
0132 
0133 void SessionManagement::requestReboot(ConfirmationMode confirmationMode)
0134 {
0135     if (!canReboot()) {
0136         return;
0137     }
0138 
0139     if (qEnvironmentVariableIntValue("PLASMA_SESSION_GUI_TEST")) {
0140         qWarning() << "reboot";
0141         return;
0142     }
0143 
0144     bool confirm = confirmationMode == ConfirmationMode::ForcePrompt;
0145     if (confirmationMode == ConfirmationMode::Default) {
0146         confirm = SessionBackend::self()->confirmLogout();
0147     }
0148     if (confirm) {
0149         LogoutPromptIface iface;
0150         iface.promptReboot().waitForFinished();
0151     } else {
0152         ShutdownIface iface;
0153         iface.logoutAndReboot().waitForFinished();
0154     }
0155 }
0156 
0157 void SessionManagement::requestLogout(ConfirmationMode confirmationMode)
0158 {
0159     if (!canLogout()) {
0160         return;
0161     }
0162     bool confirm = confirmationMode == ConfirmationMode::ForcePrompt;
0163     if (confirmationMode == ConfirmationMode::Default) {
0164         confirm = SessionBackend::self()->confirmLogout();
0165     }
0166     if (confirm) {
0167         LogoutPromptIface iface;
0168         iface.promptLogout().waitForFinished();
0169     } else {
0170         ShutdownIface iface;
0171         iface.logout().waitForFinished();
0172     }
0173 }
0174 
0175 void SessionManagement::suspend()
0176 {
0177     if (!canSuspend()) {
0178         return;
0179     }
0180     SessionBackend::self()->suspend();
0181 }
0182 
0183 void SessionManagement::hybridSuspend()
0184 {
0185     if (!canHybridSuspend()) {
0186         return;
0187     }
0188     SessionBackend::self()->hybridSuspend();
0189 }
0190 
0191 void SessionManagement::hibernate()
0192 {
0193     if (!canHibernate()) {
0194         return;
0195     }
0196     SessionBackend::self()->hibernate();
0197 }
0198 
0199 void SessionManagement::lock()
0200 {
0201     if (!canLock()) {
0202         return;
0203     }
0204     OrgFreedesktopScreenSaverInterface iface(QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("/ScreenSaver"), QDBusConnection::sessionBus());
0205     iface.Lock();
0206 }
0207 
0208 void SessionManagement::switchUser()
0209 {
0210     if (!canSwitchUser()) {
0211         return;
0212     }
0213     OrgKdeScreensaverInterface iface(QStringLiteral("org.freedesktop.ScreenSaver"), QStringLiteral("/ScreenSaver"), QDBusConnection::sessionBus());
0214     iface.SwitchUser();
0215 }
0216 
0217 void SessionManagement::saveSession()
0218 {
0219     if (!canSaveSession()) {
0220         return;
0221     }
0222     OrgKdeKSMServerInterfaceInterface ksmserver(QStringLiteral("org.kde.ksmserver"), QStringLiteral("/KSMServer"), QDBusConnection::sessionBus());
0223     ksmserver.saveCurrentSession();
0224 }
0225 
0226 #include "sessionmanagement.moc"