File indexing completed on 2024-04-28 16:55:15

0001 /***************************************************************************
0002  *   Copyright (C) 2010 by Dario Freddi <drf@kde.org>                      *
0003  *   Copyright (C) 2012 Lukáš Tinkl <ltinkl@redhat.com>                    *
0004  *                                                                         *
0005  *   This program is free software; you can redistribute it and/or modify  *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
0019  ***************************************************************************/
0020 
0021 
0022 #ifndef POWERDEVIL_POWERDEVILPOLICYAGENT_H
0023 #define POWERDEVIL_POWERDEVILPOLICYAGENT_H
0024 
0025 #include <QObject>
0026 #include <QHash>
0027 #include <QStringList>
0028 #include <QPointer>
0029 #include <QVector>
0030 
0031 #include <QDBusContext>
0032 #include <QDBusUnixFileDescriptor>
0033 
0034 class QDBusServiceWatcher;
0035 class QDBusInterface;
0036 
0037 class OrgFreedesktopScreenSaverInterface;
0038 
0039 #define SYSTEMD_LOGIN1_SERVICE "org.freedesktop.login1"
0040 #define SYSTEMD_LOGIN1_PATH "/org/freedesktop/login1"
0041 #define SYSTEMD_LOGIN1_MANAGER_IFACE "org.freedesktop.login1.Manager"
0042 #define SYSTEMD_LOGIN1_SESSION_IFACE "org.freedesktop.login1.Session"
0043 #define SYSTEMD_LOGIN1_SEAT_IFACE "org.freedesktop.login1.Seat"
0044 
0045 #define CONSOLEKIT_SERVICE "org.freedesktop.ConsoleKit"
0046 #define CONSOLEKIT_MANAGER_PATH "/org/freedesktop/ConsoleKit/Manager"
0047 #define CONSOLEKIT_MANAGER_IFACE "org.freedesktop.ConsoleKit.Manager"
0048 
0049 using InhibitionInfo = QPair<QString, QString>;
0050 
0051 struct LogindInhibition
0052 {
0053     QString what;
0054     QString who;
0055     QString why;
0056     QString mode;
0057     uint pid;
0058     uint uid;
0059 
0060     bool operator==(const LogindInhibition &other) const
0061     {
0062         return what == other.what && who == other.who && why == other.why && mode == other.mode
0063                 && pid == other.pid && uid == other.uid;
0064     }
0065 };
0066 
0067 namespace PowerDevil
0068 {
0069 
0070 class Q_DECL_EXPORT PolicyAgent : public QObject, protected QDBusContext
0071 {
0072     Q_OBJECT
0073     Q_DISABLE_COPY(PolicyAgent)
0074 
0075     Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement.PolicyAgent")
0076 
0077 public:
0078     enum RequiredPolicy {
0079         None = 0,
0080         InterruptSession = 1,
0081         ChangeProfile = 2,
0082         ChangeScreenSettings = 4
0083     };
0084     Q_DECLARE_FLAGS(RequiredPolicies, RequiredPolicy)
0085 
0086     static PolicyAgent *instance();
0087 
0088     ~PolicyAgent() override;
0089 
0090     /**
0091      * This function performs a policy check on given policies, and returns a set of unsatisfiable policies,
0092      * or \c None if all the policies are satisfiable and the action can be carried on.
0093      */
0094     RequiredPolicies requirePolicyCheck(RequiredPolicies policies);
0095 
0096     RequiredPolicies unavailablePolicies();
0097 
0098     bool screenLockerActive() const;
0099 
0100     void setupSystemdInhibition();
0101 
0102 public Q_SLOTS:
0103     // Exported slots
0104     uint AddInhibition(uint types, const QString &appName, const QString &reason);
0105     void ReleaseInhibition(uint cookie);
0106     QList<InhibitionInfo> ListInhibitions() const;
0107     bool HasInhibition(uint types);
0108 
0109     void releaseAllInhibitions();
0110 
0111 Q_SIGNALS:
0112     // Exported signals
0113     void InhibitionsChanged(const QList<InhibitionInfo> &added, const QStringList &removed);
0114 
0115     void unavailablePoliciesChanged(PowerDevil::PolicyAgent::RequiredPolicies newpolicies);
0116     void sessionActiveChanged(bool active);
0117     void screenLockerActiveChanged(bool active);
0118 
0119 private Q_SLOTS:
0120     void onServiceUnregistered(const QString & serviceName);
0121     void onSessionHandlerRegistered(const QString & serviceName);
0122     void onSessionHandlerUnregistered(const QString & serviceName);
0123     void onActiveSessionChanged(const QString & ifaceName, const QVariantMap & changedProps, const QStringList & invalidatedProps);
0124     void onActiveSessionChanged(const QString &activeSession);
0125 
0126     void onManagerPropertyChanged(const QString &ifaceName, const QVariantMap &changedProps, const QStringList &invalidatedProps);
0127 
0128 private:
0129     explicit PolicyAgent(QObject* parent = nullptr);
0130 
0131     void init();
0132     void startSessionInterruption();
0133     void finishSessionInterruption();
0134 
0135     void addInhibitionTypeHelper(uint cookie, RequiredPolicies types);
0136 
0137     void checkLogindInhibitions();
0138 
0139     // Screen locker integration
0140     void onScreenLockerOwnerChanged(const QString &serviceName, const QString &oldOwner, const QString &newOwner);
0141     QDBusServiceWatcher *m_screenLockerWatcher;
0142 
0143     void onScreenLockerActiveChanged(bool active);
0144     OrgFreedesktopScreenSaverInterface *m_screenLockerInterface = nullptr;
0145     bool m_screenLockerActive = false;
0146 
0147     // This function serves solely for fd.o connector
0148     uint addInhibitionWithExplicitDBusService(uint types, const QString &appName,
0149                                               const QString &reason, const QString &service);
0150 
0151     // used by systemd and ConsoleKit
0152     QScopedPointer< QDBusInterface > m_managerIface;
0153 
0154     // systemd support
0155     QString getNamedPathProperty(const QString & path, const QString & iface, const QString & prop) const;
0156     bool m_sdAvailable;
0157     QString m_activeSessionPath;
0158     QPointer< QDBusInterface > m_sdSessionInterface;
0159     QPointer< QDBusInterface > m_sdSeatInterface;
0160     QDBusUnixFileDescriptor m_systemdInhibitFd;
0161 
0162     // ConsoleKit support
0163     bool m_ckAvailable;
0164     QPointer< QDBusInterface > m_ckSessionInterface;
0165     QPointer< QDBusInterface > m_ckSeatInterface;
0166     bool m_sessionIsBeingInterrupted;
0167 
0168     QHash< uint, QPair< QString, QString > > m_cookieToAppName;
0169     QHash< uint, QString > m_cookieToBusService;
0170     QHash< RequiredPolicy, QList< uint > > m_typesToCookie;
0171 
0172     QHash<uint, LogindInhibition> m_logindInhibitions;
0173 
0174     QVector<int> m_pendingInhibitions;
0175 
0176     uint m_lastCookie;
0177 
0178     QPointer< QDBusServiceWatcher > m_busWatcher;
0179     QPointer< QDBusServiceWatcher > m_sdWatcher;
0180     QPointer< QDBusServiceWatcher > m_ckWatcher;
0181 
0182     bool m_wasLastActiveSession;
0183 
0184     friend class Core;
0185     friend class FdoConnector;
0186 };
0187 
0188 }
0189 
0190 #endif // POWERDEVIL_POWERDEVILPOLICYAGENT_H