OSDN Git Service

Revert "powerdeveil: drop support for upstart and systemd backends"
authorIvailo Monev <xakepa10@gmail.com>
Thu, 3 Sep 2015 07:07:28 +0000 (07:07 +0000)
committerIvailo Monev <xakepa10@gmail.com>
Thu, 3 Sep 2015 07:07:28 +0000 (07:07 +0000)
This reverts commit aaf9dc42e02282b30659cde2bf497a7e9ac2faae.

powerdevil/daemon/BackendConfig.cmake
powerdevil/daemon/backends/upower/backlighthelper.cpp
powerdevil/daemon/backends/upower/dbus/com.ubuntu.Upstart.xml [new file with mode: 0644]
powerdevil/daemon/backends/upower/login1suspendjob.cpp [new file with mode: 0644]
powerdevil/daemon/backends/upower/login1suspendjob.h [new file with mode: 0644]
powerdevil/daemon/backends/upower/powerdevilupowerbackend.cpp
powerdevil/daemon/backends/upower/powerdevilupowerbackend.h

index 2da07fc..f1d7be2 100644 (file)
@@ -10,6 +10,7 @@ if (UDEV_FOUND)
 
     set(powerdevilupowerbackend_SRCS
         backends/upower/upowersuspendjob.cpp
+        backends/upower/login1suspendjob.cpp
         backends/upower/powerdevilupowerbackend.cpp
         backends/upower/xrandrbrightness.cpp
         backends/upower/xrandrx11helper.cpp
@@ -34,6 +35,10 @@ if (UDEV_FOUND)
     ${CMAKE_CURRENT_SOURCE_DIR}/backends/upower/dbus/org.freedesktop.UPower.KbdBacklight.xml
     upower_kbdbacklight_interface)
 
+    qt4_add_dbus_interface(powerdevilupowerbackend_SRCS
+    ${CMAKE_CURRENT_SOURCE_DIR}/backends/upower/dbus/com.ubuntu.Upstart.xml
+    upstart_interface)
+
     set(powerdevilupowerbackend_LIBS ${X11_LIBRARIES} ${QT_QTGUI_LIBRARY} ${X11_Xrandr_LIB} ${KDE4_KDEUI_LIBRARY} ${UDEV_LIBS})
 
     ## backlight helper executable
index 1881683..a94217a 100644 (file)
@@ -67,7 +67,7 @@ void BacklightHelper::init()
 void BacklightHelper::initUsingBacklightType()
 {
     QDir dir(PREFIX);
-    dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Readable);
+    dir.setFilter(QDir::AllDirs | QDir::NoDot | QDir::NoDotDot | QDir::NoDotAndDotDot | QDir::Readable);
     dir.setSorting(QDir::Name | QDir::Reversed);// Reverse is needed to priorize acpi_video1 over 0
 
     QStringList interfaces = dir.entryList();
diff --git a/powerdevil/daemon/backends/upower/dbus/com.ubuntu.Upstart.xml b/powerdevil/daemon/backends/upower/dbus/com.ubuntu.Upstart.xml
new file mode 100644 (file)
index 0000000..dc7ae42
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
+<node name="/com/ubuntu/Upstart">
+  <interface name="com.ubuntu.Upstart0_6">
+    <property name="version" type="s" access="read"/>
+  </interface>
+</node>
+
diff --git a/powerdevil/daemon/backends/upower/login1suspendjob.cpp b/powerdevil/daemon/backends/upower/login1suspendjob.cpp
new file mode 100644 (file)
index 0000000..10e70d8
--- /dev/null
@@ -0,0 +1,107 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2006 Kevin Ottens <ervin@kde.org>
+    Copyright (C) 2010 Alejandro Fiestas <alex@eyeos.org>
+    Copyright (C) 2013 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 "login1suspendjob.h"
+
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/QDBusReply>
+#include <QTimer>
+#include <KDebug>
+#include <KLocale>
+
+Login1SuspendJob::Login1SuspendJob(QDBusInterface *login1Interface,
+                                   PowerDevil::BackendInterface::SuspendMethod method,
+                                   PowerDevil::BackendInterface::SuspendMethods supported)
+    : KJob(), m_login1Interface(login1Interface)
+{
+    kDebug() << "Starting Login1 suspend job";
+    m_method = method;
+    m_supported = supported;
+
+    connect(m_login1Interface, SIGNAL(PrepareForSleep(bool)), this, SLOT(slotLogin1Resuming(bool)));
+}
+
+Login1SuspendJob::~Login1SuspendJob()
+{
+
+}
+
+void Login1SuspendJob::start()
+{
+    QTimer::singleShot(0, this, SLOT(doStart()));
+}
+
+void Login1SuspendJob::kill(bool /*quietly */)
+{
+
+}
+
+void Login1SuspendJob::doStart()
+{
+    if (m_supported & m_method)
+    {
+        QVariantList args;
+        args << true; // interactive, ie. with polkit dialogs
+
+        QDBusPendingReply<void> 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_login1Interface->asyncCallWithArgumentList("Suspend", args);
+            break;
+        case PowerDevil::BackendInterface::ToDisk:
+            reply = m_login1Interface->asyncCallWithArgumentList("Hibernate", args);
+            break;
+        case PowerDevil::BackendInterface::HybridSuspend:
+            reply = m_login1Interface->asyncCallWithArgumentList("HybridSleep", args);
+            break;
+        default:
+            kDebug() << "Unsupported suspend method";
+            setError(1);
+            setErrorText(i18n("Unsupported suspend method"));
+            break;
+        }
+    }
+}
+
+void Login1SuspendJob::sendResult(QDBusPendingCallWatcher *watcher)
+{
+    const QDBusPendingReply<void> reply = *watcher;
+    if (!reply.isError()) {
+        emitResult();
+    } else {
+        kWarning() << "Failed to start suspend job" << reply.error().name() << reply.error().message();
+    }
+
+    watcher->deleteLater();
+}
+
+void Login1SuspendJob::slotLogin1Resuming(bool active)
+{
+    if (!active)
+        emitResult();
+}
+
+
+#include "moc_login1suspendjob.cpp"
diff --git a/powerdevil/daemon/backends/upower/login1suspendjob.h b/powerdevil/daemon/backends/upower/login1suspendjob.h
new file mode 100644 (file)
index 0000000..8ee5a1f
--- /dev/null
@@ -0,0 +1,55 @@
+/*  This file is part of the KDE project
+    Copyright (C) 2006 Kevin Ottens <ervin@kde.org>
+    Copyright (C) 2010 Alejandro Fiestas <alex@eyeos.org>
+    Copyright (C) 2013 Lukáš Tinkl <ltinkl@redhat.com>
+
+    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 LOGIN1SUSPENDJOB_H
+#define LOGIN1SUSPENDJOB_H
+
+#include <kjob.h>
+#include <QtDBus/QDBusInterface>
+#include <QtDBus/QDBusMessage>
+#include <QtDBus/qdbuspendingcall.h>
+
+#include "powerdevilbackendinterface.h"
+
+class Login1SuspendJob : public KJob
+{
+    Q_OBJECT
+public:
+    Login1SuspendJob(QDBusInterface *login1Interface,
+                     PowerDevil::BackendInterface::SuspendMethod method,
+                     PowerDevil::BackendInterface::SuspendMethods supported);
+    virtual ~Login1SuspendJob();
+
+    void start();
+    void kill(bool quietly);
+
+private Q_SLOTS:
+    void doStart();
+    void sendResult(QDBusPendingCallWatcher* watcher);
+    void slotLogin1Resuming(bool active);
+
+private:
+    QDBusInterface *m_login1Interface;
+    PowerDevil::BackendInterface::SuspendMethod m_method;
+    PowerDevil::BackendInterface::SuspendMethods m_supported;
+};
+
+#endif //LOGIN1SUSPENDJOB_H
index 7ce4ce6..6342e76 100644 (file)
 #include "xrandrx11helper.h"
 #include "xrandrbrightness.h"
 #include "upowersuspendjob.h"
+#include "login1suspendjob.h"
+#include "upstart_interface.h"
 #include "udevqt.h"
 
 #define HELPER_ID "org.kde.powerdevil.backlighthelper"
 
+bool checkSystemdVersion(uint requiredVersion)
+{
+
+    QDBusInterface systemdIface("org.freedesktop.systemd1", "/org/freedesktop/systemd1", "org.freedesktop.systemd1.Manager",
+                                QDBusConnection::systemBus(), 0);
+
+    const QString reply = systemdIface.property("Version").toString();
+
+    QRegExp expsd("(systemd )?([0-9]+)");
+
+    if (expsd.exactMatch(reply)) {
+        const uint version = expsd.cap(2).toUInt();
+        return (version >= requiredVersion);
+    }
+
+    // Since version 1.11 Upstart user sessions implement the exact same API as logind
+    // and are going to the maintain the API in future releases.
+    // Hence, powerdevil can support this init system as well
+    // This has no effect on systemd integration since the check is done after systemd
+    ComUbuntuUpstart0_6Interface upstartInterface(QLatin1String("com.ubuntu.Upstart"),
+                                                  QLatin1String("/com/ubuntu/Upstart"),
+                                                  QDBusConnection::sessionBus());
+
+    QRegExp exp("(?:init \\()?upstart ([0-9.]+)(?:\\))?");
+    if(exp.exactMatch(upstartInterface.version())) {
+        // Only keep the X.Y part of a X.Y.Z version
+        QStringList items = exp.cap(1).split('.').mid(0, 2);
+        const float upstartVersion = items.join(QString('.')).toFloat();
+        return upstartVersion >= 1.1;
+    }
+
+    kDebug() << "No appropriate systemd version or upstart version found";
+    return false;
+}
+
 PowerDevilUPowerBackend::PowerDevilUPowerBackend(QObject* parent)
     : BackendInterface(parent),
       m_brightnessControl(0), m_kbdMaxBrightness(0),
@@ -110,11 +147,21 @@ bool PowerDevilUPowerBackend::isAvailable()
 
 void PowerDevilUPowerBackend::init()
 {
+    // interfaces
+    if (!QDBusConnection::systemBus().interface()->isServiceRegistered(LOGIN1_SERVICE)) {
+        // Activate it.
+        QDBusConnection::systemBus().interface()->startService(LOGIN1_SERVICE);
+    }
+
     if (!QDBusConnection::systemBus().interface()->isServiceRegistered(UPOWER_SERVICE)) {
         // Activate it.
         QDBusConnection::systemBus().interface()->startService(UPOWER_SERVICE);
     }
 
+    if (QDBusConnection::systemBus().interface()->isServiceRegistered(LOGIN1_SERVICE)) {
+        m_login1Interface = new QDBusInterface(LOGIN1_SERVICE, "/org/freedesktop/login1", "org.freedesktop.login1.Manager", QDBusConnection::systemBus(), this);
+    }
+
     bool screenBrightnessAvailable = false;
     m_upowerInterface = new OrgFreedesktopUPowerInterface(UPOWER_SERVICE, "/org/freedesktop/UPower", QDBusConnection::systemBus(), this);
     m_brightnessControl = new XRandrBrightness();
@@ -187,18 +234,39 @@ void PowerDevilUPowerBackend::init()
 
     // Supported suspend methods
     SuspendMethods supported = UnknownSuspendMethod;
-    if (m_upowerInterface->canSuspend() && m_upowerInterface->SuspendAllowed()) {
-        kDebug() << "Can suspend";
-        supported |= ToRam;
-    }
+    if (m_login1Interface && checkSystemdVersion(195)) {
+        QDBusPendingReply<QString> canSuspend = m_login1Interface.data()->asyncCall("CanSuspend");
+        canSuspend.waitForFinished();
+        if (canSuspend.isValid() && (canSuspend.value() == "yes" || canSuspend.value() == "challenge"))
+            supported |= ToRam;
+
+        QDBusPendingReply<QString> canHibernate = m_login1Interface.data()->asyncCall("CanHibernate");
+        canHibernate.waitForFinished();
+        if (canHibernate.isValid() && (canHibernate.value() == "yes" || canHibernate.value() == "challenge"))
+            supported |= ToDisk;
+
+        QDBusPendingReply<QString> canHybridSleep = m_login1Interface.data()->asyncCall("CanHybridSleep");
+        canHybridSleep.waitForFinished();
+        if (canHybridSleep.isValid() && (canHybridSleep.value() == "yes" || canHybridSleep.value() == "challenge"))
+            supported |= HybridSuspend;
+    } else {
+        if (m_upowerInterface->canSuspend() && m_upowerInterface->SuspendAllowed()) {
+            kDebug() << "Can suspend";
+            supported |= ToRam;
+        }
 
-    if (m_upowerInterface->canHibernate() && m_upowerInterface->HibernateAllowed()) {
-        kDebug() << "Can hibernate";
-        supported |= ToDisk;
+        if (m_upowerInterface->canHibernate() && m_upowerInterface->HibernateAllowed()) {
+            kDebug() << "Can hibernate";
+            supported |= ToDisk;
+        }
     }
 
     // "resuming" signal
-    connect(m_upowerInterface, SIGNAL(Resuming()), this, SIGNAL(resumeFromSuspend()));
+    if (m_login1Interface && checkSystemdVersion(198)) {
+        connect(m_login1Interface.data(), SIGNAL(PrepareForSleep(bool)), this, SLOT(slotLogin1Resuming(bool)));
+    } else {
+        connect(m_upowerInterface, SIGNAL(Resuming()), this, SIGNAL(resumeFromSuspend()));
+    }
 
     // battery
     QList<RecallNotice> recallList;
@@ -366,7 +434,11 @@ void PowerDevilUPowerBackend::onKeyboardBrightnessChanged(int value)
 
 KJob* PowerDevilUPowerBackend::suspend(PowerDevil::BackendInterface::SuspendMethod method)
 {
-    return new UPowerSuspendJob(m_upowerInterface, method, supportedSuspendMethods());
+    if (m_login1Interface && checkSystemdVersion(195)) {
+        return new Login1SuspendJob(m_login1Interface.data(), method, supportedSuspendMethods());
+    } else {
+        return new UPowerSuspendJob(m_upowerInterface, method, supportedSuspendMethods());
+    }
 }
 
 void PowerDevilUPowerBackend::enumerateDevices()
index 3ec465e..c654e65 100644 (file)
@@ -95,6 +95,9 @@ private:
     OrgFreedesktopUPowerKbdBacklightInterface *m_kbdBacklight;
     int m_kbdMaxBrightness;
 
+    // login1 interface
+    QWeakPointer<QDBusInterface> m_login1Interface;
+
     // buttons
     bool m_lidIsPresent;
     bool m_lidIsClosed;