File indexing completed on 2024-04-28 05:36:16

0001 /*
0002  *   SPDX-FileCopyrightText: 2010 Dario Freddi <drf@kde.org>
0003  *   SPDX-FileCopyrightText: 2012 Lukáš Tinkl <ltinkl@redhat.com>
0004  *
0005  *   SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #pragma once
0009 
0010 #include <QHash>
0011 #include <QList>
0012 #include <QObject>
0013 #include <QPointer>
0014 #include <QStringList>
0015 
0016 #include <QDBusContext>
0017 #include <QDBusUnixFileDescriptor>
0018 
0019 #include "powerdevilcore_export.h"
0020 
0021 class QDBusServiceWatcher;
0022 class QDBusInterface;
0023 
0024 class OrgFreedesktopScreenSaverInterface;
0025 
0026 #define SYSTEMD_LOGIN1_SERVICE "org.freedesktop.login1"
0027 #define SYSTEMD_LOGIN1_PATH "/org/freedesktop/login1"
0028 #define SYSTEMD_LOGIN1_MANAGER_IFACE "org.freedesktop.login1.Manager"
0029 #define SYSTEMD_LOGIN1_SESSION_IFACE "org.freedesktop.login1.Session"
0030 #define SYSTEMD_LOGIN1_SEAT_IFACE "org.freedesktop.login1.Seat"
0031 
0032 #define CONSOLEKIT_SERVICE "org.freedesktop.ConsoleKit"
0033 #define CONSOLEKIT_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
0034 #define CONSOLEKIT_MANAGER_IFACE "org.freedesktop.ConsoleKit.Manager"
0035 
0036 using InhibitionInfo = QPair<QString, QString>;
0037 
0038 struct LogindInhibition {
0039     QString what;
0040     QString who;
0041     QString why;
0042     QString mode;
0043     uint pid;
0044     uint uid;
0045 
0046     bool operator==(const LogindInhibition &other) const
0047     {
0048         return what == other.what && who == other.who && why == other.why && mode == other.mode && pid == other.pid && uid == other.uid;
0049     }
0050 };
0051 
0052 namespace PowerDevil
0053 {
0054 class POWERDEVILCORE_EXPORT PolicyAgent : public QObject, protected QDBusContext
0055 {
0056     Q_OBJECT
0057     Q_DISABLE_COPY(PolicyAgent)
0058 
0059     Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement.PolicyAgent")
0060 
0061 public:
0062     enum RequiredPolicy {
0063         None = 0,
0064         InterruptSession = 1,
0065         ChangeScreenSettings = 4,
0066     };
0067     Q_DECLARE_FLAGS(RequiredPolicies, RequiredPolicy)
0068 
0069     static PolicyAgent *instance();
0070 
0071     ~PolicyAgent() override;
0072 
0073     /**
0074      * This function performs a policy check on given policies, and returns a set of unsatisfiable policies,
0075      * or \c None if all the policies are satisfiable and the action can be carried on.
0076      */
0077     RequiredPolicies requirePolicyCheck(RequiredPolicies policies);
0078 
0079     RequiredPolicies unavailablePolicies();
0080 
0081     bool screenLockerActive() const;
0082 
0083     void setupSystemdInhibition();
0084 
0085 public Q_SLOTS:
0086     // Exported slots
0087     uint AddInhibition(uint types, const QString &appName, const QString &reason);
0088     void ReleaseInhibition(uint cookie);
0089     QList<InhibitionInfo> ListInhibitions() const;
0090     bool HasInhibition(uint types);
0091 
0092     void releaseAllInhibitions();
0093 
0094 Q_SIGNALS:
0095     // Exported signals
0096     void InhibitionsChanged(const QList<InhibitionInfo> &added, const QStringList &removed);
0097 
0098     void unavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies newpolicies);
0099     void sessionActiveChanged(bool active);
0100     void screenLockerActiveChanged(bool active);
0101 
0102 private Q_SLOTS:
0103     void onServiceUnregistered(const QString &serviceName);
0104     void onSessionHandlerRegistered(const QString &serviceName);
0105     void onSessionHandlerUnregistered(const QString &serviceName);
0106     void onActiveSessionChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps);
0107     void onActiveSessionChanged(const QString &activeSession);
0108 
0109     void onManagerPropertyChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps);
0110 
0111 private:
0112     explicit PolicyAgent(QObject *parent = nullptr);
0113 
0114     void init();
0115 
0116     void addInhibitionTypeHelper(uint cookie, RequiredPolicies types);
0117 
0118     void checkLogindInhibitions();
0119 
0120     // Screen locker integration
0121     void onScreenLockerOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner);
0122     QDBusServiceWatcher *m_screenLockerWatcher;
0123 
0124     void onScreenLockerActiveChanged(bool active);
0125     OrgFreedesktopScreenSaverInterface *m_screenLockerInterface = nullptr;
0126     bool m_screenLockerActive = false;
0127 
0128     // This function serves solely for fd.o connector
0129     uint addInhibitionWithExplicitDBusService(uint types, const QString &appName, const QString &reason, const QString &service);
0130 
0131     // used by systemd and ConsoleKit
0132     QScopedPointer<QDBusInterface> m_managerIface;
0133 
0134     // systemd support
0135     QString getNamedPathProperty(const QString &path, const QString &iface, const QString &prop) const;
0136     bool m_sdAvailable;
0137     QString m_activeSessionPath;
0138     QPointer<QDBusInterface> m_sdSessionInterface;
0139     QPointer<QDBusInterface> m_sdSeatInterface;
0140     QDBusUnixFileDescriptor m_systemdInhibitFd;
0141 
0142     // ConsoleKit support
0143     bool m_ckAvailable;
0144     QPointer<QDBusInterface> m_ckSessionInterface;
0145     QPointer<QDBusInterface> m_ckSeatInterface;
0146     bool m_sessionIsBeingInterrupted;
0147 
0148     QHash<uint, QPair<QString, QString>> m_cookieToAppName;
0149     QHash<uint, QString> m_cookieToBusService;
0150     QHash<RequiredPolicy, QList<uint>> m_typesToCookie;
0151 
0152     QHash<uint, LogindInhibition> m_logindInhibitions;
0153 
0154     QList<int> m_pendingInhibitions;
0155 
0156     uint m_lastCookie;
0157 
0158     QPointer<QDBusServiceWatcher> m_busWatcher;
0159     QPointer<QDBusServiceWatcher> m_sdWatcher;
0160     QPointer<QDBusServiceWatcher> m_ckWatcher;
0161 
0162     bool m_wasLastActiveSession;
0163 
0164     friend class Core;
0165     friend class FdoConnector;
0166 };
0167 
0168 }