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

/*
* 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"