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

0001 /***************************************************************************
0002  *   Copyright (C) 2010 by Dario Freddi <drf@kde.org>                      *
0003  *                                                                         *
0004  *   This program is free software; you can redistribute it and/or modify  *
0005  *   it under the terms of the GNU General Public License as published by  *
0006  *   the Free Software Foundation; either version 2 of the License, or     *
0007  *   (at your option) any later version.                                   *
0008  *                                                                         *
0009  *   This program is distributed in the hope that it will be useful,       *
0010  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0011  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0012  *   GNU General Public License for more details.                          *
0013  *                                                                         *
0014  *   You should have received a copy of the GNU General Public License     *
0015  *   along with this program; if not, write to the                         *
0016  *   Free Software Foundation, Inc.,                                       *
0017  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
0018  ***************************************************************************/
0019 
0020 
0021 #ifndef POWERDEVILCORE_H
0022 #define POWERDEVILCORE_H
0023 
0024 #include "powerdevilbackendinterface.h"
0025 
0026 #include <QPointer>
0027 #include <QSet>
0028 #include <QStringList>
0029 
0030 #include <QDBusMessage>
0031 #include <QDBusError>
0032 #include <QDBusContext>
0033 #include <QDBusObjectPath>
0034 
0035 #include <QSocketNotifier>
0036 
0037 #include <KSharedConfig>
0038 
0039 namespace KActivities
0040 {
0041     class Consumer;
0042 } // namespace KActivities
0043 
0044 class QDBusServiceWatcher;
0045 class QTimer;
0046 class KNotification;
0047 
0048 namespace Solid {
0049 class Battery;
0050 }
0051 
0052 namespace PowerDevil
0053 {
0054 
0055 class BackendInterface;
0056 class Action;
0057 
0058 struct WakeupInfo {
0059     QString service;
0060     QDBusObjectPath path;
0061     int cookie;
0062     qint64 timeout;
0063 };
0064 
0065 class Q_DECL_EXPORT Core : public QObject, protected QDBusContext
0066 {
0067     Q_OBJECT
0068     Q_DISABLE_COPY(Core)
0069     Q_CLASSINFO("D-Bus Interface", "org.kde.Solid.PowerManagement")
0070 
0071 public:
0072     explicit Core(QObject* parent);
0073     ~Core() override;
0074 
0075     void reloadProfile(int state);
0076 
0077     void emitRichNotification(const QString &evid, const QString &title, const QString &message = QString());
0078 
0079     void emitNotification(const QString &eventId, const QString &title, const QString &message, const QString &iconName);
0080 
0081     enum class ChargeNotificationFlag {
0082         None,
0083         NotifyWhenAcPluggedIn
0084     };
0085     Q_DECLARE_FLAGS(ChargeNotificationFlags, ChargeNotificationFlag)
0086     Q_FLAG(ChargeNotificationFlags)
0087 
0088     bool emitBatteryChargePercentNotification(int currentPercent, int previousPercent, const QString &udi = QString(), ChargeNotificationFlags flags = {});
0089 
0090     BackendInterface *backend();
0091 
0092     // More...
0093 
0094 public Q_SLOTS:
0095     void loadCore(PowerDevil::BackendInterface *backend);
0096     // Set of common action - useful for the DBus interface
0097     uint backendCapabilities();
0098     void refreshStatus();
0099     void reparseConfiguration();
0100 
0101     QString currentProfile() const;
0102     void loadProfile(bool force = false);
0103 
0104     qulonglong batteryRemainingTime() const;
0105     qulonglong smoothedBatteryRemainingTime() const;
0106 
0107     bool isLidClosed() const;
0108     bool isLidPresent() const;
0109     bool isActionSupported(const QString &actionName);
0110     bool hasDualGpu() const;
0111     int chargeStartThreshold() const;
0112     int chargeStopThreshold() const;
0113 
0114     // service - dbus interface to ping when wakeup is done
0115     // path - dbus path on service
0116     // cookie - data to pass back
0117     // silent - true if silent wakeup is needed
0118     uint scheduleWakeup(const QString &service, const QDBusObjectPath &path, qint64 timeout);
0119     void wakeup();
0120     void clearWakeup(int cookie);
0121 
0122 Q_SIGNALS:
0123     void coreReady();
0124     void profileChanged(const QString &newProfile);
0125     void configurationReloaded();
0126     void batteryRemainingTimeChanged(qulonglong time);
0127     void smoothedBatteryRemainingTimeChanged(qulonglong time);
0128     void lidClosedChanged(bool closed);
0129     void chargeStartThresholdChanged(int threshold);
0130     void chargeStopThresholdChanged(int threshold);
0131 
0132 private:
0133     void registerActionTimeout(Action *action, int timeout);
0134     void unregisterActionTimeouts(Action *action);
0135     void handleLowBattery(int percent);
0136     void handleCriticalBattery(int percent);
0137     void updateBatteryNotifications(int percent);
0138     void triggerCriticalBatteryAction();
0139 
0140     void readChargeThreshold();
0141 
0142     /**
0143      * Computes the current global charge percentage.
0144      * Sum of all battery charges.
0145      */
0146     int currentChargePercent() const;
0147 
0148     friend class Action;
0149 
0150     bool m_hasDualGpu;
0151     int m_chargeStartThreshold = 0;
0152     int m_chargeStopThreshold = 100;
0153 
0154     BackendInterface *m_backend = nullptr;
0155 
0156     QDBusServiceWatcher *m_notificationsWatcher = nullptr;
0157     bool m_notificationsReady = false;
0158 
0159     KSharedConfigPtr m_profilesConfig;
0160 
0161     QString m_currentProfile;
0162 
0163     QHash<QString, int> m_batteriesPercent;
0164     QHash<QString, int> m_peripheralBatteriesPercent;
0165     QHash<QString, bool> m_batteriesCharged;
0166 
0167     QPointer<KNotification> m_lowBatteryNotification;
0168     QTimer *const m_criticalBatteryTimer;
0169     QPointer<KNotification> m_criticalBatteryNotification;
0170 
0171     KActivities::Consumer *const m_activityConsumer;
0172 
0173     // Idle time management
0174     QHash< Action*, QList< int > > m_registeredActionTimeouts;
0175     QSet<Action *> m_pendingResumeFromIdleActions;
0176     bool m_pendingWakeupEvent;
0177 
0178     // Scheduled wakeups and alarms
0179     QList<WakeupInfo> m_scheduledWakeups;
0180     int m_lastWakeupCookie = 0;
0181     int m_timerFd = -1;
0182     QSocketNotifier *m_timerFdSocketNotifier = nullptr;
0183 
0184     // Activity inhibition management
0185     QHash< QString, int > m_sessionActivityInhibit;
0186     QHash< QString, int > m_screenActivityInhibit;
0187 
0188 private Q_SLOTS:
0189     void onBackendReady();
0190     void onAcAdapterStateChanged(PowerDevil::BackendInterface::AcAdapterState);
0191     void onBatteryChargePercentChanged(int,const QString&);
0192     void onBatteryChargeStateChanged(int,const QString&);
0193     void onBatteryRemainingTimeChanged(qulonglong);
0194     void onSmoothedBatteryRemainingTimeChanged(qulonglong);
0195     void onKIdleTimeoutReached(int,int);
0196     void onResumingFromIdle();
0197     void onDeviceAdded(const QString &udi);
0198     void onDeviceRemoved(const QString &udi);
0199     void onCriticalBatteryTimerExpired();
0200     void onNotificationTimeout();
0201     void onServiceRegistered(const QString &service);
0202     void onLidClosedChanged(bool closed);
0203     void onAboutToSuspend();
0204     // handlers for handling wakeup dbus call
0205     void resetAndScheduleNextWakeup();
0206     void timerfdEventHandler();
0207 };
0208 
0209 }
0210 
0211 #endif // POWERDEVILCORE_H