From: Ivailo Monev Date: Mon, 5 Jul 2021 21:07:57 +0000 (+0000) Subject: powerdevil: implement ConsoleKit support X-Git-Tag: 4.22.0~1029 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=69db6d5d4c77070df51ed8dcb995761bc4bb542d;p=kde%2Fkde-workspace.git powerdevil: implement ConsoleKit support fixes suspend/sleep on FreeBSD Signed-off-by: Ivailo Monev --- diff --git a/powerdevil/daemon/BackendConfig.cmake b/powerdevil/daemon/BackendConfig.cmake index 7d27223e..d1d24fbf 100644 --- a/powerdevil/daemon/BackendConfig.cmake +++ b/powerdevil/daemon/BackendConfig.cmake @@ -16,6 +16,7 @@ endif() set(powerdevilupowerbackend_SRCS backends/upower/upowersuspendjob.cpp backends/upower/login1suspendjob.cpp + backends/upower/consolekitsuspendjob.cpp backends/upower/powerdevilupowerbackend.cpp backends/upower/xrandrbrightness.cpp backends/upower/xrandrx11helper.cpp diff --git a/powerdevil/daemon/backends/upower/consolekitsuspendjob.cpp b/powerdevil/daemon/backends/upower/consolekitsuspendjob.cpp new file mode 100644 index 00000000..9d1f18ef --- /dev/null +++ b/powerdevil/daemon/backends/upower/consolekitsuspendjob.cpp @@ -0,0 +1,105 @@ +/* This file is part of the KDE project + Copyright (C) 2021 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#include "consolekitsuspendjob.h" + +#include +#include +#include +#include +#include + +ConsoleKitSuspendJob::ConsoleKitSuspendJob(QDBusInterface *consolekitInterface, + PowerDevil::BackendInterface::SuspendMethod method, + PowerDevil::BackendInterface::SuspendMethods supported) + : KJob(), m_consolekitInterface(consolekitInterface) +{ + kDebug() << "Starting ConsoleKit suspend job"; + m_method = method; + m_supported = supported; + + connect(m_consolekitInterface, SIGNAL(PrepareForSleep(bool)), this, SLOT(slotConsoleKitResuming(bool))); +} + +ConsoleKitSuspendJob::~ConsoleKitSuspendJob() +{ + +} + +void ConsoleKitSuspendJob::start() +{ + QTimer::singleShot(0, this, SLOT(doStart())); +} + +void ConsoleKitSuspendJob::kill(bool /*quietly */) +{ + +} + +void ConsoleKitSuspendJob::doStart() +{ + if (m_supported & m_method) + { + QVariantList args; + args << true; // interactive, ie. with polkit dialogs + + QDBusPendingReply reply; + QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); + connect(watcher, SIGNAL(finished(QDBusPendingCallWatcher*)), this, SLOT(sendResult(QDBusPendingCallWatcher*))); + + switch(m_method) + { + case PowerDevil::BackendInterface::ToRam: + reply = m_consolekitInterface->asyncCallWithArgumentList("Suspend", args); + break; + case PowerDevil::BackendInterface::ToDisk: + reply = m_consolekitInterface->asyncCallWithArgumentList("Hibernate", args); + break; + case PowerDevil::BackendInterface::HybridSuspend: + reply = m_consolekitInterface->asyncCallWithArgumentList("HybridSleep", args); + break; + default: + kDebug() << "Unsupported suspend method"; + setError(1); + setErrorText(i18n("Unsupported suspend method")); + break; + } + } +} + +void ConsoleKitSuspendJob::sendResult(QDBusPendingCallWatcher *watcher) +{ + const QDBusPendingReply reply = *watcher; + if (!reply.isError()) { + emitResult(); + } else { + kWarning() << "Failed to start suspend job" << reply.error().name() << reply.error().message(); + } + + watcher->deleteLater(); +} + +void ConsoleKitSuspendJob::slotConsoleKitResuming(bool active) +{ + if (!active) + emitResult(); +} + + +#include "moc_consolekitsuspendjob.cpp" diff --git a/powerdevil/daemon/backends/upower/consolekitsuspendjob.h b/powerdevil/daemon/backends/upower/consolekitsuspendjob.h new file mode 100644 index 00000000..f8daaaeb --- /dev/null +++ b/powerdevil/daemon/backends/upower/consolekitsuspendjob.h @@ -0,0 +1,53 @@ +/* This file is part of the KDE project + Copyright (C) 2021 Ivailo Monev + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License version 2 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + +*/ + +#ifndef CONSOLEKITSUSPENDJOB_H +#define CONSOLEKITSUSPENDJOB_H + +#include +#include +#include +#include + +#include "powerdevilbackendinterface.h" + +class ConsoleKitSuspendJob : public KJob +{ + Q_OBJECT +public: + ConsoleKitSuspendJob(QDBusInterface *consolekitInterface, + PowerDevil::BackendInterface::SuspendMethod method, + PowerDevil::BackendInterface::SuspendMethods supported); + virtual ~ConsoleKitSuspendJob(); + + void start(); + void kill(bool quietly); + +private Q_SLOTS: + void doStart(); + void sendResult(QDBusPendingCallWatcher* watcher); + void slotConsoleKitResuming(bool active); + +private: + QDBusInterface *m_consolekitInterface; + PowerDevil::BackendInterface::SuspendMethod m_method; + PowerDevil::BackendInterface::SuspendMethods m_supported; +}; + +#endif //CONSOLEKITSUSPENDJOB_H diff --git a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp index 64491452..c5705930 100644 --- a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp +++ b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp @@ -36,6 +36,7 @@ #include "xrandrbrightness.h" #include "upowersuspendjob.h" #include "login1suspendjob.h" +#include "consolekitsuspendjob.h" #ifdef HAVE_XF86VMODE #include "xf86vmodegamma.h" @@ -80,79 +81,47 @@ PowerDevilUPowerBackend::~PowerDevilUPowerBackend() bool PowerDevilUPowerBackend::isAvailable() { - if (!QDBusConnection::systemBus().interface()->isServiceRegistered(UPOWER_SERVICE)) { - // Is it pending activation? - kDebug() << "UPower service, " << UPOWER_SERVICE << ", is not registered on the bus. Trying to find out if it is activated."; - QDBusMessage message = QDBusMessage::createMethodCall("org.freedesktop.DBus", - "/org/freedesktop/DBus", - "org.freedesktop.DBus", - "ListActivatableNames"); - - QDBusPendingReply< QStringList > reply = QDBusConnection::systemBus().asyncCall(message); - reply.waitForFinished(); - - if (reply.isValid()) { - if (reply.value().contains(UPOWER_SERVICE)) { - kDebug() << "UPower was found, activating service..."; - QDBusConnection::systemBus().interface()->startService(UPOWER_SERVICE); - if (!QDBusConnection::systemBus().interface()->isServiceRegistered(UPOWER_SERVICE)) { - // Wait for it - QEventLoop e; - QTimer *timer = new QTimer; - timer->setInterval(10000); - timer->setSingleShot(true); - - connect(QDBusConnection::systemBus().interface(), SIGNAL(serviceRegistered(QString)), - &e, SLOT(quit())); - connect(timer, SIGNAL(timeout()), &e, SLOT(quit())); - - timer->start(); - - while (!QDBusConnection::systemBus().interface()->isServiceRegistered(UPOWER_SERVICE)) { - e.exec(); - - if (!timer->isActive()) { - kDebug() << "Activation of UPower timed out. There is likely a problem with your configuration."; - timer->deleteLater(); - return false; - } - } - - timer->deleteLater(); - } - return true; - } else { - kDebug() << "UPower cannot be found on this system."; - return false; - } - } else { - kWarning() << "Could not request activatable names to DBus!"; - return false; - } - } else { - return true; - } -} - -void PowerDevilUPowerBackend::init() -{ - // interfaces if (!QDBusConnection::systemBus().interface()->isServiceRegistered(LOGIN1_SERVICE)) { - // Activate it. + kDebug() << "activating" << LOGIN1_SERVICE; QDBusConnection::systemBus().interface()->startService(LOGIN1_SERVICE); } + if (!QDBusConnection::systemBus().interface()->isServiceRegistered(CONSOLEKIT_SERVICE)) { + kDebug() << "activating" << CONSOLEKIT_SERVICE; + QDBusConnection::systemBus().interface()->startService(CONSOLEKIT_SERVICE); + } + if (!QDBusConnection::systemBus().interface()->isServiceRegistered(UPOWER_SERVICE)) { - // Activate it. + kDebug() << "activating" << UPOWER_SERVICE; QDBusConnection::systemBus().interface()->startService(UPOWER_SERVICE); } + bool isavailable = QDBusConnection::systemBus().interface()->isServiceRegistered(LOGIN1_SERVICE); + isavailable |= QDBusConnection::systemBus().interface()->isServiceRegistered(CONSOLEKIT_SERVICE); + isavailable |= QDBusConnection::systemBus().interface()->isServiceRegistered(UPOWER_SERVICE); + + if (!isavailable) { + kWarning() << "No service for suspending is available on this system."; + } + + return isavailable; +} + +void PowerDevilUPowerBackend::init() +{ + // interfaces if (QDBusConnection::systemBus().interface()->isServiceRegistered(LOGIN1_SERVICE)) { - m_login1Interface = new QDBusInterface(LOGIN1_SERVICE, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus(), this); + kDebug() << LOGIN1_SERVICE << "available"; + m_login1Interface = new QDBusInterface(LOGIN1_SERVICE, LOGIN1_PATH, LOGIN1_IFACE, QDBusConnection::systemBus(), this); + } + + if (QDBusConnection::systemBus().interface()->isServiceRegistered(CONSOLEKIT_SERVICE)) { + kDebug() << CONSOLEKIT_SERVICE << "available"; + m_consolekitInterface = new QDBusInterface(CONSOLEKIT_SERVICE, CONSOLEKIT_PATH, CONSOLEKIT_IFACE, QDBusConnection::systemBus(), this); } bool screenBrightnessAvailable = false; - m_upowerInterface = new OrgFreedesktopUPowerInterface(UPOWER_SERVICE, "/org/freedesktop/UPower", QDBusConnection::systemBus(), this); + m_upowerInterface = new OrgFreedesktopUPowerInterface(UPOWER_SERVICE, UPOWER_PATH, QDBusConnection::systemBus(), this); m_brightnessControl = new XRandrBrightness(); if (m_brightnessControl->isSupported()) { kDebug() << "Using XRandR"; @@ -235,6 +204,25 @@ void PowerDevilUPowerBackend::init() canHybridSleep.waitForFinished(); if (canHybridSleep.isValid() && (canHybridSleep.value() == "yes" || canHybridSleep.value() == "challenge")) supported |= HybridSuspend; + + kDebug() << LOGIN1_SERVICE << "supported" << supported; + } else if (m_consolekitInterface) { + QDBusPendingReply canSuspend = m_consolekitInterface.data()->asyncCall("CanSuspend"); + canSuspend.waitForFinished(); + if (canSuspend.isValid() && (canSuspend.value() == "yes" || canSuspend.value() == "challenge")) + supported |= ToRam; + + QDBusPendingReply canHibernate = m_consolekitInterface.data()->asyncCall("CanHibernate"); + canHibernate.waitForFinished(); + if (canHibernate.isValid() && (canHibernate.value() == "yes" || canHibernate.value() == "challenge")) + supported |= ToDisk; + + QDBusPendingReply canHybridSleep = m_consolekitInterface.data()->asyncCall("CanHybridSleep"); + canHybridSleep.waitForFinished(); + if (canHybridSleep.isValid() && (canHybridSleep.value() == "yes" || canHybridSleep.value() == "challenge")) + supported |= HybridSuspend; + + kDebug() << CONSOLEKIT_SERVICE << "supported" << supported; } else { if (m_upowerInterface->canSuspend() && m_upowerInterface->SuspendAllowed()) { kDebug() << "Can suspend"; @@ -250,6 +238,8 @@ void PowerDevilUPowerBackend::init() // "resuming" signal if (m_login1Interface && checkSystemdVersion(198)) { connect(m_login1Interface.data(), SIGNAL(PrepareForSleep(bool)), this, SLOT(slotLogin1Resuming(bool))); + } else if (m_consolekitInterface) { + connect(m_consolekitInterface.data(), SIGNAL(PrepareForSleep(bool)), this, SLOT(slotConsoleKitResuming(bool))); } else { connect(m_upowerInterface, SIGNAL(Resuming()), this, SIGNAL(resumeFromSuspend())); } @@ -393,6 +383,8 @@ KJob* PowerDevilUPowerBackend::suspend(PowerDevil::BackendInterface::SuspendMeth { if (m_login1Interface && checkSystemdVersion(195)) { return new Login1SuspendJob(m_login1Interface.data(), method, supportedSuspendMethods()); + } else if (m_consolekitInterface) { + return new ConsoleKitSuspendJob(m_consolekitInterface.data(), method, supportedSuspendMethods()); } else { return new UPowerSuspendJob(m_upowerInterface, method, supportedSuspendMethods()); } @@ -527,4 +519,11 @@ void PowerDevilUPowerBackend::slotLogin1Resuming(bool active) } } +void PowerDevilUPowerBackend::slotConsoleKitResuming(bool active) +{ + if (!active) { + emit resumeFromSuspend(); + } +} + #include "moc_powerdevilupowerbackend.cpp" diff --git a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h index 48375130..8b64bdb9 100644 --- a/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h +++ b/powerdevil/daemon/backends/upower/powerdevilupowerbackend.h @@ -42,6 +42,12 @@ #define UPOWER_IFACE_DEVICE "org.freedesktop.UPower.Device" #define LOGIN1_SERVICE "org.freedesktop.login1" +#define LOGIN1_PATH "/org/freedesktop/login1" +#define LOGIN1_IFACE "org.freedesktop.login1.Manager" + +#define CONSOLEKIT_SERVICE "org.freedesktop.ConsoleKit" +#define CONSOLEKIT_PATH "/org/freedesktop/ConsoleKit/Manager" +#define CONSOLEKIT_IFACE "org.freedesktop.ConsoleKit.Manager" class UdevHelper; class XRandRX11Helper; @@ -77,6 +83,7 @@ private slots: void slotDeviceChanged(const QString &); void slotPropertyChanged(); void slotLogin1Resuming(bool active); + void slotConsoleKitResuming(bool active); void slotScreenBrightnessChanged(); void onKeyboardBrightnessChanged(int); @@ -101,6 +108,8 @@ private: // login1 interface QWeakPointer m_login1Interface; + // consolekit interface + QWeakPointer m_consolekitInterface; // buttons bool m_lidIsPresent;