File indexing completed on 2024-03-24 05:30:33
0001 /* 0002 SPDX-FileCopyrightText: 1999 Martin R. Jones <mjones@kde.org> 0003 SPDX-FileCopyrightText: 2011 Martin Gräßlin <mgraesslin@kde.org> 0004 0005 SPDX-License-Identifier: GPL-2.0-or-later 0006 */ 0007 #include "interface.h" 0008 #include "kscreensaveradaptor.h" 0009 #include "ksldapp.h" 0010 #include "powerdevilpolicyagent.h" 0011 #include "screensaveradaptor.h" 0012 // KDE 0013 #include <KAuthorized> 0014 #include <KIdleTime> 0015 #include <KWindowSystem> 0016 // Qt 0017 #include <QDBusConnection> 0018 #include <QDBusContext> 0019 #include <QDBusReply> 0020 #include <QDBusServiceWatcher> 0021 #include <QRandomGenerator> 0022 0023 namespace ScreenLocker 0024 { 0025 const uint ChangeScreenSettings = 4; 0026 0027 Interface::Interface(KSldApp *parent) 0028 : QObject(parent) 0029 , m_daemon(parent) 0030 , m_serviceWatcher(new QDBusServiceWatcher(this)) 0031 , m_next_cookie(0) 0032 { 0033 (void)new ScreenSaverAdaptor(this); 0034 QDBusConnection::sessionBus().registerService(QStringLiteral("org.freedesktop.ScreenSaver")); 0035 (void)new KScreenSaverAdaptor(this); 0036 QDBusConnection::sessionBus().registerService(QStringLiteral("org.kde.screensaver")); 0037 QDBusConnection::sessionBus().registerObject(QStringLiteral("/ScreenSaver"), this); 0038 QDBusConnection::sessionBus().registerObject(QStringLiteral("/org/freedesktop/ScreenSaver"), this); 0039 connect(m_daemon, &KSldApp::locked, this, &Interface::slotLocked); 0040 connect(m_daemon, &KSldApp::unlocked, this, &Interface::slotUnlocked); 0041 connect(m_daemon, &KSldApp::aboutToLock, this, &Interface::AboutToLock); 0042 0043 m_serviceWatcher->setConnection(QDBusConnection::sessionBus()); 0044 m_serviceWatcher->setWatchMode(QDBusServiceWatcher::WatchForUnregistration); 0045 connect(m_serviceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, &Interface::serviceUnregistered); 0046 0047 // I make it a really random number to avoid 0048 // some assumptions in clients, but just increase 0049 // while gnome-ss creates a random number every time 0050 m_next_cookie = QRandomGenerator::global()->bounded(19999); 0051 } 0052 0053 Interface::~Interface() 0054 { 0055 } 0056 0057 bool Interface::GetActive() 0058 { 0059 return m_daemon->lockState() == KSldApp::Locked; 0060 } 0061 0062 uint Interface::GetActiveTime() 0063 { 0064 return m_daemon->activeTime(); 0065 } 0066 0067 uint Interface::GetSessionIdleTime() 0068 { 0069 if (KWindowSystem::isPlatformWayland()) { 0070 QDBusContext::sendErrorReply(QDBusError::NotSupported, QStringLiteral("GetSessionIdleTime is not supported on this platform")); 0071 return 0; 0072 } 0073 return KIdleTime::instance()->idleTime(); 0074 } 0075 0076 void Interface::Lock() 0077 { 0078 if (!KAuthorized::authorizeAction(QStringLiteral("lock_screen"))) { 0079 return; 0080 } 0081 m_daemon->lock(calledFromDBus() ? EstablishLock::Immediate : EstablishLock::Delayed); 0082 0083 if (calledFromDBus() && m_daemon->lockState() == KSldApp::AcquiringLock) { 0084 m_lockReplies << message().createReply(); 0085 setDelayedReply(true); 0086 } 0087 } 0088 0089 void Interface::SwitchUser() 0090 { 0091 if (!KAuthorized::authorizeAction(QStringLiteral("lock_screen"))) { 0092 return; 0093 } 0094 m_daemon->lock(EstablishLock::DefaultToSwitchUser); 0095 0096 if (calledFromDBus() && m_daemon->lockState() == KSldApp::AcquiringLock) { 0097 m_lockReplies << message().createReply(); 0098 setDelayedReply(true); 0099 } 0100 } 0101 0102 bool Interface::SetActive(bool state) 0103 { 0104 // TODO: what should the return value be? 0105 if (state) { 0106 Lock(); 0107 return true; 0108 } 0109 // set inactive is ignored 0110 return false; 0111 } 0112 0113 uint Interface::Inhibit(const QString &application_name, const QString &reason_for_inhibit) 0114 { 0115 OrgKdeSolidPowerManagementPolicyAgentInterface policyAgent(QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent"), 0116 QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent"), 0117 QDBusConnection::sessionBus()); 0118 QDBusReply<uint> reply = policyAgent.AddInhibition(ChangeScreenSettings, application_name, reason_for_inhibit); 0119 0120 InhibitRequest sr; 0121 sr.cookie = m_next_cookie++; 0122 sr.dbusid = message().service(); 0123 sr.powerdevilcookie = reply.isValid() ? reply : 0; 0124 m_requests.append(sr); 0125 m_serviceWatcher->addWatchedService(sr.dbusid); 0126 KSldApp::self()->inhibit(); 0127 return sr.cookie; 0128 } 0129 0130 void Interface::UnInhibit(uint cookie) 0131 { 0132 QMutableListIterator<InhibitRequest> it(m_requests); 0133 while (it.hasNext()) { 0134 if (it.next().cookie == cookie) { 0135 if (uint powerdevilcookie = it.value().powerdevilcookie) { 0136 OrgKdeSolidPowerManagementPolicyAgentInterface policyAgent(QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent"), 0137 QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent"), 0138 QDBusConnection::sessionBus()); 0139 policyAgent.ReleaseInhibition(powerdevilcookie); 0140 } 0141 it.remove(); 0142 KSldApp::self()->uninhibit(); 0143 break; 0144 } 0145 } 0146 } 0147 0148 void Interface::serviceUnregistered(const QString &name) 0149 { 0150 m_serviceWatcher->removeWatchedService(name); 0151 QListIterator<InhibitRequest> it(m_requests); 0152 while (it.hasNext()) { 0153 const InhibitRequest &r = it.next(); 0154 if (r.dbusid == name) { 0155 UnInhibit(r.cookie); 0156 } 0157 } 0158 } 0159 0160 void Interface::SimulateUserActivity() 0161 { 0162 KIdleTime::instance()->simulateUserActivity(); 0163 } 0164 0165 uint Interface::Throttle(const QString &application_name, const QString &reason_for_inhibit) 0166 { 0167 Q_UNUSED(application_name) 0168 Q_UNUSED(reason_for_inhibit) 0169 // TODO: implement me 0170 return 0; 0171 } 0172 0173 void Interface::UnThrottle(uint cookie) 0174 { 0175 Q_UNUSED(cookie) 0176 // TODO: implement me 0177 } 0178 0179 void Interface::slotLocked() 0180 { 0181 sendLockReplies(); 0182 Q_EMIT ActiveChanged(true); 0183 } 0184 0185 void Interface::slotUnlocked() 0186 { 0187 sendLockReplies(); 0188 Q_EMIT ActiveChanged(false); 0189 } 0190 0191 void Interface::configure() 0192 { 0193 m_daemon->configure(); 0194 } 0195 0196 void Interface::sendLockReplies() 0197 { 0198 for (const QDBusMessage &reply : std::as_const(m_lockReplies)) { 0199 QDBusConnection::sessionBus().send(reply); 0200 } 0201 0202 m_lockReplies.clear(); 0203 } 0204 0205 } // namespace 0206 0207 #include "moc_interface.cpp"