set(powerdevilupowerbackend_SRCS
backends/upower/upowersuspendjob.cpp
+ backends/upower/login1suspendjob.cpp
backends/upower/powerdevilupowerbackend.cpp
backends/upower/xrandrbrightness.cpp
backends/upower/xrandrx11helper.cpp
${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
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();
--- /dev/null
+<!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>
+
--- /dev/null
+/* 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"
--- /dev/null
+/* 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
#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),
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();
// 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;
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()
OrgFreedesktopUPowerKbdBacklightInterface *m_kbdBacklight;
int m_kbdMaxBrightness;
+ // login1 interface
+ QWeakPointer<QDBusInterface> m_login1Interface;
+
// buttons
bool m_lidIsPresent;
bool m_lidIsClosed;