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

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