You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
681 lines
33 KiB
681 lines
33 KiB
/* |
|
* Copyright 2007 Aaron Seigo <aseigo@kde.org> |
|
* Copyright 2007-2008 Sebastian Kuegler <sebas@kde.org> |
|
* CopyRight 2007 Maor Vanmak <mvanmak1@gmail.com> |
|
* Copyright 2008 Dario Freddi <drf54321@gmail.com> |
|
* |
|
* This program is free software; you can redistribute it and/or modify |
|
* it under the terms of the GNU Library General Public License version 2 as |
|
* published by the Free Software Foundation |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details |
|
* |
|
* You should have received a copy of the GNU Library General Public |
|
* License along with this program; if not, write to the |
|
* Free Software Foundation, Inc., |
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
*/ |
|
|
|
#include "powermanagementengine.h" |
|
|
|
//solid specific includes |
|
#include <solid/devicenotifier.h> |
|
#include <solid/device.h> |
|
#include <solid/deviceinterface.h> |
|
#include <solid/battery.h> |
|
#include <solid/powermanagement.h> |
|
|
|
#include <klocalizedstring.h> |
|
#include <KAuthorized> |
|
#include <KIdleTime> |
|
|
|
#include <QDebug> |
|
|
|
#include <QDBusConnectionInterface> |
|
#include <QDBusError> |
|
#include <QDBusInterface> |
|
#include <QDBusMetaType> |
|
#include <QDBusReply> |
|
#include <QDBusPendingCallWatcher> |
|
|
|
#include <Plasma/DataContainer> |
|
#include "powermanagementservice.h" |
|
|
|
static const char SOLID_POWERMANAGEMENT_SERVICE[] = "org.kde.Solid.PowerManagement"; |
|
|
|
Q_DECLARE_METATYPE(QList<InhibitionInfo>) |
|
Q_DECLARE_METATYPE(InhibitionInfo) |
|
|
|
PowermanagementEngine::PowermanagementEngine(QObject* parent, const QVariantList& args) |
|
: Plasma::DataEngine(parent, args) |
|
, m_sources(basicSourceNames()) |
|
{ |
|
Q_UNUSED(args) |
|
qDBusRegisterMetaType<QList<InhibitionInfo>>(); |
|
qDBusRegisterMetaType<InhibitionInfo>(); |
|
init(); |
|
} |
|
|
|
PowermanagementEngine::~PowermanagementEngine() |
|
{} |
|
|
|
void PowermanagementEngine::init() |
|
{ |
|
connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceAdded, |
|
this, &PowermanagementEngine::deviceAdded); |
|
connect(Solid::DeviceNotifier::instance(), &Solid::DeviceNotifier::deviceRemoved, |
|
this, &PowermanagementEngine::deviceRemoved); |
|
|
|
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(SOLID_POWERMANAGEMENT_SERVICE)) { |
|
if (!QDBusConnection::sessionBus().connect(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.Actions.BrightnessControl"), |
|
QStringLiteral("brightnessChanged"), this, |
|
SLOT(screenBrightnessChanged(int)))) { |
|
qDebug() << "error connecting to Brightness changes via dbus"; |
|
} |
|
|
|
if (!QDBusConnection::sessionBus().connect(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.Actions.BrightnessControl"), |
|
QStringLiteral("brightnessMaxChanged"), this, |
|
SLOT(maximumScreenBrightnessChanged(int)))) { |
|
qDebug() << "error connecting to max brightness changes via dbus"; |
|
} |
|
|
|
if (!QDBusConnection::sessionBus().connect(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl"), |
|
QStringLiteral("keyboardBrightnessChanged"), this, |
|
SLOT(keyboardBrightnessChanged(int)))) { |
|
qDebug() << "error connecting to Keyboard Brightness changes via dbus"; |
|
} |
|
|
|
if (!QDBusConnection::sessionBus().connect(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl"), |
|
QStringLiteral("keyboardBrightnessMaxChanged"), this, |
|
SLOT(maximumKeyboardBrightnessChanged(int)))) { |
|
qDebug() << "error connecting to max keyboard Brightness changes via dbus"; |
|
} |
|
|
|
if (!QDBusConnection::sessionBus().connect(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/Actions/HandleButtonEvents"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.Actions.HandleButtonEvents"), |
|
QStringLiteral("triggersLidActionChanged"), this, |
|
SLOT(triggersLidActionChanged(bool)))) { |
|
qDebug() << "error connecting to lid action trigger changes via dbus"; |
|
} |
|
|
|
if (!QDBusConnection::sessionBus().connect(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent"), |
|
QStringLiteral("InhibitionsChanged"), this, |
|
SLOT(inhibitionsChanged(QList<InhibitionInfo>,QStringList)))) { |
|
qDebug() << "error connecting to inhibition changes via dbus"; |
|
} |
|
|
|
if (!QDBusConnection::sessionBus().connect(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement"), |
|
SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("batteryRemainingTimeChanged"), this, |
|
SLOT(batteryRemainingTimeChanged(qulonglong)))) { |
|
qDebug() << "error connecting to remaining time changes"; |
|
} |
|
} |
|
} |
|
|
|
QStringList PowermanagementEngine::basicSourceNames() const |
|
{ |
|
QStringList sources; |
|
sources << QStringLiteral("Battery") << QStringLiteral("AC Adapter") << QStringLiteral("Sleep States") << QStringLiteral("PowerDevil") << QStringLiteral("Inhibitions"); |
|
return sources; |
|
} |
|
|
|
QStringList PowermanagementEngine::sources() const |
|
{ |
|
return m_sources; |
|
} |
|
|
|
bool PowermanagementEngine::sourceRequestEvent(const QString &name) |
|
{ |
|
if (name == QLatin1String("Battery")) { |
|
const QList<Solid::Device> listBattery = Solid::Device::listFromType(Solid::DeviceInterface::Battery); |
|
m_batterySources.clear(); |
|
|
|
if (listBattery.isEmpty()) { |
|
setData(QStringLiteral("Battery"), QStringLiteral("Has Battery"), false); |
|
setData(QStringLiteral("Battery"), QStringLiteral("Has Cumulative"), false); |
|
return true; |
|
} |
|
|
|
uint index = 0; |
|
QStringList batterySources; |
|
|
|
foreach (const Solid::Device &deviceBattery, listBattery) { |
|
const Solid::Battery* battery = deviceBattery.as<Solid::Battery>(); |
|
|
|
const QString source = QStringLiteral("Battery%1").arg(index++); |
|
|
|
batterySources << source; |
|
m_batterySources[deviceBattery.udi()] = source; |
|
|
|
connect(battery, &Solid::Battery::chargeStateChanged, this, |
|
&PowermanagementEngine::updateBatteryChargeState); |
|
connect(battery, &Solid::Battery::chargePercentChanged, this, |
|
&PowermanagementEngine::updateBatteryChargePercent); |
|
connect(battery, &Solid::Battery::energyChanged, |
|
this, &PowermanagementEngine::updateBatteryEnergy); |
|
connect(battery, &Solid::Battery::presentStateChanged, this, |
|
&PowermanagementEngine::updateBatteryPresentState); |
|
|
|
// Set initial values |
|
updateBatteryChargeState(battery->chargeState(), deviceBattery.udi()); |
|
updateBatteryChargePercent(battery->chargePercent(), deviceBattery.udi()); |
|
updateBatteryEnergy(battery->energy(), deviceBattery.udi()); |
|
updateBatteryPresentState(battery->isPresent(), deviceBattery.udi()); |
|
updateBatteryPowerSupplyState(battery->isPowerSupply(), deviceBattery.udi()); |
|
|
|
setData(source, QStringLiteral("Vendor"), deviceBattery.vendor()); |
|
setData(source, QStringLiteral("Product"), deviceBattery.product()); |
|
setData(source, QStringLiteral("Capacity"), battery->capacity()); |
|
setData(source, QStringLiteral("Type"), batteryType(battery)); |
|
} |
|
|
|
updateBatteryNames(); |
|
updateOverallBattery(); |
|
|
|
setData(QStringLiteral("Battery"), QStringLiteral("Has Battery"), !batterySources.isEmpty()); |
|
if (!batterySources.isEmpty()) { |
|
setData(QStringLiteral("Battery"), QStringLiteral("Sources"), batterySources); |
|
QDBusMessage msg = QDBusMessage::createMethodCall(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement"), |
|
SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("batteryRemainingTime")); |
|
QDBusPendingReply<qulonglong> reply = QDBusConnection::sessionBus().asyncCall(msg); |
|
QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(reply, this); |
|
QObject::connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { |
|
QDBusPendingReply<qulonglong> reply = *watcher; |
|
if (!reply.isError()) { |
|
batteryRemainingTimeChanged(reply.value()); |
|
} |
|
watcher->deleteLater(); |
|
}); |
|
} |
|
|
|
m_sources = basicSourceNames() + batterySources; |
|
} else if (name == QLatin1String("AC Adapter")) { |
|
connect(Solid::PowerManagement::notifier(), &Solid::PowerManagement::Notifier::appShouldConserveResourcesChanged, |
|
this, &PowermanagementEngine::updateAcPlugState); |
|
updateAcPlugState(Solid::PowerManagement::appShouldConserveResources()); |
|
} else if (name == QLatin1String("Sleep States")) { |
|
const QSet<Solid::PowerManagement::SleepState> sleepstates = Solid::PowerManagement::supportedSleepStates(); |
|
setData(QStringLiteral("Sleep States"), QStringLiteral("Standby"), sleepstates.contains(Solid::PowerManagement::StandbyState)); |
|
setData(QStringLiteral("Sleep States"), QStringLiteral("Suspend"), sleepstates.contains(Solid::PowerManagement::SuspendState)); |
|
setData(QStringLiteral("Sleep States"), QStringLiteral("Hibernate"), sleepstates.contains(Solid::PowerManagement::HibernateState)); |
|
setData(QStringLiteral("Sleep States"), QStringLiteral("HybridSuspend"), sleepstates.contains(Solid::PowerManagement::HybridSuspendState)); |
|
setData(QStringLiteral("Sleep States"), QStringLiteral("LockScreen"), KAuthorized::authorizeAction(QStringLiteral("lock_screen"))); |
|
setData(QStringLiteral("Sleep States"), QStringLiteral("Logout"), KAuthorized::authorize(QStringLiteral("logout"))); |
|
} else if (name == QLatin1String("PowerDevil")) { |
|
QDBusMessage screenMsg = QDBusMessage::createMethodCall(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.Actions.BrightnessControl"), |
|
QStringLiteral("brightness")); |
|
QDBusPendingReply<int> screenReply = QDBusConnection::sessionBus().asyncCall(screenMsg); |
|
QDBusPendingCallWatcher *screenWatcher = new QDBusPendingCallWatcher(screenReply, this); |
|
QObject::connect(screenWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { |
|
QDBusPendingReply<int> reply = *watcher; |
|
if (!reply.isError()) { |
|
screenBrightnessChanged(reply.value()); |
|
} |
|
watcher->deleteLater(); |
|
}); |
|
|
|
QDBusMessage maxScreenMsg = QDBusMessage::createMethodCall(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/Actions/BrightnessControl"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.Actions.BrightnessControl"), |
|
QStringLiteral("brightnessMax")); |
|
QDBusPendingReply<int> maxScreenReply = QDBusConnection::sessionBus().asyncCall(maxScreenMsg); |
|
QDBusPendingCallWatcher *maxScreenWatcher = new QDBusPendingCallWatcher(maxScreenReply, this); |
|
QObject::connect(maxScreenWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { |
|
QDBusPendingReply<int> reply = *watcher; |
|
if (!reply.isError()) { |
|
maximumScreenBrightnessChanged(reply.value()); |
|
} |
|
watcher->deleteLater(); |
|
}); |
|
|
|
QDBusMessage keyboardMsg = QDBusMessage::createMethodCall(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl"), |
|
QStringLiteral("keyboardBrightness")); |
|
QDBusPendingReply<int> keyboardReply = QDBusConnection::sessionBus().asyncCall(keyboardMsg); |
|
QDBusPendingCallWatcher *keyboardWatcher = new QDBusPendingCallWatcher(keyboardReply, this); |
|
QObject::connect(keyboardWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { |
|
QDBusPendingReply<int> reply = *watcher; |
|
if (!reply.isError()) { |
|
keyboardBrightnessChanged(reply.value()); |
|
} |
|
watcher->deleteLater(); |
|
}); |
|
|
|
QDBusMessage maxKeyboardMsg = QDBusMessage::createMethodCall(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/Actions/KeyboardBrightnessControl"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.Actions.KeyboardBrightnessControl"), |
|
QStringLiteral("keyboardBrightnessMax")); |
|
QDBusPendingReply<int> maxKeyboardReply = QDBusConnection::sessionBus().asyncCall(maxKeyboardMsg); |
|
QDBusPendingCallWatcher *maxKeyboardWatcher = new QDBusPendingCallWatcher(maxKeyboardReply, this); |
|
QObject::connect(maxKeyboardWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { |
|
QDBusPendingReply<int> reply = *watcher; |
|
if (!reply.isError()) { |
|
maximumKeyboardBrightnessChanged(reply.value()); |
|
} |
|
watcher->deleteLater(); |
|
}); |
|
|
|
|
|
QDBusMessage lidIsPresentMsg = QDBusMessage::createMethodCall(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement"), |
|
SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("isLidPresent")); |
|
QDBusPendingReply<bool> lidIsPresentReply = QDBusConnection::sessionBus().asyncCall(lidIsPresentMsg); |
|
QDBusPendingCallWatcher *lidIsPresentWatcher = new QDBusPendingCallWatcher(lidIsPresentReply, this); |
|
QObject::connect(lidIsPresentWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { |
|
QDBusPendingReply<bool> reply = *watcher; |
|
if (!reply.isError()) { |
|
setData(QStringLiteral("PowerDevil"), QStringLiteral("Is Lid Present"), reply.value()); |
|
} |
|
watcher->deleteLater(); |
|
}); |
|
|
|
QDBusMessage triggersLidActionMsg = QDBusMessage::createMethodCall(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/Actions/HandleButtonEvents"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.Actions.HandleButtonEvents"), |
|
QStringLiteral("triggersLidAction")); |
|
QDBusPendingReply<bool> triggersLidActionReply = QDBusConnection::sessionBus().asyncCall(triggersLidActionMsg); |
|
QDBusPendingCallWatcher *triggersLidActionWatcher = new QDBusPendingCallWatcher(triggersLidActionReply, this); |
|
QObject::connect(triggersLidActionWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { |
|
QDBusPendingReply<bool> reply = *watcher; |
|
if (!reply.isError()) { |
|
triggersLidActionChanged(reply.value()); |
|
} |
|
watcher->deleteLater(); |
|
}); |
|
|
|
} else if (name == QLatin1String("Inhibitions")) { |
|
QDBusMessage inhibitionsMsg = QDBusMessage::createMethodCall(SOLID_POWERMANAGEMENT_SERVICE, |
|
QStringLiteral("/org/kde/Solid/PowerManagement/PolicyAgent"), |
|
QStringLiteral("org.kde.Solid.PowerManagement.PolicyAgent"), |
|
QStringLiteral("ListInhibitions")); |
|
QDBusPendingReply<QList<InhibitionInfo>> inhibitionsReply = QDBusConnection::sessionBus().asyncCall(inhibitionsMsg); |
|
QDBusPendingCallWatcher *inhibitionsWatcher = new QDBusPendingCallWatcher(inhibitionsReply, this); |
|
QObject::connect(inhibitionsWatcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) { |
|
QDBusPendingReply<QList<InhibitionInfo>> reply = *watcher; |
|
watcher->deleteLater(); |
|
|
|
if (!reply.isError()) { |
|
removeAllData(QStringLiteral("Inhibitions")); |
|
|
|
inhibitionsChanged(reply.value(), QStringList()); |
|
} |
|
}); |
|
|
|
//any info concerning lock screen/screensaver goes here |
|
} else if (name == QLatin1String("UserActivity")) { |
|
setData(QStringLiteral("UserActivity"), QStringLiteral("IdleTime"), KIdleTime::instance()->idleTime()); |
|
} else { |
|
qDebug() << "Data for '" << name << "' not found"; |
|
return false; |
|
} |
|
return true; |
|
} |
|
|
|
QString PowermanagementEngine::batteryType(const Solid::Battery* battery) const |
|
{ |
|
switch(battery->type()) { |
|
case Solid::Battery::PrimaryBattery: |
|
return QStringLiteral("Battery"); |
|
break; |
|
case Solid::Battery::UpsBattery: |
|
return QStringLiteral("Ups"); |
|
break; |
|
case Solid::Battery::MonitorBattery: |
|
return QStringLiteral("Monitor"); |
|
break; |
|
case Solid::Battery::MouseBattery: |
|
return QStringLiteral("Mouse"); |
|
break; |
|
case Solid::Battery::KeyboardBattery: |
|
return QStringLiteral("Keyboard"); |
|
break; |
|
case Solid::Battery::PdaBattery: |
|
return QStringLiteral("Pda"); |
|
break; |
|
case Solid::Battery::PhoneBattery: |
|
return QStringLiteral("Phone"); |
|
break; |
|
case Solid::Battery::GamingInputBattery: |
|
return QStringLiteral("GamingInput"); |
|
break; |
|
case Solid::Battery::BluetoothBattery: |
|
return QStringLiteral("Bluetooth"); |
|
break; |
|
default: |
|
return QStringLiteral("Unknown"); |
|
} |
|
|
|
return QStringLiteral("Unknown"); |
|
} |
|
|
|
bool PowermanagementEngine::updateSourceEvent(const QString &source) |
|
{ |
|
if (source == QLatin1String("UserActivity")) { |
|
setData(QStringLiteral("UserActivity"), QStringLiteral("IdleTime"), KIdleTime::instance()->idleTime()); |
|
return true; |
|
} |
|
return Plasma::DataEngine::updateSourceEvent(source); |
|
} |
|
|
|
Plasma::Service* PowermanagementEngine::serviceForSource(const QString &source) |
|
{ |
|
if (source == QLatin1String("PowerDevil")) { |
|
return new PowerManagementService(this); |
|
} |
|
|
|
return nullptr; |
|
} |
|
|
|
QString PowermanagementEngine::batteryStateToString(int newState) const |
|
{ |
|
QString state(QStringLiteral("Unknown")); |
|
if (newState == Solid::Battery::NoCharge) { |
|
state = QLatin1String("NoCharge"); |
|
} else if (newState == Solid::Battery::Charging) { |
|
state = QLatin1String("Charging"); |
|
} else if (newState == Solid::Battery::Discharging) { |
|
state = QLatin1String("Discharging"); |
|
} else if (newState == Solid::Battery::FullyCharged) { |
|
state = QLatin1String("FullyCharged"); |
|
} |
|
|
|
return state; |
|
} |
|
|
|
void PowermanagementEngine::updateBatteryChargeState(int newState, const QString& udi) |
|
{ |
|
const QString source = m_batterySources[udi]; |
|
setData(source, QStringLiteral("State"), batteryStateToString(newState)); |
|
updateOverallBattery(); |
|
} |
|
|
|
void PowermanagementEngine::updateBatteryPresentState(bool newState, const QString& udi) |
|
{ |
|
const QString source = m_batterySources[udi]; |
|
setData(source, QStringLiteral("Plugged in"), newState); // FIXME This needs to be renamed and Battery Monitor adjusted |
|
} |
|
|
|
void PowermanagementEngine::updateBatteryChargePercent(int newValue, const QString& udi) |
|
{ |
|
const QString source = m_batterySources[udi]; |
|
setData(source, QStringLiteral("Percent"), newValue); |
|
updateOverallBattery(); |
|
} |
|
|
|
void PowermanagementEngine::updateBatteryEnergy(double newValue, const QString &udi) |
|
{ |
|
const QString source = m_batterySources[udi]; |
|
setData(source, QStringLiteral("Energy"), newValue); |
|
} |
|
|
|
void PowermanagementEngine::updateBatteryPowerSupplyState(bool newState, const QString& udi) |
|
{ |
|
const QString source = m_batterySources[udi]; |
|
setData(source, QStringLiteral("Is Power Supply"), newState); |
|
} |
|
|
|
void PowermanagementEngine::updateBatteryNames() |
|
{ |
|
uint unnamedBatteries = 0; |
|
foreach (QString source, m_batterySources) { |
|
DataContainer *batteryDataContainer = containerForSource(source); |
|
if (batteryDataContainer) { |
|
const QString batteryVendor = batteryDataContainer->data()[QStringLiteral("Vendor")].toString(); |
|
const QString batteryProduct = batteryDataContainer->data()[QStringLiteral("Product")].toString(); |
|
|
|
// Don't show battery name for primary power supply batteries. They usually have cryptic serial number names. |
|
const bool showBatteryName = batteryDataContainer->data()[QStringLiteral("Type")].toString() != QLatin1String("Battery") || |
|
!batteryDataContainer->data()[QStringLiteral("Is Power Supply")].toBool(); |
|
|
|
if (!batteryProduct.isEmpty() && batteryProduct != QLatin1String("Unknown Battery") && showBatteryName) { |
|
if (!batteryVendor.isEmpty()) { |
|
setData(source, QStringLiteral("Pretty Name"), QString(batteryVendor + ' ' + batteryProduct)); |
|
} else { |
|
setData(source, QStringLiteral("Pretty Name"), batteryProduct); |
|
} |
|
} else { |
|
++unnamedBatteries; |
|
if (unnamedBatteries > 1) { |
|
setData(source, QStringLiteral("Pretty Name"), i18nc("Placeholder is the battery number", "Battery %1", unnamedBatteries)); |
|
} else { |
|
setData(source, QStringLiteral("Pretty Name"), i18n("Battery")); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
void PowermanagementEngine::updateOverallBattery() |
|
{ |
|
const QList<Solid::Device> listBattery = Solid::Device::listFromType(Solid::DeviceInterface::Battery); |
|
bool hasCumulative = false; |
|
|
|
double energy = 0; |
|
double totalEnergy = 0; |
|
bool allFullyCharged = true; |
|
bool charging = false; |
|
bool noCharge = false; |
|
double totalPercentage = 0; |
|
int count = 0; |
|
|
|
foreach (const Solid::Device &deviceBattery, listBattery) { |
|
const Solid::Battery* battery = deviceBattery.as<Solid::Battery>(); |
|
|
|
if (battery && battery->isPowerSupply()) { |
|
hasCumulative = true; |
|
|
|
energy += battery->energy(); |
|
totalEnergy += battery->energyFull(); |
|
totalPercentage += battery->chargePercent(); |
|
allFullyCharged = allFullyCharged && (battery->chargeState() == Solid::Battery::FullyCharged); |
|
charging = charging || (battery->chargeState() == Solid::Battery::Charging); |
|
noCharge = noCharge || (battery->chargeState() == Solid::Battery::NoCharge); |
|
++count; |
|
} |
|
} |
|
|
|
if (count == 1) { |
|
// Energy is sometimes way off causing us to show rubbish; this is a UPower issue |
|
// but anyway having just one battery and the tooltip showing strange readings |
|
// compared to the popup doesn't look polished. |
|
setData(QStringLiteral("Battery"), QStringLiteral("Percent"), totalPercentage); |
|
} else if (totalEnergy > 0) { |
|
setData(QStringLiteral("Battery"), QStringLiteral("Percent"), qRound(energy / totalEnergy * 100)); |
|
} else if (count > 0) { // UPS don't have energy, see Bug 348588 |
|
setData(QStringLiteral("Battery"), QStringLiteral("Percent"), qRound(totalPercentage / static_cast<qreal>(count))); |
|
} else { |
|
setData(QStringLiteral("Battery"), QStringLiteral("Percent"), 0); |
|
} |
|
|
|
if (hasCumulative) { |
|
if (allFullyCharged) { |
|
setData(QStringLiteral("Battery"), QStringLiteral("State"), "FullyCharged"); |
|
} else if (charging) { |
|
setData(QStringLiteral("Battery"), QStringLiteral("State"), "Charging"); |
|
} else if (noCharge) { |
|
setData(QStringLiteral("Battery"), QStringLiteral("State"), "NoCharge"); |
|
} else { |
|
setData(QStringLiteral("Battery"), QStringLiteral("State"), "Discharging"); |
|
} |
|
} else { |
|
setData(QStringLiteral("Battery"), QStringLiteral("State"), "Unknown"); |
|
} |
|
|
|
setData(QStringLiteral("Battery"), QStringLiteral("Has Cumulative"), hasCumulative); |
|
} |
|
|
|
void PowermanagementEngine::updateAcPlugState(bool onBattery) |
|
{ |
|
setData(QStringLiteral("AC Adapter"), QStringLiteral("Plugged in"), !onBattery); |
|
} |
|
|
|
void PowermanagementEngine::deviceRemoved(const QString& udi) |
|
{ |
|
if (m_batterySources.contains(udi)) { |
|
Solid::Device device(udi); |
|
Solid::Battery* battery = device.as<Solid::Battery>(); |
|
if (battery) |
|
battery->disconnect(); |
|
|
|
const QString source = m_batterySources[udi]; |
|
m_batterySources.remove(udi); |
|
removeSource(source); |
|
|
|
QStringList sourceNames(m_batterySources.values()); |
|
sourceNames.removeAll(source); |
|
setData(QStringLiteral("Battery"), QStringLiteral("Sources"), sourceNames); |
|
setData(QStringLiteral("Battery"), QStringLiteral("Has Battery"), !sourceNames.isEmpty()); |
|
|
|
updateOverallBattery(); |
|
} |
|
} |
|
|
|
void PowermanagementEngine::deviceAdded(const QString& udi) |
|
{ |
|
Solid::Device device(udi); |
|
if (device.isValid()) { |
|
const Solid::Battery* battery = device.as<Solid::Battery>(); |
|
|
|
if (battery) { |
|
int index = 0; |
|
QStringList sourceNames(m_batterySources.values()); |
|
while (sourceNames.contains(QStringLiteral("Battery%1").arg(index))) { |
|
index++; |
|
} |
|
|
|
const QString source = QStringLiteral("Battery%1").arg(index); |
|
sourceNames << source; |
|
m_batterySources[device.udi()] = source; |
|
|
|
connect(battery, &Solid::Battery::chargeStateChanged, this, |
|
&PowermanagementEngine::updateBatteryChargeState); |
|
connect(battery, &Solid::Battery::chargePercentChanged, this, |
|
&PowermanagementEngine::updateBatteryChargePercent); |
|
connect(battery, &Solid::Battery::energyChanged, |
|
this, &PowermanagementEngine::updateBatteryEnergy); |
|
connect(battery, &Solid::Battery::presentStateChanged, this, |
|
&PowermanagementEngine::updateBatteryPresentState); |
|
connect(battery, &Solid::Battery::powerSupplyStateChanged, this, |
|
&PowermanagementEngine::updateBatteryPowerSupplyState); |
|
|
|
// Set initial values |
|
updateBatteryChargeState(battery->chargeState(), device.udi()); |
|
updateBatteryChargePercent(battery->chargePercent(), device.udi()); |
|
updateBatteryEnergy(battery->energy(), device.udi()); |
|
updateBatteryPresentState(battery->isPresent(), device.udi()); |
|
updateBatteryPowerSupplyState(battery->isPowerSupply(), device.udi()); |
|
|
|
setData(source, QStringLiteral("Vendor"), device.vendor()); |
|
setData(source, QStringLiteral("Product"), device.product()); |
|
setData(source, QStringLiteral("Capacity"), battery->capacity()); |
|
setData(source, QStringLiteral("Type"), batteryType(battery)); |
|
|
|
setData(QStringLiteral("Battery"), QStringLiteral("Sources"), sourceNames); |
|
setData(QStringLiteral("Battery"), QStringLiteral("Has Battery"), !sourceNames.isEmpty()); |
|
|
|
updateBatteryNames(); |
|
updateOverallBattery(); |
|
} |
|
} |
|
} |
|
|
|
void PowermanagementEngine::batteryRemainingTimeChanged(qulonglong time) |
|
{ |
|
//qDebug() << "Remaining time 2:" << time; |
|
setData(QStringLiteral("Battery"), QStringLiteral("Remaining msec"), time); |
|
} |
|
|
|
void PowermanagementEngine::screenBrightnessChanged(int brightness) |
|
{ |
|
setData(QStringLiteral("PowerDevil"), QStringLiteral("Screen Brightness"), brightness); |
|
} |
|
|
|
void PowermanagementEngine::maximumScreenBrightnessChanged(int maximumBrightness) |
|
{ |
|
setData(QStringLiteral("PowerDevil"), QStringLiteral("Maximum Screen Brightness"), maximumBrightness); |
|
setData(QStringLiteral("PowerDevil"), QStringLiteral("Screen Brightness Available"), maximumBrightness > 0); |
|
} |
|
|
|
void PowermanagementEngine::keyboardBrightnessChanged(int brightness) |
|
{ |
|
setData(QStringLiteral("PowerDevil"), QStringLiteral("Keyboard Brightness"), brightness); |
|
} |
|
|
|
void PowermanagementEngine::maximumKeyboardBrightnessChanged(int maximumBrightness) |
|
{ |
|
setData(QStringLiteral("PowerDevil"), QStringLiteral("Maximum Keyboard Brightness"), maximumBrightness); |
|
setData(QStringLiteral("PowerDevil"), QStringLiteral("Keyboard Brightness Available"), maximumBrightness > 0); |
|
} |
|
|
|
void PowermanagementEngine::triggersLidActionChanged(bool triggers) |
|
{ |
|
setData(QStringLiteral("PowerDevil"), QStringLiteral("Triggers Lid Action"), triggers); |
|
} |
|
|
|
void PowermanagementEngine::inhibitionsChanged(const QList<InhibitionInfo> &added, const QStringList &removed) |
|
{ |
|
for (auto it = removed.constBegin(); it != removed.constEnd(); ++it) { |
|
removeData(QStringLiteral("Inhibitions"), (*it)); |
|
} |
|
|
|
for (auto it = added.constBegin(); it != added.constEnd(); ++it) { |
|
const QString &name = (*it).first; |
|
QString prettyName; |
|
QString icon; |
|
const QString &reason = (*it).second; |
|
|
|
populateApplicationData(name, &prettyName, &icon); |
|
|
|
setData(QStringLiteral("Inhibitions"), name, QVariantMap{ |
|
{QStringLiteral("Name"), prettyName}, |
|
{QStringLiteral("Icon"), icon}, |
|
{QStringLiteral("Reason"), reason} |
|
}); |
|
} |
|
} |
|
|
|
void PowermanagementEngine::populateApplicationData(const QString &name, QString *prettyName, QString *icon) |
|
{ |
|
if (m_applicationInfo.contains(name)) { |
|
const auto &info = m_applicationInfo.value(name); |
|
*prettyName = info.first; |
|
*icon = info.second; |
|
} else { |
|
KService::Ptr service = KService::serviceByStorageId(name + ".desktop"); |
|
if (service) { |
|
*prettyName = service->property(QStringLiteral("Name"), QVariant::Invalid).toString(); // cannot be null |
|
*icon = service->icon(); |
|
|
|
m_applicationInfo.insert(name, qMakePair(*prettyName, *icon)); |
|
} else { |
|
*prettyName = name; |
|
*icon = name.section(QLatin1Char('/'), -1).toLower(); |
|
} |
|
} |
|
} |
|
|
|
K_EXPORT_PLASMA_DATAENGINE_WITH_JSON(powermanagement, PowermanagementEngine, "plasma-dataengine-powermanagement.json") |
|
|
|
#include "powermanagementengine.moc"
|
|
|