2 * Copyright (C) 2012 Denis Yantarev
3 * Copyright (C) 2005-2013 Team XBMC
6 * This Program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2, or (at your option)
11 * This Program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with XBMC; see the file COPYING. If not, write to
18 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
19 * http://www.gnu.org/copyleft/gpl.html
24 #include "SystemdUPowerSyscall.h"
25 #include "utils/log.h"
28 #include "Application.h"
30 // logind DBus interface specification:
31 // http://www.freedesktop.org/wiki/Software/systemd/logind
33 #define LOGIND_DEST "org.freedesktop.login1"
34 #define LOGIND_PATH "/org/freedesktop/login1"
35 #define LOGIND_IFACE "org.freedesktop.login1.Manager"
37 CSystemdUPowerSyscall::CSystemdUPowerSyscall()
42 bool CSystemdUPowerSyscall::Powerdown()
44 return SystemdSetPowerState("PowerOff");
47 bool CSystemdUPowerSyscall::Reboot()
49 return SystemdSetPowerState("Reboot");
52 bool CSystemdUPowerSyscall::Suspend()
54 return SystemdSetPowerState("Suspend");
57 bool CSystemdUPowerSyscall::Hibernate()
59 return SystemdSetPowerState("Hibernate");
62 void CSystemdUPowerSyscall::UpdateCapabilities()
64 m_CanPowerdown = SystemdCheckCapability("CanPowerOff");
65 m_CanReboot = SystemdCheckCapability("CanReboot");
66 m_CanHibernate = SystemdCheckCapability("CanHibernate");
67 m_CanSuspend = SystemdCheckCapability("CanSuspend");
70 bool CSystemdUPowerSyscall::HasSystemdAndUPower()
74 bool hasSystemd = false;
76 dbus_error_init(&error);
77 con = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
79 if(dbus_error_is_set(&error))
81 CLog::Log(LOGDEBUG, "SystemdUPowerSyscall: %s: %s", error.name, error.message);
82 dbus_error_free(&error);
86 CDBusMessage message(LOGIND_DEST, LOGIND_PATH, LOGIND_IFACE, "CanPowerOff");
87 message.Send(con, &error);
89 if(!dbus_error_is_set(&error))
92 CLog::Log(LOGDEBUG, "Systemd error: %s: %s", error.name, error.message);
94 dbus_error_free(&error);
96 return HasUPower() && hasSystemd;
99 bool CSystemdUPowerSyscall::SystemdSetPowerState(const char *state)
102 CDBusMessage message(LOGIND_DEST, LOGIND_PATH, LOGIND_IFACE, state);
103 // The user_interaction boolean parameters can be used to control
104 // wether PolicyKit should interactively ask the user for authentication
105 // credentials if it needs to.
106 message.AppendArgument(arg);
107 return message.SendSystem() != NULL;
110 bool CSystemdUPowerSyscall::SystemdCheckCapability(const char *capability)
114 CDBusMessage message(LOGIND_DEST, LOGIND_PATH, LOGIND_IFACE, capability);
115 DBusMessage *reply = message.SendSystem();
116 if(reply && dbus_message_get_args(reply, NULL, DBUS_TYPE_STRING, &arg, DBUS_TYPE_INVALID))
118 // Returns one of "yes", "no" or "challenge". If "challenge" is
119 // returned the operation is available, but only after authorization.
120 result = (strcmp(arg, "yes") == 0);