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