[cosmetics] update date in GPL header
[vuplus_xbmc] / xbmc / powermanagement / linux / SystemdUPowerSyscall.cpp
1 /*
2  *      Copyright (C) 2012 Denis Yantarev
3  *      Copyright (C) 2005-2013 Team XBMC
4  *      http://www.xbmc.org
5  *
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)
9  *  any later version.
10  *
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.
15  *
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
20  *
21  */
22
23 #include "system.h"
24 #include "SystemdUPowerSyscall.h"
25 #include "utils/log.h"
26
27 #ifdef HAS_DBUS
28 #include "Application.h"
29
30 // logind DBus interface specification:
31 // http://www.freedesktop.org/wiki/Software/systemd/logind
32
33 #define LOGIND_DEST  "org.freedesktop.login1"
34 #define LOGIND_PATH  "/org/freedesktop/login1"
35 #define LOGIND_IFACE "org.freedesktop.login1.Manager"
36
37 CSystemdUPowerSyscall::CSystemdUPowerSyscall()
38 {
39   UpdateCapabilities();
40 }
41
42 bool CSystemdUPowerSyscall::Powerdown()
43 {
44   return SystemdSetPowerState("PowerOff");
45 }
46
47 bool CSystemdUPowerSyscall::Reboot()
48 {
49   return SystemdSetPowerState("Reboot");
50 }
51
52 bool CSystemdUPowerSyscall::Suspend()
53 {
54   return SystemdSetPowerState("Suspend");
55 }
56
57 bool CSystemdUPowerSyscall::Hibernate()
58 {
59   return SystemdSetPowerState("Hibernate");
60 }
61
62 void CSystemdUPowerSyscall::UpdateCapabilities()
63 {
64   m_CanPowerdown = SystemdCheckCapability("CanPowerOff");
65   m_CanReboot    = SystemdCheckCapability("CanReboot");
66   m_CanHibernate = SystemdCheckCapability("CanHibernate");
67   m_CanSuspend   = SystemdCheckCapability("CanSuspend");
68 }
69
70 bool CSystemdUPowerSyscall::HasSystemdAndUPower()
71 {
72   DBusConnection *con;
73   DBusError error;
74   bool hasSystemd = false;
75
76   dbus_error_init(&error);
77   con = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
78
79   if(dbus_error_is_set(&error))
80   {
81     CLog::Log(LOGDEBUG, "SystemdUPowerSyscall: %s: %s", error.name, error.message);
82     dbus_error_free(&error);
83     return false;
84   }
85
86   CDBusMessage message(LOGIND_DEST, LOGIND_PATH, LOGIND_IFACE, "CanPowerOff");
87   message.Send(con, &error);
88
89   if(!dbus_error_is_set(&error))
90     hasSystemd = true;
91   else
92     CLog::Log(LOGDEBUG, "Systemd error: %s: %s", error.name, error.message);
93
94   dbus_error_free(&error);
95
96   return HasUPower() && hasSystemd;
97 }
98
99 bool CSystemdUPowerSyscall::SystemdSetPowerState(const char *state)
100 {
101   bool arg = false;
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;
108 }
109
110 bool CSystemdUPowerSyscall::SystemdCheckCapability(const char *capability)
111 {
112   bool result = false;
113   char *arg;
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))
117   {
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);
121   }
122   return result;
123 }
124
125 #endif