From c069f00bfdaafdba240cac5551216516c053aff1 Mon Sep 17 00:00:00 2001 From: Pier Luigi Fiorini Date: Fri, 21 Oct 2022 16:33:25 +0200 Subject: [PATCH] Move logind library to Aurora --- CMakeLists.txt | 4 - README.md | 5 +- src/logind/CMakeLists.txt | 23 - src/logind/defaultlogind_p_p.h | 48 -- src/logind/lirilogindglobal.h | 33 -- src/logind/logind.cpp | 970 ------------------------------- src/logind/logind.h | 130 ----- src/logind/logind_p.h | 89 --- src/logind/logindtypes.cpp | 56 -- src/logind/logindtypes_p.h | 67 --- tests/auto/logind/CMakeLists.txt | 8 - tests/auto/logind/fakelogind.cpp | 129 ---- tests/auto/logind/fakelogind.h | 81 --- tests/auto/logind/tst_logind.cpp | 238 -------- 14 files changed, 1 insertion(+), 1880 deletions(-) delete mode 100644 src/logind/CMakeLists.txt delete mode 100644 src/logind/defaultlogind_p_p.h delete mode 100644 src/logind/lirilogindglobal.h delete mode 100644 src/logind/logind.cpp delete mode 100644 src/logind/logind.h delete mode 100644 src/logind/logind_p.h delete mode 100644 src/logind/logindtypes.cpp delete mode 100644 src/logind/logindtypes_p.h delete mode 100644 tests/auto/logind/CMakeLists.txt delete mode 100644 tests/auto/logind/fakelogind.cpp delete mode 100644 tests/auto/logind/fakelogind.h delete mode 100644 tests/auto/logind/tst_logind.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 60e7b85..82350aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,7 +44,6 @@ add_subdirectory(src/imports/dbusservice) add_subdirectory(src/imports/device) add_subdirectory(src/imports/notifications) add_subdirectory(src/localdevice) -add_subdirectory(src/logind) add_subdirectory(src/models) add_subdirectory(src/notifications) add_subdirectory(src/notify) @@ -53,9 +52,6 @@ if(LIRI_BUILD_TESTING) if(TARGET Liri::Models) add_subdirectory(tests/auto/core) endif() - if(TARGET Liri::Logind) - add_subdirectory(tests/auto/logind) - endif() if(TARGET Liri::Xdg) add_subdirectory(tests/auto/xdg) endif() diff --git a/README.md b/README.md index 157b6cf..2724a1b 100644 --- a/README.md +++ b/README.md @@ -6,9 +6,7 @@ libliri [![GitHub issues](https://img.shields.io/github/issues/lirios/libliri.svg)](https://github.com/lirios/libliri/issues) [![CI](https://github.com/lirios/libliri/workflows/CI/badge.svg?branch=develop)](https://github.com/lirios/libliri/actions?query=workflow%3ACI) -Library for Liri apps, including: - - * Qt-style API for logind. +Library for Liri apps. ## Dependencies @@ -45,7 +43,6 @@ to learn how to enable them. Available categories: - * **liri.logind:** Logind wrapper * **liri.localdevice.systemd:** systemd support for LiriLocalDevice * **liri.xdg:** freedesktop.org desktop entry and menus diff --git a/src/logind/CMakeLists.txt b/src/logind/CMakeLists.txt deleted file mode 100644 index 47c83f9..0000000 --- a/src/logind/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -liri_add_module(Logind - DESCRIPTION - "Qt API for logind" - SOURCES - defaultlogind_p_p.h - logind.cpp - logind.h - logind_p.h - logindtypes.cpp - logindtypes_p.h - DEFINES - #QT_NO_CAST_FROM_ASCII - QT_NO_FOREACH - QT_NO_KEYWORDS - PUBLIC_LIBRARIES - Qt5::Core - Qt5::DBus - PKGCONFIG_DEPENDENCIES - Qt5Core - Qt5DBus -) - -liri_finalize_module(Logind) diff --git a/src/logind/defaultlogind_p_p.h b/src/logind/defaultlogind_p_p.h deleted file mode 100644 index 0a89d46..0000000 --- a/src/logind/defaultlogind_p_p.h +++ /dev/null @@ -1,48 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Liri API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include "logind.h" - -namespace Liri { - -class DefaultLogind : public Logind -{ - Q_OBJECT -public: - explicit DefaultLogind(QObject *parent = nullptr); -}; - -} // namespace Liri diff --git a/src/logind/lirilogindglobal.h b/src/logind/lirilogindglobal.h deleted file mode 100644 index 4e1c27c..0000000 --- a/src/logind/lirilogindglobal.h +++ /dev/null @@ -1,33 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include - -#if defined(QT_BUILD_LIRILOGIND_LIB) -# define LIRILOGIND_EXPORT Q_DECL_EXPORT -#else -# define LIRILOGIND_EXPORT Q_DECL_IMPORT -#endif -#define LIRILOGIND_NO_EXPORT Q_DECL_HIDDEN diff --git a/src/logind/logind.cpp b/src/logind/logind.cpp deleted file mode 100644 index b041946..0000000 --- a/src/logind/logind.cpp +++ /dev/null @@ -1,970 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include -#include -#include -#include -#include -#include - -#include "defaultlogind_p_p.h" -#include "logind.h" -#include "logind_p.h" - -#include - -#include - -Q_LOGGING_CATEGORY(lcLogind, "liri.logind") - -#define LOGIN1_SERVICE QStringLiteral("org.freedesktop.login1") - -#define LOGIN1_OBJECT QLatin1String("/org/freedesktop/login1") -#define LOGIN1_MANAGER_INTERFACE QLatin1String("org.freedesktop.login1.Manager") -#define LOGIN1_SEAT_INTERFACE QLatin1String("org.freedesktop.login1.Seat") -#define LOGIN1_SESSION_INTERFACE QLatin1String("org.freedesktop.login1.Session") - -#define DBUS_SERVICE QLatin1String("org.freedesktop.DBus") -#define DBUS_PROPERTIES_INTERFACE QLatin1String("org.freedesktop.DBus.Properties") - -namespace Liri { - -/* - * DefaultLogind - */ - -DefaultLogind::DefaultLogind(QObject *parent) - : Logind(QDBusConnection::systemBus(), parent) -{ -} - -Q_GLOBAL_STATIC(DefaultLogind, s_logind) - -/* - * LogindPrivate - */ - -LogindPrivate::LogindPrivate(Logind *qq) - : bus(QDBusConnection::systemBus()) - , q_ptr(qq) -{ -} - -void LogindPrivate::_q_serviceRegistered() -{ - Q_Q(Logind); - - // Skip if we're already connected - if (isConnected) - return; - - // Find the active session otherwise try with XDG_SESSION_ID or the PID, - // when spawned by systemd --user only the first method is expected to work - DBusUserSession session; - if (getUserSession(session)) { - sessionPath = session.objectPath.path(); - qCInfo(lcLogind, "Using session %s", qPrintable(session.id)); - } else { - QDBusObjectPath sessionObjectPath; - - if (qEnvironmentVariableIsSet("XDG_SESSION_ID")) { - if (getSessionById(QString::fromLocal8Bit(qgetenv("XDG_SESSION_ID")), sessionObjectPath)) - sessionPath = sessionObjectPath.path(); - } - - if (sessionObjectPath.path().isEmpty()) { - if (getSessionByPid(sessionObjectPath)) - sessionPath = sessionObjectPath.path(); - } - - if (!sessionPath.isEmpty()) { - QString sessionId = getSessionId(sessionPath); - qCInfo(lcLogind, "Using session %s", qPrintable(sessionId)); - } - } - if (sessionPath.isEmpty()) { - qCWarning(lcLogind) << "Unable to find session!"; - return; - } - qCDebug(lcLogind) << "Session path:" << sessionPath; - - // We are connected now - isConnected = true; - - // Listen for lock and unlock signals - bus.connect(LOGIN1_SERVICE, sessionPath, LOGIN1_SESSION_INTERFACE, - QLatin1String("Lock"), - q, SIGNAL(lockSessionRequested())); - bus.connect(LOGIN1_SERVICE, sessionPath, LOGIN1_SESSION_INTERFACE, - QLatin1String("Unlock"), - q, SIGNAL(unlockSessionRequested())); - - // Listen for properties changed - bus.connect(LOGIN1_SERVICE, sessionPath, DBUS_PROPERTIES_INTERFACE, - QLatin1String("PropertiesChanged"), - q, SLOT(_q_sessionPropertiesChanged())); - - // Listen for prepare signals - bus.connect(LOGIN1_SERVICE, LOGIN1_OBJECT, LOGIN1_MANAGER_INTERFACE, - QLatin1String("PrepareForSleep"), - q, SIGNAL(prepareForSleep(bool))); - bus.connect(LOGIN1_SERVICE, LOGIN1_OBJECT, LOGIN1_MANAGER_INTERFACE, - QLatin1String("PrepareForShutdown"), - q, SIGNAL(prepareForShutdown(bool))); - - // Activate the session in case we are on another vt, the - // call blocks on purpose because we need to get properties - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - LOGIN1_MANAGER_INTERFACE, - QLatin1String("Activate")); - bus.call(message); - - // Get properties - _q_sessionPropertiesChanged(); - - Q_EMIT q->connectedChanged(isConnected); -} - -void LogindPrivate::_q_serviceUnregistered() -{ - Q_Q(Logind); - - // Disconnect prepare signals - bus.disconnect(LOGIN1_SERVICE, LOGIN1_OBJECT, LOGIN1_MANAGER_INTERFACE, - QLatin1String("PrepareForSleep"), - q, SIGNAL(prepareForSleep(bool))); - bus.disconnect(LOGIN1_SERVICE, LOGIN1_OBJECT, LOGIN1_MANAGER_INTERFACE, - QLatin1String("PrepareForShutdown"), - q, SIGNAL(prepareForShutdown(bool))); - - // Connection lost - isConnected = false; - Q_EMIT q->connectedChanged(isConnected); - - // Reset properties - if (sessionActive) { - sessionActive = false; - Q_EMIT q->sessionActiveChanged(false); - } - if (vt != -1) { - vt = -1; - Q_EMIT q->vtNumberChanged(-1); - } - if (!seat.isEmpty()) { - seat = QString(); - Q_EMIT q->seatChanged(seat); - } -} - -void LogindPrivate::_q_sessionPropertiesChanged() -{ - if (!isConnected || sessionPath.isEmpty()) - return; - - getSessionActive(); - getVirtualTerminal(); - getSeat(); -} - -void LogindPrivate::checkServiceRegistration() -{ - Q_Q(Logind); - - // Get the current session if the logind service is register - QDBusMessage message = - QDBusMessage::createMethodCall(DBUS_SERVICE, - QLatin1String("/"), - DBUS_SERVICE, - QLatin1String("ListNames")); - - QDBusPendingReply result = bus.asyncCall(message); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, q); - q->connect(watcher, &QDBusPendingCallWatcher::finished, q, - [this](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) - return; - - if (reply.value().contains(LOGIN1_SERVICE)) - _q_serviceRegistered(); - }); -} - -bool LogindPrivate::getSessionById(const QString &sessionId, QDBusObjectPath &path) const -{ - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - LOGIN1_OBJECT, - LOGIN1_MANAGER_INTERFACE, - QStringLiteral("GetSession")); - message.setArguments(QVariantList() << sessionId); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(lcLogind, "Failed to get session path for session %s: %s", - qPrintable(sessionId), - qPrintable(reply.error().message())); - return false; - } - - path = reply.value(); - return true; -} - -bool LogindPrivate::getSessionByPid(QDBusObjectPath &path) const -{ - QVariantList args; - args << static_cast(QCoreApplication::applicationPid()); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - LOGIN1_OBJECT, - LOGIN1_MANAGER_INTERFACE, - QStringLiteral("GetSessionByPID")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(lcLogind, "Failed to get session path by PID: %s", - qPrintable(reply.error().message())); - return false; - } - - path = reply.value(); - return true; -} - -bool LogindPrivate::getUserSession(DBusUserSession &session) const -{ - QDBusObjectPath userPath; - - { - QVariantList args; - args << ::getuid(); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - LOGIN1_OBJECT, - LOGIN1_MANAGER_INTERFACE, - QStringLiteral("GetUser")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(lcLogind, "Failed to get user path: %s", - qPrintable(reply.error().message())); - return false; - } - - userPath = reply.value(); - } - - { - QVariantList args; - args << QStringLiteral("org.freedesktop.login1.User") - << QStringLiteral("Sessions"); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - userPath.path(), - DBUS_PROPERTIES_INTERFACE, - QStringLiteral("Get")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(lcLogind, "Failed to list user sessions: %s", - qPrintable(reply.error().message())); - return false; - } - - // Find which session meets our critera - QStringList validTypes = { - QStringLiteral("tty"), - QStringLiteral("wayland"), - QStringLiteral("x11") - }; - - // We expect to have only one session for each user, and the session for the current - // user is supposed to be active because the user logged in with a login manager (either - // text based such as getty, or graphical like SDDM). - // Graphical login managers usually don't spawn a second session, but activate an already - // existing session for the user. - bool found = false; - DBusUserSessionVector sessions = qdbus_cast(reply.value().value()); - for (const auto &curSession : qAsConst(sessions)) { - const QString type = getSessionType(curSession.id, curSession.objectPath.path()); - const QString state = getSessionState(curSession.id, curSession.objectPath.path()); - - if (!validTypes.contains(type)) - continue; - if (state != QStringLiteral("active")) - continue; - - // We get the sessions from newest to oldest, pick the last - // one that meets the criteria - session = curSession; - found = true; - } - - return found; - } - - return false; -} - -QString LogindPrivate::getSessionId(const QString &sessionPath) const -{ - QVariantList args; - args << LOGIN1_SESSION_INTERFACE - << QStringLiteral("Id"); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QStringLiteral("Get")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(lcLogind, "Failed to get session id: %s", - qPrintable(reply.error().message())); - return QString(); - } - - return reply.value().toString(); -} - -QString LogindPrivate::getSessionType(const QString &sessionId, const QString &sessionPath) const -{ - QVariantList args; - args << LOGIN1_SESSION_INTERFACE - << QStringLiteral("Type"); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QStringLiteral("Get")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(lcLogind, "Failed to get type for session %s: %s", - qPrintable(sessionId), qPrintable(reply.error().message())); - return QString(); - } - - return reply.value().toString(); -} - -QString LogindPrivate::getSessionState(const QString &sessionId, const QString &sessionPath) const -{ - QVariantList args; - args << LOGIN1_SESSION_INTERFACE - << QStringLiteral("State"); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QStringLiteral("Get")); - message.setArguments(args); - - QDBusReply reply = bus.call(message); - if (!reply.isValid()) { - qCWarning(lcLogind, "Failed to get state for session %s: %s", - qPrintable(sessionId), qPrintable(reply.error().message())); - return QString(); - } - - return reply.value().toString(); -} - -void LogindPrivate::getSessionActive() -{ - Q_Q(Logind); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QLatin1String("Get")); - message.setArguments(QVariantList() << LOGIN1_SESSION_INTERFACE << QStringLiteral("Active")); - - QDBusPendingReply result = bus.asyncCall(message); - QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(result, q); - q->connect(callWatcher, &QDBusPendingCallWatcher::finished, q, - [q, this](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) { - qCWarning(lcLogind, "Failed to get \"Active\" property from session: %s", - qPrintable(reply.error().message())); - return; - } - - const bool active = reply.value().toBool(); - if (sessionActive != active) { - sessionActive = active; - Q_EMIT q->sessionActiveChanged(active); - } - }); -} - -void LogindPrivate::getVirtualTerminal() -{ - Q_Q(Logind); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QLatin1String("Get")); - message.setArguments(QVariantList() << LOGIN1_SESSION_INTERFACE << QStringLiteral("VTNr")); - - QDBusPendingReply result = bus.asyncCall(message); - QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(result, q); - q->connect(callWatcher, &QDBusPendingCallWatcher::finished, q, - [q, this](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) { - qCWarning(lcLogind, "Failed to get \"VTNr\" property from session: %s", - qPrintable(reply.error().message())); - return; - } - - const uint vtnr = reply.value().toUInt(); - if (vt != static_cast(vtnr)) { - vt = static_cast(vtnr); - Q_EMIT q->vtNumberChanged(vt); - } - }); -} - -void LogindPrivate::getSeat() -{ - Q_Q(Logind); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - sessionPath, - DBUS_PROPERTIES_INTERFACE, - QLatin1String("Get")); - message.setArguments(QVariantList() << LOGIN1_SESSION_INTERFACE << QStringLiteral("Seat")); - - QDBusPendingReply result = bus.asyncCall(message); - QDBusPendingCallWatcher *callWatcher = new QDBusPendingCallWatcher(result, q); - q->connect(callWatcher, &QDBusPendingCallWatcher::finished, q, - [q, this](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) { - qCWarning(lcLogind, "Failed to get \"Seat\" property from session: %s", - qPrintable(reply.error().message())); - return; - } - - const DBusSeat dbusSeat = qdbus_cast(reply.value().value()); - if (seat != dbusSeat.id) { - seat = dbusSeat.id; - Q_EMIT q->seatChanged(seat); - } - }); -} - -/* - * Logind - */ - -/*! - * \class Logind - * \inmodule LiriLogind - * \brief Qt-style API for logind. - * - * LiriLogind is a Qt-style API for logind. - * - * More information on logind can be obtained - * \l{https://www.freedesktop.org/wiki/Software/systemd/logind/}(here). - * - * Logging category is "liri.logind". - * - * This class is a singleton, you cannot instantiate it. Use the instance() - * method to get access. - */ - -/*! - * Constructs a Logind instance with the given \a parent and D-Bus \a connection. - */ -Logind::Logind(const QDBusConnection &connection, QObject *parent) - : QObject(parent) - , d_ptr(new LogindPrivate(this)) -{ - // Register custom types - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - qDBusRegisterMetaType(); - - // Initialize and respond to logind service (un)registration - Q_D(Logind); - d->bus = connection; - d->watcher = - new QDBusServiceWatcher(LOGIN1_SERVICE, d->bus, - QDBusServiceWatcher::WatchForRegistration | QDBusServiceWatcher::WatchForUnregistration, - this); - connect(d->watcher, SIGNAL(serviceRegistered(QString)), - this, SLOT(_q_serviceRegistered())); - connect(d->watcher, SIGNAL(serviceUnregistered(QString)), - this, SLOT(_q_serviceUnregistered())); - - // Is logind already registered? - d->checkServiceRegistration(); -} - -/*! - * Destroys the Logind object. - */ -Logind::~Logind() -{ - delete d_ptr; -} - -/*! - * Return the instance of Logind. - */ -Logind *Logind::instance() -{ - return s_logind(); -} - -bool Logind::checkService() -{ - QDBusConnectionInterface *interface = QDBusConnection::systemBus().interface(); - return interface->isServiceRegistered(LOGIN1_SERVICE); -} - -/*! - * \property Logind::isConnected - * - * This property holds whether we are connected to logind. - */ -bool Logind::isConnected() const -{ - Q_D(const Logind); - return d->isConnected; -} - -/*! - * \property Logind::isConnected - * - * This property holds whether session control was acquired. - * - * \sa Logind::takeControl() - * \sa Logind::releaseControl() - */ -bool Logind::hasSessionControl() const -{ - Q_D(const Logind); - return d->hasSessionControl; -} - -/*! - * \property Logind::isSessionActive - * - * This property holds whether the session this process lives in - * is active or not, that is whether the current vt is the one - * where the session was executed. - */ -bool Logind::isSessionActive() const -{ - Q_D(const Logind); - return d->sessionActive; -} - -/*! - * \property Logind::isInhibited - * - * This property holds if there are inhibitions installed. - */ -bool Logind::isInhibited() const -{ - Q_D(const Logind); - return d->inhibitFds.size() > 0; -} - -/*! - * \property Logind::vtNumber - * - * This property holds the current vt number. - */ -int Logind::vtNumber() const -{ - Q_D(const Logind); - return d->vt; -} - -/*! - * \property Logind::seat - * - * This property holds the current seat. - */ -QString Logind::seat() const -{ - Q_D(const Logind); - return d->seat; -} - -/*! - * Set the idle hint state to \a idle. - */ -void Logind::setIdleHint(bool idle) -{ - Q_D(Logind); - - if (!d->isConnected || d->sessionPath.isEmpty()) - return; - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QStringLiteral("SetIdleHint")); - d->bus.asyncCall(message, idle); -} - -/*! - * Install an inhibitor. - * \param who Name of the application that is installing the inhibitor - * \param why Reason why the inhibitor is being installed - * \param flags What is being inhibited - * \param mode Inhibition mode - * - * \sa Logind::inhibited() - * \sa Logind::uninhibited() - */ -void Logind::inhibit(const QString &who, const QString &why, - InhibitFlags flags, InhibitMode mode) -{ - Q_D(Logind); - - if (!d->isConnected) - return; - - QStringList what; - if (flags.testFlag(InhibitShutdown)) - what.append(QStringLiteral("shutdown")); - if (flags.testFlag(InhibitSleep)) - what.append(QStringLiteral("sleep")); - if (flags.testFlag(InhibitIdle)) - what.append(QStringLiteral("idle")); - if (flags.testFlag(InhibitPowerKey)) - what.append(QStringLiteral("handle-power-key")); - if (flags.testFlag(InhibitSuspendKey)) - what.append(QStringLiteral("handle-suspend-key")); - if (flags.testFlag(InhibitHibernateKey)) - what.append(QStringLiteral("handle-hibernate-key")); - if (flags.testFlag(InhibitLidSwitch)) - what.append(QStringLiteral("handle-lid-switch")); - - QString modeStr = mode == Block ? QStringLiteral("block") : QStringLiteral("delay"); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - LOGIN1_OBJECT, - LOGIN1_MANAGER_INTERFACE, - QLatin1String("Inhibit")); - message.setArguments(QVariantList() << what.join(':') << who << why << modeStr); - - QDBusPendingReply result = d->bus.asyncCall(message); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this); - connect(watcher, &QDBusPendingCallWatcher::finished, this, - [d, this, who, why](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) { - qCWarning(lcLogind, "Unable to acquire inhibition lock: %s", - qPrintable(reply.error().message())); - return; - } - - qCDebug(lcLogind) << "Inhibition lock acquired successfully"; - - const int fd = ::dup(reply.value().fileDescriptor()); - d->inhibitFds.append(fd); - if (d->inhibitFds.size() == 1) - Q_EMIT inhibitedChanged(true); - Q_EMIT inhibited(who, why, fd); - }); -} - -/*! - * Uninstall the inhibitor with \a fd file descriptor. - */ -void Logind::uninhibit(int fd) -{ - Q_D(Logind); - - if (!d->isConnected || !d->inhibitFds.contains(fd)) - return; - - ::close(fd); - d->inhibitFds.removeOne(fd); - - if (d->inhibitFds.size() == 0) - Q_EMIT inhibitedChanged(false); - Q_EMIT uninhibited(fd); -} - -/*! - * Lock the session. - * - * \sa Logind::unlockSession() - */ -void Logind::lockSession() -{ - Q_D(Logind); - - if (!d->isConnected || d->sessionPath.isEmpty()) - return; - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("Lock")); - d->bus.asyncCall(message); -} - -/*! - * Unlock the session. - * - * \sa Logind::lockSession() - */ -void Logind::unlockSession() -{ - Q_D(Logind); - - if (!d->isConnected || d->sessionPath.isEmpty()) - return; - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("Unlock")); - d->bus.asyncCall(message); -} - -/*! - * Take control of the session. No other process will be - * able to take control, until the releaaseControl() method is called. - * - * Access to video and input devices will be granted to the caller. - * - * \sa Logind::releaseControl() - */ -void Logind::takeControl() -{ - Q_D(Logind); - - if (!d->isConnected || d->sessionPath.isEmpty() || d->hasSessionControl) - return; - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("TakeControl")); - message.setArguments(QVariantList() << false); - - QDBusPendingReply result = d->bus.asyncCall(message); - QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(result, this); - connect(watcher, &QDBusPendingCallWatcher::finished, this, - [d, this](QDBusPendingCallWatcher *w) { - QDBusPendingReply reply = *w; - w->deleteLater(); - - if (!reply.isValid()) { - qCWarning(lcLogind, "Unable to take control of the session: %s", - qPrintable(reply.error().message())); - d->hasSessionControl = false; - Q_EMIT hasSessionControlChanged(d->hasSessionControl); - return; - } - - qCDebug(lcLogind) << "Acquired control of the session"; - d->hasSessionControl = true; - Q_EMIT hasSessionControlChanged(d->hasSessionControl); - - d->bus.connect(LOGIN1_SERVICE, d->sessionPath, LOGIN1_SESSION_INTERFACE, - QLatin1String("PauseDevice"), - this, SIGNAL(devicePaused(quint32,quint32,QString))); - d->bus.connect(LOGIN1_SERVICE, d->sessionPath, LOGIN1_SESSION_INTERFACE, - QLatin1String("ResumeDevice"), - this, SIGNAL(deviceResumed(quint32,quint32,int))); - }); -} - -/*! - * Release control of the session. - * - * Access to video and input devices will be revoked from the caller. - * - * \sa Logind::takeControl() - */ -void Logind::releaseControl() -{ - Q_D(Logind); - - if (!d->isConnected || d->sessionPath.isEmpty() || !d->hasSessionControl) - return; - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("ReleaseControl")); - d->bus.asyncCall(message); - - qCDebug(lcLogind) << "Released control of the session"; - d->hasSessionControl = false; - Q_EMIT hasSessionControlChanged(d->hasSessionControl); -} - -/*! - * Request access to the device \a fileName. - * - * \return File descriptor of the device - * - * \sa Logind::releaseDevice() - */ -int Logind::takeDevice(const QString &fileName) -{ - Q_D(Logind); - - struct stat st; - if (::stat(qPrintable(fileName), &st) < 0) { - qCWarning(lcLogind, "Failed to stat: %s", qPrintable(fileName)); - return -1; - } - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("TakeDevice")); - message.setArguments(QVariantList() - << QVariant(major(st.st_rdev)) - << QVariant(minor(st.st_rdev))); - - // Block until the device is taken - QDBusMessage reply = d->bus.call(message); - if (reply.type() == QDBusMessage::ErrorMessage) { - qCWarning(lcLogind, "Failed to take device \"%s\": %s", - qPrintable(fileName), qPrintable(reply.errorMessage())); - return -1; - } - - const int fd = reply.arguments().at(0).value().fileDescriptor(); - return ::fcntl(fd, F_DUPFD_CLOEXEC, 0); -} - -/* - * Revoke access to the device \a fd. - * - * \sa Logind::takeDevice() - */ -void Logind::releaseDevice(int fd) -{ - Q_D(Logind); - - struct stat st; - if (::fstat(fd, &st) < 0) { - qCWarning(lcLogind, "Failed to stat the file descriptor"); - return; - } - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("ReleaseDevice")); - message.setArguments(QVariantList() - << QVariant(major(st.st_rdev)) - << QVariant(minor(st.st_rdev))); - - d->bus.asyncCall(message); -} - -/*! - * Allow a session-controller to synchronously pause a device - * with \a devMajor major and \a devMinor minor after receiving - * the devicePaused signal. - * - * \sa Logind::devicePaused() - */ -void Logind::pauseDeviceComplete(quint32 devMajor, quint32 devMinor) -{ - Q_D(Logind); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - d->sessionPath, - LOGIN1_SESSION_INTERFACE, - QLatin1String("PauseDeviceComplete")); - message.setArguments(QVariantList() << devMajor << devMinor); - - d->bus.asyncCall(message); -} - -/*! - * Switch to the vt number \a vt. - */ -void Logind::switchTo(quint32 vt) -{ - Q_D(Logind); - - QDBusMessage message = - QDBusMessage::createMethodCall(LOGIN1_SERVICE, - QLatin1String("/org/freedesktop/login1/seat/self"), - LOGIN1_SEAT_INTERFACE, - QLatin1String("SwitchTo")); - message.setArguments(QVariantList() << QVariant(vt)); - - d->bus.asyncCall(message); -} - -} // namespace Liri - -#include "moc_logind.cpp" diff --git a/src/logind/logind.h b/src/logind/logind.h deleted file mode 100644 index 70f923d..0000000 --- a/src/logind/logind.h +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include -#include - -#include - -namespace Liri { - -class LogindPrivate; - -class LIRILOGIND_EXPORT Logind : public QObject -{ - Q_OBJECT - Q_DECLARE_PRIVATE(Logind) - Q_PROPERTY(bool connected READ isConnected NOTIFY connectedChanged) - Q_PROPERTY(bool hasSessionControl READ hasSessionControl NOTIFY hasSessionControlChanged) - Q_PROPERTY(bool sessionActive READ isSessionActive NOTIFY sessionActiveChanged) - Q_PROPERTY(bool inhibited READ isInhibited NOTIFY inhibitedChanged) - Q_PROPERTY(int vtNumber READ vtNumber NOTIFY vtNumberChanged) - Q_PROPERTY(QString seat READ seat NOTIFY seatChanged) -public: - enum InhibitFlag { - InhibitShutdown = 0x01, - InhibitSleep = 0x02, - InhibitIdle = 0x04, - InhibitPowerKey = 0x08, - InhibitSuspendKey = 0x10, - InhibitHibernateKey = 0x20, - InhibitLidSwitch = 0x40 - }; - Q_DECLARE_FLAGS(InhibitFlags, InhibitFlag) - - enum InhibitMode { - Block = 0, - Delay - }; - - ~Logind(); - - static bool checkService(); - - static Logind *instance(); - - bool isConnected() const; - bool hasSessionControl() const; - bool isSessionActive() const; - bool isInhibited() const; - int vtNumber() const; - QString seat() const; - - void setIdleHint(bool idle); - -public Q_SLOTS: - void inhibit(const QString &who, const QString &why, Logind::InhibitFlags flags, Logind::InhibitMode mode); - void uninhibit(int fd); - - void lockSession(); - void unlockSession(); - - void takeControl(); - void releaseControl(); - - int takeDevice(const QString &fileName); - void releaseDevice(int fd); - - void pauseDeviceComplete(quint32 devMajor, quint32 devMinor); - - void switchTo(quint32 vt); - -Q_SIGNALS: - void connectedChanged(bool); - void hasSessionControlChanged(bool); - void sessionActiveChanged(bool); - void inhibitedChanged(bool); - void vtNumberChanged(int); - void seatChanged(const QString &seat); - - void prepareForSleep(bool before); - void prepareForShutdown(bool before); - - void lockSessionRequested(); - void unlockSessionRequested(); - - void inhibited(const QString &who, const QString &why, - int fd); - void uninhibited(int fd); - - void devicePaused(quint32 major, quint32 minor, const QString &type); - void deviceResumed(quint32 major, quint32 minor, int fd); - -protected: - explicit Logind(const QDBusConnection &connection, QObject *parent = nullptr); - -private: - Q_DISABLE_COPY(Logind) - - LogindPrivate *const d_ptr; - - Q_PRIVATE_SLOT(d_func(), void _q_serviceRegistered()) - Q_PRIVATE_SLOT(d_func(), void _q_serviceUnregistered()) - Q_PRIVATE_SLOT(d_func(), void _q_sessionPropertiesChanged()) -}; - -Q_DECLARE_OPERATORS_FOR_FLAGS(Logind::InhibitFlags) - -} // namespace Liri diff --git a/src/logind/logind_p.h b/src/logind/logind_p.h deleted file mode 100644 index 9a99e42..0000000 --- a/src/logind/logind_p.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Liri API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include -#include -#include -#include -#include - -#include "logindtypes_p.h" - -Q_DECLARE_LOGGING_CATEGORY(lcLogind) - -namespace Liri { - -class Logind; - -class LogindPrivate -{ - Q_DECLARE_PUBLIC(Logind) -public: - explicit LogindPrivate(Logind *qq); - - void _q_serviceRegistered(); - void _q_serviceUnregistered(); - void _q_sessionPropertiesChanged(); - - void checkServiceRegistration(); - - QDBusConnection bus; - QDBusServiceWatcher *watcher = nullptr; - bool isConnected = false; - bool hasSessionControl = false; - QString sessionPath; - bool sessionActive = false; - int vt = -1; - QString seat; - QVector inhibitFds; - -protected: - Logind *q_ptr; - -private: - bool getSessionById(const QString &sessionId, QDBusObjectPath &path) const; - bool getSessionByPid(QDBusObjectPath &path) const; - bool getUserSession(DBusUserSession &session) const; - QString getSessionId(const QString &sessionPath) const; - QString getSessionType(const QString &sessionId, const QString &sessionPath) const; - QString getSessionState(const QString &sessionId, const QString &sessionPath) const; - - void getSessionActive(); - void getVirtualTerminal(); - void getSeat(); -}; - -} // namespace Liri diff --git a/src/logind/logindtypes.cpp b/src/logind/logindtypes.cpp deleted file mode 100644 index bb804cc..0000000 --- a/src/logind/logindtypes.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2019 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include "logindtypes_p.h" - -QDBusArgument &operator<<(QDBusArgument &argument, const DBusUserSession &userSession) -{ - argument.beginStructure(); - argument << userSession.id << userSession.objectPath; - argument.endStructure(); - return argument; -} - -const QDBusArgument &operator>>(const QDBusArgument &argument, DBusUserSession &userSession) -{ - argument.beginStructure(); - argument >> userSession.id >> userSession.objectPath; - argument.endStructure(); - return argument; -} - -QDBusArgument &operator<<(QDBusArgument &argument, const DBusSeat &seat) -{ - argument.beginStructure(); - argument << seat.id << seat.objectPath; - argument.endStructure(); - return argument; -} - -const QDBusArgument &operator>>(const QDBusArgument &argument, DBusSeat &seat) -{ - argument.beginStructure(); - argument >> seat.id >> seat.objectPath; - argument.endStructure(); - return argument; -} diff --git a/src/logind/logindtypes_p.h b/src/logind/logindtypes_p.h deleted file mode 100644 index 0c5d5b8..0000000 --- a/src/logind/logindtypes_p.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2019 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:LGPLv3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#ifndef LOGINDTYPES_P_H -#define LOGINDTYPES_P_H - -#include -#include -#include - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Liri API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -class DBusUserSession -{ -public: - QString id; - QDBusObjectPath objectPath; -}; -Q_DECLARE_METATYPE(DBusUserSession) - -typedef QVector DBusUserSessionVector; -Q_DECLARE_METATYPE(DBusUserSessionVector) - -class DBusSeat -{ -public: - QString id; - QDBusObjectPath objectPath; -}; -Q_DECLARE_METATYPE(DBusSeat) - -QDBusArgument &operator<<(QDBusArgument &argument, const DBusUserSession &userSession); -const QDBusArgument &operator>>(const QDBusArgument &argument, DBusUserSession &userSession); - -QDBusArgument &operator<<(QDBusArgument &argument, const DBusSeat &seat); -const QDBusArgument &operator>>(const QDBusArgument &argument, DBusSeat &seat); - -#endif // LOGINDTYPES_P_H diff --git a/tests/auto/logind/CMakeLists.txt b/tests/auto/logind/CMakeLists.txt deleted file mode 100644 index 7812663..0000000 --- a/tests/auto/logind/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -liri_add_test(tst_liri_logind - SOURCES - fakelogind.cpp - fakelogind.h - tst_logind.cpp - LIBRARIES - Liri::Logind -) diff --git a/tests/auto/logind/fakelogind.cpp b/tests/auto/logind/fakelogind.cpp deleted file mode 100644 index 06d9f8c..0000000 --- a/tests/auto/logind/fakelogind.cpp +++ /dev/null @@ -1,129 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:GPL3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include - -#include "fakelogind.h" - -/* - * FakeLogindSession - */ - -FakeLogindSession::FakeLogindSession(const QString &path, QObject *parent) - : QObject(parent) - , m_path(path) -{ - QDBusConnection::sessionBus().registerObject( - m_path, this, QDBusConnection::ExportScriptableContents); -} - -FakeLogindSession::~FakeLogindSession() -{ - QDBusConnection::sessionBus().unregisterObject(m_path); -} - -const QString &FakeLogindSession::path() -{ - return m_path; -} - -bool FakeLogindSession::isActive() const -{ - return true; -} - -quint32 FakeLogindSession::vtNumber() const -{ - return 1; -} - -void FakeLogindSession::TakeControl(bool force) -{ - Q_UNUSED(force); -} - -void FakeLogindSession::ReleaseControl() -{ -} - -/* - * FakeLogind - */ - -FakeLogind::FakeLogind(QObject *parent) - : QObject(parent) - , m_session(new FakeLogindSession(QStringLiteral("/org/freedesktop/login1/session/_1"), this)) -{ - QDBusConnection::sessionBus().registerObject( - QStringLiteral("/org/freedesktop/login1"), this, - QDBusConnection::ExportScriptableContents); - QDBusConnection::sessionBus().registerService( - QStringLiteral("org.freedesktop.login1")); -} - -FakeLogind::~FakeLogind() -{ - QDBusConnection::sessionBus().unregisterObject( - QStringLiteral("/org/freedesktop/login1")); - QDBusConnection::sessionBus().unregisterService( - QStringLiteral("org.freedesktop.login1")); -} - -void FakeLogind::doLock() -{ - Q_EMIT m_session->Lock(); -} - -void FakeLogind::doUnlock() -{ - Q_EMIT m_session->Unlock(); -} - -void FakeLogind::doPrepareForSleep(bool before) -{ - Q_EMIT PrepareForSleep(before); -} - -void FakeLogind::doPrepareForShutdown(bool before) -{ - Q_EMIT PrepareForShutdown(before); -} - -QDBusObjectPath FakeLogind::GetSessionByPID(quint32 pid) -{ - Q_UNUSED(pid); - return QDBusObjectPath(m_session->path()); -} - -int FakeLogind::TakeDevice(int maj, int min) -{ - Q_UNUSED(maj); - Q_UNUSED(min); - return -1; -} - -void FakeLogind::ReleaseDevice(int maj, int min) -{ - Q_UNUSED(maj); - Q_UNUSED(min); -} diff --git a/tests/auto/logind/fakelogind.h b/tests/auto/logind/fakelogind.h deleted file mode 100644 index 588edde..0000000 --- a/tests/auto/logind/fakelogind.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:GPL3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#pragma once - -#include -#include - -class FakeLogindSession : public QObject -{ - Q_OBJECT - Q_PROPERTY(bool Active READ isActive) - Q_PROPERTY(uint VTNr READ vtNumber) - Q_CLASSINFO("D-Bus Interface", "org.freedesktop.login1.Session") -public: - explicit FakeLogindSession(const QString &path, QObject *parent = nullptr); - virtual ~FakeLogindSession(); - - const QString &path(); - - bool isActive() const; - quint32 vtNumber() const; - -public Q_SLOTS: - Q_SCRIPTABLE void TakeControl(bool force); - Q_SCRIPTABLE void ReleaseControl(); - -Q_SIGNALS: - Q_SCRIPTABLE void Lock(); - Q_SCRIPTABLE void Unlock(); - -private: - QString m_path; -}; - -class FakeLogind : public QObject -{ - Q_OBJECT - Q_CLASSINFO("D-Bus Interface", "org.freedesktop.login1.Manager") -public: - explicit FakeLogind(QObject *parent = nullptr); - virtual ~FakeLogind(); - - // Methods to trigger signals - void doLock(); - void doUnlock(); - void doPrepareForSleep(bool before); - void doPrepareForShutdown(bool before); - -public Q_SLOTS: - Q_SCRIPTABLE QDBusObjectPath GetSessionByPID(quint32 pid); - Q_SCRIPTABLE int TakeDevice(int maj, int min); - Q_SCRIPTABLE void ReleaseDevice(int maj, int min); - -Q_SIGNALS: - Q_SCRIPTABLE void PrepareForSleep(bool before); - Q_SCRIPTABLE void PrepareForShutdown(bool before); - -private: - FakeLogindSession *m_session; -}; diff --git a/tests/auto/logind/tst_logind.cpp b/tests/auto/logind/tst_logind.cpp deleted file mode 100644 index e291b31..0000000 --- a/tests/auto/logind/tst_logind.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/**************************************************************************** - * This file is part of Liri. - * - * Copyright (C) 2018 Pier Luigi Fiorini - * - * $BEGIN_LICENSE:GPL3+$ - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * $END_LICENSE$ - ***************************************************************************/ - -#include - -#include - -#include "fakelogind.h" - -using namespace Liri; - -class CustomLogind : public Logind -{ - Q_OBJECT -public: - CustomLogind(QObject *parent = nullptr) - : Logind(QDBusConnection::sessionBus(), parent) - { - } -}; - -class TestLogind : public QObject -{ - Q_OBJECT -public: - TestLogind(QObject *parent = nullptr) - : QObject(parent) - { - } - -private Q_SLOTS: - void initTestCase() - { - qunsetenv("XDG_SESSION_ID"); - } - - void testConnection() - { - // Integration is initially disconnected - CustomLogind *logind = new CustomLogind; - QVERIFY(!logind->isConnected()); - - // Spy on connectedChanged(bool) and create the service - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyConnected.wait()); - QVERIFY(logind->isConnected()); - - // Delete - fakeLogind->deleteLater(); - QVERIFY(spyConnected.wait()); - QVERIFY(!logind->isConnected()); - logind->deleteLater(); - } - - void testRegistration() - { - // Integration is initially disconnected - CustomLogind *logind = new CustomLogind; - QVERIFY(!logind->isConnected()); - - // Spy on connectedChanged(bool) and create the service - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - QScopedPointer fakeLogind(new FakeLogind); - QVERIFY(spyConnected.wait()); - QVERIFY(logind->isConnected()); - spyConnected.clear(); - - // Now the service goes away - fakeLogind.reset(); - - // And the integration should no longer be connected - QVERIFY(spyConnected.wait()); - QVERIFY(!logind->isConnected()); - spyConnected.clear(); - - // Now the service is brought up again - fakeLogind.reset(new FakeLogind); - - // And the integration should connect again - QVERIFY(spyConnected.wait()); - QVERIFY(logind->isConnected()); - - // Delete - fakeLogind.reset(); - logind->deleteLater(); - } - - void testPropertySessionActive() - { - CustomLogind *logind = new CustomLogind; - - // Spy on sessionActiveChanged(bool) - QSignalSpy spySessionActive(logind, SIGNAL(sessionActiveChanged(bool))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spySessionActive.wait()); - QVERIFY(logind->isSessionActive()); - - fakeLogind->deleteLater(); - logind->deleteLater(); - - QTest::qWait(1000); - } - - void testPropertyVtNumber() - { - CustomLogind *logind = new CustomLogind; - QCOMPARE(logind->vtNumber(), -1); - - // Spy on vtNumberChanged(int) - QSignalSpy spyVtNumber(logind, SIGNAL(vtNumberChanged(int))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyVtNumber.wait()); - QCOMPARE(logind->vtNumber(), 1); - - fakeLogind->deleteLater(); - logind->deleteLater(); - - QTest::qWait(1000); - } - - void testSessionControl() - { - // Connect to a fake logind service and wait for the signal - CustomLogind *logind = new CustomLogind; - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - QSignalSpy spyTakeControl(logind, SIGNAL(hasSessionControlChanged(bool))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyConnected.wait()); - - // Take control as soon as we are connected to logind and - // then release control, we should have received two signals - logind->takeControl(); - spyTakeControl.wait(); - logind->releaseControl(); - spyTakeControl.wait(); - QCOMPARE(spyTakeControl.count(), 2); - - fakeLogind->deleteLater(); - logind->deleteLater(); - - QTest::qWait(1000); - } - - void testLockUnlock() - { - // Connect and spy on lockSessionRequested() and unlockSessionRequested() - CustomLogind *logind = new CustomLogind; - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - QSignalSpy spyLock(logind, SIGNAL(lockSessionRequested())); - QSignalSpy spyUnlock(logind, SIGNAL(unlockSessionRequested())); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyConnected.wait()); - - // Lock - fakeLogind->doLock(); - QVERIFY(spyLock.wait()); - - // Unlock - fakeLogind->doUnlock(); - QVERIFY(spyUnlock.wait()); - - logind->deleteLater(); - fakeLogind->deleteLater(); - - QTest::qWait(1000); - } - - void testPrepareForSleep() - { - // Connect and spy on prepareForSleep(bool) - CustomLogind *logind = new CustomLogind; - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - QSignalSpy spyPrepare(logind, SIGNAL(prepareForSleep(bool))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyConnected.wait()); - - // Prepare for sleep before - fakeLogind->doPrepareForSleep(true); - QVERIFY(spyPrepare.wait()); - - // Prepare for sleep after - fakeLogind->doPrepareForSleep(false); - QVERIFY(spyPrepare.wait()); - - logind->deleteLater(); - fakeLogind->deleteLater(); - - QTest::qWait(1000); - } - - void testPrepareForShutdown() - { - // Connect and spy on prepareForShutdown(bool) - CustomLogind *logind = new CustomLogind; - QSignalSpy spyConnected(logind, SIGNAL(connectedChanged(bool))); - QSignalSpy spyPrepare(logind, SIGNAL(prepareForShutdown(bool))); - FakeLogind *fakeLogind = new FakeLogind; - QVERIFY(spyConnected.wait()); - - // Prepare for shutdown before - fakeLogind->doPrepareForShutdown(true); - QVERIFY(spyPrepare.wait()); - - // Prepare for shutdown after - fakeLogind->doPrepareForShutdown(false); - QVERIFY(spyPrepare.wait()); - - logind->deleteLater(); - fakeLogind->deleteLater(); - - QTest::qWait(1000); - } -}; - -QTEST_MAIN(TestLogind) - -#include "tst_logind.moc"