File indexing completed on 2024-05-19 05:36:15

0001 /*
0002     kcmsmserver.cpp
0003     SPDX-FileCopyrightText: 2000, 2002 Oswald Buddenhagen <ossi@kde.org>
0004 
0005     based on kcmtaskbar.cpp
0006     SPDX-FileCopyrightText: 2000 Kurt Granroth <granroth@kde.org>
0007 
0008     SPDX-FileCopyrightText: 2019 Kevin Ottens <kevin.ottens@enioka.com>
0009     SPDX-FileCopyrightText: 2020 Carl Schwan <carl@carlschwan.eu>
0010 
0011     SPDX-License-Identifier: GPL-2.0-or-later
0012 */
0013 
0014 #include <QAction>
0015 #include <QDBusConnection>
0016 #include <QDBusPendingCallWatcher>
0017 #include <QDBusPendingReply>
0018 #include <QFileInfo>
0019 
0020 #include <KDesktopFile>
0021 #include <KPluginFactory>
0022 #include <KProcess>
0023 #include <QDBusInterface>
0024 
0025 #include "kcmsmserver.h"
0026 #include "smserverdata.h"
0027 #include "smserversettings.h"
0028 
0029 #include <KLocalizedString>
0030 
0031 #include <sessionmanagement.h>
0032 
0033 #include "login1_manager.h"
0034 
0035 K_PLUGIN_FACTORY_WITH_JSON(SMServerConfigFactory, "kcm_smserver.json", registerPlugin<SMServerConfig>(); registerPlugin<SMServerData>();)
0036 
0037 SMServerConfig::SMServerConfig(QObject *parent, const KPluginMetaData &metaData)
0038     : KQuickManagedConfigModule(parent, metaData)
0039     , m_login1Manager(new OrgFreedesktopLogin1ManagerInterface(QStringLiteral("org.freedesktop.login1"),
0040                                                                QStringLiteral("/org/freedesktop/login1"),
0041                                                                QDBusConnection::systemBus(),
0042                                                                this))
0043 {
0044     auto settings = new SMServerSettings(this);
0045     qmlRegisterSingletonInstance("org.kde.desktopsession.private", 1, 0, "Settings", settings);
0046 
0047     checkFirmwareSetupRequested();
0048     m_restartInSetupScreenInitial = m_restartInSetupScreen;
0049 
0050     setButtons(Help | Apply | Default);
0051 
0052     const QString canFirmwareSetup = m_login1Manager->CanRebootToFirmwareSetup().value();
0053     if (canFirmwareSetup == QLatin1String("yes") || canFirmwareSetup == QLatin1String("challenge")) {
0054         m_canFirmwareSetup = true;
0055         // now check whether we're UEFI to provide a more descriptive button label
0056         if (QFileInfo(QStringLiteral("/sys/firmware/efi")).isDir()) {
0057             m_isUefi = true;
0058         }
0059     }
0060 }
0061 
0062 SMServerConfig::~SMServerConfig() = default;
0063 
0064 bool SMServerConfig::isUefi() const
0065 {
0066     return m_isUefi;
0067 }
0068 
0069 bool SMServerConfig::restartInSetupScreen() const
0070 {
0071     return m_restartInSetupScreen;
0072 }
0073 
0074 void SMServerConfig::setRestartInSetupScreen(bool restartInSetupScreen)
0075 {
0076     if (m_restartInSetupScreen == restartInSetupScreen) {
0077         return;
0078     }
0079 
0080     QDBusMessage message = QDBusMessage::createMethodCall(m_login1Manager->service(),
0081                                                           m_login1Manager->path(),
0082                                                           m_login1Manager->interface(),
0083                                                           QStringLiteral("SetRebootToFirmwareSetup"));
0084 
0085     message.setArguments({restartInSetupScreen});
0086     // This cannot be set through a generated DBus interface, so we have to create the message ourself.
0087     message.setInteractiveAuthorizationAllowed(true);
0088 
0089     QDBusPendingReply<void> call = m_login1Manager->connection().asyncCall(message);
0090     QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(call, this);
0091     connect(callWatcher, &QDBusPendingCallWatcher::finished, this, [this, restartInSetupScreen](QDBusPendingCallWatcher *watcher) {
0092         QDBusPendingReply<void> reply = *watcher;
0093         watcher->deleteLater();
0094 
0095         checkFirmwareSetupRequested();
0096 
0097         settingsChanged();
0098 
0099         if (reply.isError()) {
0100             // User likely canceled the PolKit prompt, don't show an error in this case
0101             if (reply.error().type() != QDBusError::AccessDenied) {
0102                 m_error = reply.error().message();
0103                 Q_EMIT errorChanged();
0104             }
0105             return;
0106         } else if (m_error.length() > 0) {
0107             m_error = QString();
0108             Q_EMIT errorChanged();
0109         }
0110         m_restartInSetupScreen = restartInSetupScreen;
0111         Q_EMIT restartInSetupScreenChanged();
0112 
0113         if (!restartInSetupScreen) {
0114             return;
0115         }
0116     });
0117 }
0118 
0119 QString SMServerConfig::error() const
0120 {
0121     return m_error;
0122 }
0123 
0124 void SMServerConfig::reboot()
0125 {
0126     auto sm = new SessionManagement(this);
0127     auto doShutdown = [sm]() {
0128         sm->requestReboot();
0129         delete sm;
0130     };
0131     if (sm->state() == SessionManagement::State::Loading) {
0132         connect(sm, &SessionManagement::stateChanged, this, doShutdown);
0133     } else {
0134         doShutdown();
0135     }
0136 }
0137 
0138 void SMServerConfig::checkFirmwareSetupRequested()
0139 {
0140     m_restartInSetupScreen = m_login1Manager->property("RebootToFirmwareSetup").toBool();
0141     Q_EMIT restartInSetupScreenChanged();
0142 }
0143 
0144 bool SMServerConfig::canFirmwareSetup() const
0145 {
0146     return m_canFirmwareSetup;
0147 }
0148 
0149 bool SMServerConfig::isSaveNeeded() const
0150 {
0151     return m_restartInSetupScreen != m_restartInSetupScreenInitial;
0152 }
0153 
0154 bool SMServerConfig::isDefaults() const
0155 {
0156     return !m_restartInSetupScreen;
0157 }
0158 
0159 void SMServerConfig::defaults()
0160 {
0161     KQuickManagedConfigModule::defaults();
0162     setRestartInSetupScreen(false);
0163 }
0164 
0165 void SMServerConfig::save()
0166 {
0167     KQuickManagedConfigModule::save();
0168     Q_EMIT ksmserverSettingsChanged();
0169 }
0170 
0171 #include "kcmsmserver.moc"