|
|
|
|
@ -19,12 +19,22 @@
|
|
|
|
|
|
|
|
|
|
#include "powermanager.h"
|
|
|
|
|
|
|
|
|
|
#include <QDBusArgument>
|
|
|
|
|
#include <QDBusConnection>
|
|
|
|
|
#include <QDBusInterface>
|
|
|
|
|
#include <QDBusMessage>
|
|
|
|
|
#include <QDBusPendingCallWatcher>
|
|
|
|
|
#include <QDBusPendingReply>
|
|
|
|
|
#include <QDBusVariant>
|
|
|
|
|
#include <QSettings>
|
|
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
constexpr auto s_powerGroup = "Power";
|
|
|
|
|
|
|
|
|
|
const QString s_profilesService = QStringLiteral("org.freedesktop.UPower.PowerProfiles");
|
|
|
|
|
const QString s_profilesPath = QStringLiteral("/org/freedesktop/UPower/PowerProfiles");
|
|
|
|
|
const QString s_propertiesInterface = QStringLiteral("org.freedesktop.DBus.Properties");
|
|
|
|
|
|
|
|
|
|
int normalizedTimeout(int timeout)
|
|
|
|
|
{
|
|
|
|
|
return timeout < 0 ? -1 : qMax(1, timeout);
|
|
|
|
|
@ -67,12 +77,11 @@ void callPowerManager(const QString &method, const QVariant &value)
|
|
|
|
|
|
|
|
|
|
PowerManager::PowerManager(QObject *parent)
|
|
|
|
|
: QObject(parent)
|
|
|
|
|
, m_iface("com.cutefish.Services", "/com/cutefish/Services/Power",
|
|
|
|
|
"com.cutefish.Services.Power", QDBusConnection::sessionBus())
|
|
|
|
|
, m_mode(-1)
|
|
|
|
|
{
|
|
|
|
|
if (m_iface.isValid())
|
|
|
|
|
m_mode = m_iface.property("mode").toInt();
|
|
|
|
|
QDBusConnection::systemBus().connect(s_profilesService, s_profilesPath, s_propertiesInterface,
|
|
|
|
|
QStringLiteral("PropertiesChanged"), this,
|
|
|
|
|
SLOT(onProfilePropertiesChanged(QString, QVariantMap, QStringList)));
|
|
|
|
|
loadProfileProperties();
|
|
|
|
|
|
|
|
|
|
QSettings settings(QSettings::UserScope, "cutefish", "power");
|
|
|
|
|
m_batteryScreenOff = readTimeout(settings, QStringLiteral("BatteryScreenOff"),
|
|
|
|
|
@ -84,21 +93,101 @@ PowerManager::PowerManager(QObject *parent)
|
|
|
|
|
settings.endGroup();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int PowerManager::mode() const
|
|
|
|
|
QString PowerManager::profile() const
|
|
|
|
|
{
|
|
|
|
|
return m_mode;
|
|
|
|
|
return m_profile;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PowerManager::setMode(int mode)
|
|
|
|
|
void PowerManager::setProfile(const QString &profile)
|
|
|
|
|
{
|
|
|
|
|
if (m_mode == mode)
|
|
|
|
|
if (m_profile == profile || !m_profiles.contains(profile))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (m_iface.isValid())
|
|
|
|
|
m_iface.asyncCall(QStringLiteral("setMode"), mode);
|
|
|
|
|
QDBusMessage message = QDBusMessage::createMethodCall(s_profilesService, s_profilesPath,
|
|
|
|
|
s_propertiesInterface, QStringLiteral("Set"));
|
|
|
|
|
message << s_profilesService << QStringLiteral("ActiveProfile")
|
|
|
|
|
<< QVariant::fromValue(QDBusVariant(profile));
|
|
|
|
|
|
|
|
|
|
auto *watcher = new QDBusPendingCallWatcher(QDBusConnection::systemBus().asyncCall(message), this);
|
|
|
|
|
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
|
|
|
|
|
// A refused switch (e.g. by polkit) sends no PropertiesChanged; re-read the real profile.
|
|
|
|
|
if (watcher->isError())
|
|
|
|
|
loadProfileProperties();
|
|
|
|
|
|
|
|
|
|
watcher->deleteLater();
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
m_profile = profile;
|
|
|
|
|
emit profileChanged();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QStringList PowerManager::profiles() const
|
|
|
|
|
{
|
|
|
|
|
return m_profiles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_mode = mode;
|
|
|
|
|
emit modeChanged();
|
|
|
|
|
QString PowerManager::performanceDegraded() const
|
|
|
|
|
{
|
|
|
|
|
return m_performanceDegraded;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PowerManager::onProfilePropertiesChanged(const QString &interface, const QVariantMap &changed,
|
|
|
|
|
const QStringList &invalidated)
|
|
|
|
|
{
|
|
|
|
|
Q_UNUSED(invalidated)
|
|
|
|
|
|
|
|
|
|
if (interface == s_profilesService)
|
|
|
|
|
updateProfileProperties(changed);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PowerManager::loadProfileProperties()
|
|
|
|
|
{
|
|
|
|
|
QDBusMessage message = QDBusMessage::createMethodCall(s_profilesService, s_profilesPath,
|
|
|
|
|
s_propertiesInterface, QStringLiteral("GetAll"));
|
|
|
|
|
message << s_profilesService;
|
|
|
|
|
|
|
|
|
|
auto *watcher = new QDBusPendingCallWatcher(QDBusConnection::systemBus().asyncCall(message), this);
|
|
|
|
|
connect(watcher, &QDBusPendingCallWatcher::finished, this, [this](QDBusPendingCallWatcher *watcher) {
|
|
|
|
|
QDBusPendingReply<QVariantMap> reply = *watcher;
|
|
|
|
|
if (!reply.isError())
|
|
|
|
|
updateProfileProperties(reply.value());
|
|
|
|
|
|
|
|
|
|
watcher->deleteLater();
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void PowerManager::updateProfileProperties(const QVariantMap &properties)
|
|
|
|
|
{
|
|
|
|
|
auto it = properties.constFind(QStringLiteral("Profiles"));
|
|
|
|
|
if (it != properties.constEnd()) {
|
|
|
|
|
QStringList profiles;
|
|
|
|
|
const QDBusArgument argument = it->value<QDBusArgument>();
|
|
|
|
|
|
|
|
|
|
argument.beginArray();
|
|
|
|
|
while (!argument.atEnd()) {
|
|
|
|
|
QVariantMap profile;
|
|
|
|
|
argument >> profile;
|
|
|
|
|
profiles.append(profile.value(QStringLiteral("Profile")).toString());
|
|
|
|
|
}
|
|
|
|
|
argument.endArray();
|
|
|
|
|
|
|
|
|
|
if (m_profiles != profiles) {
|
|
|
|
|
m_profiles = profiles;
|
|
|
|
|
emit profilesChanged();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it = properties.constFind(QStringLiteral("ActiveProfile"));
|
|
|
|
|
if (it != properties.constEnd() && m_profile != it->toString()) {
|
|
|
|
|
m_profile = it->toString();
|
|
|
|
|
emit profileChanged();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
it = properties.constFind(QStringLiteral("PerformanceDegraded"));
|
|
|
|
|
if (it != properties.constEnd() && m_performanceDegraded != it->toString()) {
|
|
|
|
|
m_performanceDegraded = it->toString();
|
|
|
|
|
emit performanceDegradedChanged();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int PowerManager::batteryScreenOff() const
|
|
|
|
|
|