File indexing completed on 2021-12-21 14:17:30

0001 /********************************************************************
0002  KSld - the KDE Screenlocker Daemon
0003  This file is part of the KDE project.
0004 
0005  Copyright (C) 2016 Martin Gräßlin <mgraesslin@kde.org>
0006 
0007 This program is free software; you can redistribute it and/or modify
0008 it under the terms of the GNU General Public License as published by
0009 the Free Software Foundation; either version 2 of the License, or
0010 (at your option) any later version.
0011 
0012 This program is distributed in the hope that it will be useful,
0013 but WITHOUT ANY WARRANTY; without even the implied warranty of
0014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0015 GNU General Public License for more details.
0016 
0017 You should have received a copy of the GNU General Public License
0018 along with this program.  If not, see <http://www.gnu.org/licenses/>.
0019 *********************************************************************/
0020 #include "powermanagement_inhibition.h"
0021 
0022 #include <QDBusConnection>
0023 #include <QDBusMessage>
0024 #include <QDBusMetaType>
0025 #include <QDBusPendingCallWatcher>
0026 #include <QDBusPendingReply>
0027 #include <QDBusServiceWatcher>
0028 
0029 static const QString s_solidPowerService = QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent");
0030 static const QString s_solidPath = QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent");
0031 
0032 Q_DECLARE_METATYPE(QList<InhibitionInfo>)
0033 Q_DECLARE_METATYPE(InhibitionInfo)
0034 
0035 PowerManagementInhibition::PowerManagementInhibition(QObject *parent)
0036     : QObject(parent)
0037     , m_solidPowerServiceWatcher(new QDBusServiceWatcher(s_solidPowerService,
0038                                                          QDBusConnection::sessionBus(),
0039                                                          QDBusServiceWatcher::WatchForUnregistration | QDBusServiceWatcher::WatchForRegistration))
0040 {
0041     qDBusRegisterMetaType<QList<InhibitionInfo>>();
0042     qDBusRegisterMetaType<InhibitionInfo>();
0043 
0044     connect(m_solidPowerServiceWatcher, &QDBusServiceWatcher::serviceUnregistered, this, [this] {
0045         m_serviceRegistered = false;
0046         m_inhibited = false;
0047         QDBusConnection::sessionBus().disconnect(s_solidPowerService,
0048                                                  s_solidPath,
0049                                                  s_solidPowerService,
0050                                                  QStringLiteral("InhibitionsChanged"),
0051                                                  this,
0052                                                  SLOT(inhibitionsChanged(QList<InhibitionInfo>, QStringList)));
0053     });
0054     connect(m_solidPowerServiceWatcher, &QDBusServiceWatcher::serviceRegistered, this, &PowerManagementInhibition::update);
0055 
0056     // check whether the service is registered
0057     QDBusMessage message = QDBusMessage::createMethodCall(QStringLiteral("org.freedesktop.DBus"),
0058                                                           QStringLiteral("/"),
0059                                                           QStringLiteral("org.freedesktop.DBus"),
0060                                                           QStringLiteral("ListNames"));
0061     QDBusPendingReply<QStringList> async = QDBusConnection::sessionBus().asyncCall(message);
0062     QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(async, this);
0063     connect(callWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
0064         QDBusPendingReply<QStringList> reply = *self;
0065         self->deleteLater();
0066         if (!reply.isValid()) {
0067             return;
0068         }
0069         if (reply.value().contains(s_solidPowerService)) {
0070             update();
0071         }
0072     });
0073 }
0074 
0075 PowerManagementInhibition::~PowerManagementInhibition() = default;
0076 
0077 void PowerManagementInhibition::update()
0078 {
0079     m_serviceRegistered = true;
0080     QDBusConnection::sessionBus().connect(s_solidPowerService,
0081                                           s_solidPath,
0082                                           s_solidPowerService,
0083                                           QStringLiteral("InhibitionsChanged"),
0084                                           this,
0085                                           SLOT(inhibitionsChanged(QList<InhibitionInfo>, QStringList)));
0086     checkInhibition();
0087 }
0088 
0089 void PowerManagementInhibition::inhibitionsChanged(const QList<InhibitionInfo> &added, const QStringList &removed)
0090 {
0091     Q_UNUSED(added)
0092     Q_UNUSED(removed)
0093     checkInhibition();
0094 }
0095 
0096 void PowerManagementInhibition::checkInhibition()
0097 {
0098     QDBusMessage msg = QDBusMessage::createMethodCall(s_solidPowerService, s_solidPath, s_solidPowerService, QStringLiteral("HasInhibition"));
0099     msg << (uint)5; // PowerDevil::PolicyAgent::RequiredPolicy::ChangeScreenSettings | PowerDevil::PolicyAgent::RequiredPolicy::InterruptSession
0100     QDBusPendingReply<bool> pendingReply = QDBusConnection::sessionBus().asyncCall(msg);
0101     QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(pendingReply, this);
0102     connect(callWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *self) {
0103         QDBusPendingReply<bool> reply = *self;
0104         self->deleteLater();
0105         if (!reply.isValid()) {
0106             return;
0107         }
0108         m_inhibited = reply.value();
0109     });
0110 }