Warning, file /plasma/kscreenlocker/interface.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

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