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"