File indexing completed on 2024-05-12 09:41:27

0001 /*
0002  *   SPDX-FileCopyrightText: 2010 Dario Freddi <drf@kde.org>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #pragma once
0008 
0009 #include "powerdevilbackendinterface.h"
0010 
0011 #include <QPointer>
0012 #include <QSet>
0013 #include <QStringList>
0014 
0015 #include <QDBusContext>
0016 #include <QDBusError>
0017 #include <QDBusMessage>
0018 #include <QDBusObjectPath>
0019 
0020 #include <QSocketNotifier>
0021 
0022 #include <KSharedConfig>
0023 
0024 #include "batterycontroller.h"
0025 #include "lidcontroller.h"
0026 #include "powerdevilcore_export.h"
0027 #include "suspendcontroller.h"
0028 
0029 namespace KActivities
0030 {
0031 class Consumer;
0032 } // namespace KActivities
0033 
0034 class QDBusServiceWatcher;
0035 class QTimer;
0036 class KNotification;
0037 
0038 namespace Solid
0039 {
0040 class Battery;
0041 }
0042 
0043 namespace PowerDevil
0044 {
0045 class BackendInterface;
0046 class Action;
0047 class GlobalSettings;
0048 
0049 struct WakeupInfo {
0050     QString service;
0051     QDBusObjectPath path;
0052     int cookie;
0053     qint64 timeout;
0054 };
0055 
0056 class POWERDEVILCORE_EXPORT Core : public QObject, protected QDBusContext
0057 {
0058     Q_OBJECT
0059     Q_DISABLE_COPY(Core)
0060     Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement")
0061 
0062 public:
0063     explicit Core(QObject *parent);
0064     ~Core() override;
0065 
0066     void reloadProfile(int state);
0067 
0068     void emitRichNotification(const QString &evid, const QString &title, const QString &message = QString());
0069 
0070     void emitNotification(const QString &eventId, const QString &title, const QString &message, const QString &iconName);
0071 
0072     enum class ChargeNotificationFlag {
0073         None,
0074         NotifyWhenAcPluggedIn,
0075     };
0076     Q_DECLARE_FLAGS(ChargeNotificationFlags, ChargeNotificationFlag)
0077     Q_FLAG(ChargeNotificationFlags)
0078 
0079     bool emitBatteryChargePercentNotification(int currentPercent, int previousPercent, const QString &udi = QString(), ChargeNotificationFlags flags = {});
0080 
0081     BackendInterface *backend();
0082     SuspendController *suspendController();
0083     BatteryController *batteryController();
0084     LidController *lidController();
0085 
0086     Action *action(const QString actionId);
0087 
0088     // More...
0089 
0090 public Q_SLOTS:
0091     void loadCore(PowerDevil::BackendInterface *backend);
0092     // Set of common action - useful for the DBus interface
0093     uint backendCapabilities();
0094     void refreshStatus();
0095     void reparseConfiguration();
0096 
0097     QString currentProfile() const;
0098     void loadProfile(bool force = false);
0099 
0100     qulonglong batteryRemainingTime() const;
0101     qulonglong smoothedBatteryRemainingTime() const;
0102 
0103     bool isLidClosed() const;
0104     bool isLidPresent() const;
0105     bool isActionSupported(const QString &actionName);
0106     bool hasDualGpu() const;
0107     int chargeStartThreshold() const;
0108     int chargeStopThreshold() const;
0109 
0110     // service - dbus interface to ping when wakeup is done
0111     // path - dbus path on service
0112     // cookie - data to pass back
0113     // silent - true if silent wakeup is needed
0114     uint scheduleWakeup(const QString &service, const QDBusObjectPath &path, qint64 timeout);
0115     void wakeup();
0116     void clearWakeup(int cookie);
0117 
0118 Q_SIGNALS:
0119     void coreReady();
0120     void profileChanged(const QString &newProfile);
0121     void configurationReloaded();
0122     void batteryRemainingTimeChanged(qulonglong time);
0123     void smoothedBatteryRemainingTimeChanged(qulonglong time);
0124     void lidClosedChanged(bool closed);
0125     void chargeStartThresholdChanged(int threshold);
0126     void chargeStopThresholdChanged(int threshold);
0127 
0128 private:
0129     void initActions();
0130     void unloadAllActiveActions();
0131     void registerActionTimeout(Action *action, std::chrono::milliseconds timeout);
0132     void unregisterActionTimeouts(Action *action);
0133     void handleLowBattery(int percent);
0134     void handleCriticalBattery(int percent);
0135     void updateBatteryNotifications(int percent);
0136     void triggerCriticalBatteryAction();
0137 
0138     void readChargeThreshold();
0139 
0140     /**
0141      * Computes the current global charge percentage.
0142      * Sum of all battery charges.
0143      */
0144     int currentChargePercent() const;
0145 
0146     friend class Action;
0147 
0148     bool m_hasDualGpu;
0149     int m_chargeStartThreshold = 0;
0150     int m_chargeStopThreshold = 100;
0151 
0152     BackendInterface *m_backend = nullptr;
0153     std::unique_ptr<SuspendController> m_suspendController;
0154     std::unique_ptr<BatteryController> m_batteryController;
0155     std::unique_ptr<LidController> m_lidController;
0156 
0157     QDBusServiceWatcher *m_notificationsWatcher = nullptr;
0158     bool m_notificationsReady = false;
0159 
0160     GlobalSettings *m_globalSettings = nullptr;
0161 
0162     QString m_currentProfile;
0163 
0164     QHash<QString, int> m_batteriesPercent;
0165     QHash<QString, int> m_peripheralBatteriesPercent;
0166     QHash<QString, bool> m_batteriesCharged;
0167 
0168     QPointer<KNotification> m_lowBatteryNotification;
0169     QTimer *const m_criticalBatteryTimer;
0170     QPointer<KNotification> m_criticalBatteryNotification;
0171 
0172     KActivities::Consumer *const m_activityConsumer;
0173 
0174     // Idle time management
0175     QHash<Action *, QList<int>> m_registeredActionTimeouts;
0176     QSet<Action *> m_pendingResumeFromIdleActions;
0177     bool m_pendingWakeupEvent;
0178 
0179     // Scheduled wakeups and alarms
0180     QList<WakeupInfo> m_scheduledWakeups;
0181     int m_lastWakeupCookie = 0;
0182     int m_timerFd = -1;
0183     QSocketNotifier *m_timerFdSocketNotifier = nullptr;
0184 
0185     // Activity inhibition management
0186     QHash<QString, int> m_sessionActivityInhibit;
0187     QHash<QString, int> m_screenActivityInhibit;
0188 
0189     QHash<QString, Action *> m_actionPool;
0190     QStringList m_activeActions;
0191 
0192 private Q_SLOTS:
0193     void onBackendReady();
0194     void onAcAdapterStateChanged(BatteryController::AcAdapterState);
0195     void onBatteryChargePercentChanged(int, const QString &);
0196     void onBatteryChargeStateChanged(int, const QString &);
0197     void onBatteryRemainingTimeChanged(qulonglong);
0198     void onSmoothedBatteryRemainingTimeChanged(qulonglong);
0199     void onKIdleTimeoutReached(int, int);
0200     void onResumingFromIdle();
0201     void onDeviceAdded(const QString &udi);
0202     void onDeviceRemoved(const QString &udi);
0203     void onCriticalBatteryTimerExpired();
0204     void onNotificationTimeout();
0205     void onServiceRegistered(const QString &service);
0206     void onLidClosedChanged(bool closed);
0207     void onAboutToSuspend();
0208     // handlers for handling wakeup dbus call
0209     void resetAndScheduleNextWakeup();
0210     void timerfdEventHandler();
0211 };
0212 
0213 }