2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
9 #include "UPowerSyscall.h"
11 #include "utils/log.h"
13 CUPowerSource::CUPowerSource(const char *powerSource
)
15 if(powerSource
== NULL
)
18 m_powerSource
= powerSource
;
20 CVariant properties
= CDBusUtil::GetAll("org.freedesktop.UPower", m_powerSource
.c_str(), "org.freedesktop.UPower.Device");
21 m_isRechargeable
= properties
["IsRechargeable"].asBoolean();
25 CUPowerSource::~CUPowerSource() = default;
27 void CUPowerSource::Update()
29 CVariant properties
= CDBusUtil::GetAll("org.freedesktop.UPower", m_powerSource
.c_str(), "org.freedesktop.UPower.Device");
30 m_batteryLevel
= properties
["Percentage"].asDouble();
33 bool CUPowerSource::IsRechargeable()
35 return m_isRechargeable
;
38 double CUPowerSource::BatteryLevel()
40 return m_batteryLevel
;
43 CUPowerSyscall::CUPowerSyscall()
45 CLog::Log(LOGINFO
, "Selected UPower as PowerSyscall");
49 //! @todo do not use dbus_connection_pop_message() that requires the use of a
50 //! private connection
51 if (m_connection
.Connect(DBUS_BUS_SYSTEM
, true))
53 dbus_connection_set_exit_on_disconnect(m_connection
, false);
56 dbus_bus_add_match(m_connection
, "type='signal',interface='org.freedesktop.UPower'", error
);
57 dbus_connection_flush(m_connection
);
61 error
.Log("UPower: Failed to attach to signal");
62 m_connection
.Destroy();
66 m_CanPowerdown
= false;
71 EnumeratePowerSources();
74 bool CUPowerSyscall::Powerdown()
79 bool CUPowerSyscall::Suspend()
81 // UPower 0.9.1 does not signal sleeping unless you tell that its about to sleep...
82 CDBusMessage
aboutToSleepMessage("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "AboutToSleep");
83 aboutToSleepMessage
.SendAsyncSystem();
85 CDBusMessage
message("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "Suspend");
86 return message
.SendAsyncSystem();
89 bool CUPowerSyscall::Hibernate()
91 // UPower 0.9.1 does not signal sleeping unless you tell that its about to sleep...
92 CDBusMessage
aboutToSleepMessage("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "AboutToSleep");
93 aboutToSleepMessage
.SendAsyncSystem();
95 CDBusMessage
message("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "Hibernate");
96 return message
.SendAsyncSystem();
99 bool CUPowerSyscall::Reboot()
104 bool CUPowerSyscall::CanPowerdown()
106 return m_CanPowerdown
;
109 bool CUPowerSyscall::CanSuspend()
114 bool CUPowerSyscall::CanHibernate()
116 return m_CanHibernate
;
119 bool CUPowerSyscall::CanReboot()
124 int CUPowerSyscall::BatteryLevel()
126 unsigned int nBatteryCount
= 0;
127 double subCapacity
= 0;
128 double batteryLevel
= 0;
130 for (auto& itr
: m_powerSources
)
133 if (itr
.IsRechargeable())
136 subCapacity
+= itr
.BatteryLevel();
141 batteryLevel
= subCapacity
/ (double)nBatteryCount
;
143 return (int) batteryLevel
;
146 void CUPowerSyscall::EnumeratePowerSources()
148 CDBusMessage
message("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "EnumerateDevices");
149 DBusMessage
*reply
= message
.SendSystem();
152 char** source
= NULL
;
155 if (dbus_message_get_args (reply
, NULL
, DBUS_TYPE_ARRAY
, DBUS_TYPE_OBJECT_PATH
, &source
, &length
, DBUS_TYPE_INVALID
))
157 for (int i
= 0; i
< length
; i
++)
159 m_powerSources
.emplace_back(source
[i
]);
162 dbus_free_string_array(source
);
167 bool CUPowerSyscall::HasUPower()
169 return CDBusUtil::TryMethodCall(DBUS_BUS_SYSTEM
, "org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "EnumerateDevices");
172 bool CUPowerSyscall::PumpPowerEvents(IPowerEventsCallback
*callback
)
178 dbus_connection_read_write(m_connection
, 0);
179 DBusMessagePtr
msg(dbus_connection_pop_message(m_connection
));
184 if (dbus_message_is_signal(msg
.get(), "org.freedesktop.UPower", "Sleeping"))
186 else if (dbus_message_is_signal(msg
.get(), "org.freedesktop.UPower", "Resuming"))
188 else if (dbus_message_is_signal(msg
.get(), "org.freedesktop.UPower", "Changed"))
190 bool lowBattery
= m_lowBattery
;
191 UpdateCapabilities();
192 if (m_lowBattery
&& !lowBattery
)
193 callback
->OnLowBattery();
196 CLog::Log(LOGDEBUG
, "UPower: Received an unknown signal {}",
197 dbus_message_get_member(msg
.get()));
203 void CUPowerSyscall::UpdateCapabilities()
205 m_CanSuspend
= CDBusUtil::GetVariant("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "CanSuspend").asBoolean(false);
206 m_CanHibernate
= CDBusUtil::GetVariant("org.freedesktop.UPower", "/org/freedesktop/UPower", "org.freedesktop.UPower", "CanHibernate").asBoolean(false);