11 #include <QDBusUnixFileDescriptor>
13 #define LOC QString("PowerDBus: ")
15 #define FREE_SERVICE (QString("org.freedesktop."))
16 #define FREE_PATH (QString("/org/freedesktop/"))
17 #define UPOWER (QString("UPower"))
18 #define LOGIN1 (QString("login1"))
19 #define UPOWER_SERVICE (FREE_SERVICE + UPOWER)
20 #define UPOWER_PATH (FREE_PATH + UPOWER)
21 #define UPOWER_INTERFACE (UPOWER_SERVICE)
22 #define LOGIN1_SERVICE (FREE_SERVICE + LOGIN1)
23 #define LOGIN1_PATH (FREE_PATH + LOGIN1)
24 #define LOGIN1_INTERFACE (LOGIN1_SERVICE + QString(".Manager"))
48 QMutexLocker locker(&
s_lock);
49 static bool s_available =
false;
50 static bool s_checked =
false;
54 auto* upower =
new QDBusInterface(
56 auto* login1 =
new QDBusInterface(
58 s_available = upower->isValid() || login1->isValid();
77 LOG(VB_GENERAL, LOG_INFO,
LOC +
"Closing interfaces");
107 LOG(VB_GENERAL, LOG_ERR,
LOC +
"No UPower interface. Unable to monitor battery state");
109 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"No login1 interface. Cannot change system power state");
120 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Failed to listen for sleep events");
125 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Failed to listen for shutdown events");
132 QDBusReply<QList<QDBusObjectPath> > response =
134 if (response.isValid())
136 QList devices = response.value();
137 for (
const auto& device : std::as_const(devices))
143 LOG(VB_GENERAL, LOG_ERR,
"Failed to register for Changed");
149 LOG(VB_GENERAL, LOG_ERR,
"Failed to register for DeviceChanged");
155 LOG(VB_GENERAL, LOG_ERR,
"Failed to register for DeviceAdded");
161 LOG(VB_GENERAL, LOG_ERR,
"Failed to register for DeviceRemoved");
229 if (property.isValid() && property.toBool())
235 if (property.isValid() && property.toBool())
255 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Trying to delay system %1 for %2 seconds")
271 QMutexLocker locker(&
s_lock);
303 auto time = nowAsDuration<std::chrono::milliseconds>();
306 std::chrono::milliseconds millisecs = time + Delay;
314 QDBusReply<void> reply =
316 static_cast<qint64
>(millisecs.count()));
318 if (reply.isValid() && !reply.error().isValid())
322 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"%1 scheduled via logind")
328 LOG(VB_GENERAL, LOG_DEBUG,
LOC +
329 QString(
"Failed to schedule %1 - falling back to default behaviour")
331 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"Error %1 Message %2")
332 .arg(reply.error().name(), reply.error().message()));
350 QMutexLocker locker(&
s_lock);
359 QMutexLocker locker(&
s_lock);
367 QMutexLocker locker(&
s_lock);
372 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Added UPower.Device '%1'").arg(
Device.path()));
379 QMutexLocker locker(&
s_lock);
384 LOG(VB_GENERAL, LOG_INFO, QString(
"Removed UPower.Device '%1'").arg(
Device.path()));
396 QMutexLocker locker(&
s_lock);
411 QDBusReply<QString> cansuspend =
m_logindInterface->call(QLatin1String(
"CanSuspend"));
412 if (cansuspend.isValid() && cansuspend.value() ==
"yes")
414 QDBusReply<QString> canshutdown =
m_logindInterface->call(QLatin1String(
"CanPowerOff"));
415 if (canshutdown.isValid() && canshutdown.value() ==
"yes")
417 QDBusReply<QString> canrestart =
m_logindInterface->call(QLatin1String(
"CanReboot"));
418 if (canrestart.isValid() && canrestart.value() ==
"yes")
420 QDBusReply<QString> canhibernate =
m_logindInterface->call(QLatin1String(
"CanHibernate"));
421 if (canhibernate.isValid() && canhibernate.value() ==
"yes")
423 QDBusReply<QString> canhybrid =
m_logindInterface->call(QLatin1String(
"CanHybridSleep"));
424 if (canhybrid.isValid() && canhybrid.value() ==
"yes")
430 auto value = std::chrono::microseconds(delay.toUInt());
432 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"Max inhibit delay: %1seconds")
444 QMutexLocker locker(&
s_lock);
452 if (level >= 0 && level <= 100)
455 total +=
static_cast<qreal
>(level);
460 newlevel = lround(total / count);
466 if (acpower.isValid() && acpower.toBool())
477 if (interface.isValid())
479 QVariant battery = interface.property(
"IsRechargeable");
480 if (battery.isValid() && battery.toBool())
482 QVariant percent = interface.property(
"Percentage");
483 if (percent.isValid())
485 int result =
static_cast<int>(lroundf(percent.toFloat() * 100.0F));
486 if (result >= 0 && result <= 100)
495 QVariant
type = interface.property(
"Type");
498 QString typestr =
type.toString();
499 if (typestr ==
"Line Power")
501 if (typestr ==
"Ups")
522 QMutexLocker locker(&
s_lock);
526 LOG(VB_GENERAL, LOG_WARNING,
LOC +
"Already hold delay lock");
535 LOG(VB_GENERAL, LOG_ERR,
LOC +
"Unknown delay requests");
539 QDBusReply<QDBusUnixFileDescriptor> reply =
541 QLatin1String(
"MythTV"), QLatin1String(
""), QLatin1String(
"delay"));
542 if (!reply.isValid())
544 LOG(VB_GENERAL, LOG_INFO,
LOC + QString(
"Failed to delay %1: %2")
545 .arg(
types.join(
","), reply.error().message()));
561 QMutexLocker locker(&
s_lock);
568 LOG(VB_GENERAL, LOG_DEBUG,
LOC + QString(
"Releasing delay FD: %1").arg(
m_lockHandle));