summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Koegel <eric.koegel@gmail.com>2014-10-09 19:30:59 +0300
committerEric Koegel <eric.koegel@gmail.com>2014-10-09 19:30:59 +0300
commitd79c28572185335bd7c0d4f8bbce63d3904d1d6c (patch)
treeb2c54f1d09b2fdfbb1f2b1ca2c8276d2da25af8e
parent98d14ab7faa49c080c9b230653ae6266e03094ab (diff)
downloadConsoleKit2-d79c28572185335bd7c0d4f8bbce63d3904d1d6c.tar.gz
Start adding the Suspend/Hibernate DBUS API
The initial work in progress to add in suspend/hibernate and the inhibit locks.
-rw-r--r--data/org.freedesktop.consolekit.policy35
-rw-r--r--src/ck-log-event.h2
-rw-r--r--src/ck-manager.c218
-rw-r--r--src/ck-manager.h10
-rw-r--r--src/org.freedesktop.ConsoleKit.Manager.xml28
5 files changed, 293 insertions, 0 deletions
diff --git a/data/org.freedesktop.consolekit.policy b/data/org.freedesktop.consolekit.policy
index a709b39..76a6cc8 100644
--- a/data/org.freedesktop.consolekit.policy
+++ b/data/org.freedesktop.consolekit.policy
@@ -45,4 +45,39 @@ Policy definitions for ConsoleKit
</defaults>
</action>
+ <action id="org.freedesktop.consolekit.system.suspend">
+ <description>Suspend the system</description>
+ <message>System policy prevents suspending the system</message>
+ <defaults>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+
+ <action id="org.freedesktop.consolekit.system.suspend-multiple-users">
+ <description>Suspend the system when multiple users are logged in</description>
+ <message>System policy prevents suspending the system when other users are logged in</message>
+ <defaults>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin_keep</allow_active>
+ </defaults>
+ </action>
+
+ <action id="org.freedesktop.consolekit.system.hibernate">
+ <description>Hibernate the system</description>
+ <message>System policy prevents hibernating the system</message>
+ <defaults>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ </action>
+
+ <action id="org.freedesktop.consolekit.system.hibernate-multiple-users">
+ <description>Hibernate the system when multiple users are logged in</description>
+ <message>System policy prevents hibernating the system when other users are logged in</message>
+ <defaults>
+ <allow_inactive>no</allow_inactive>
+ <allow_active>auth_admin_keep</allow_active>
+ </defaults>
+ </action>
</policyconfig>
diff --git a/src/ck-log-event.h b/src/ck-log-event.h
index 65571f0..dd307f7 100644
--- a/src/ck-log-event.h
+++ b/src/ck-log-event.h
@@ -33,6 +33,8 @@ typedef enum
CK_LOG_EVENT_SYSTEM_START,
CK_LOG_EVENT_SYSTEM_STOP,
CK_LOG_EVENT_SYSTEM_RESTART,
+ CK_LOG_EVENT_SYSTEM_SUSPEND,
+ CK_LOG_EVENT_SYSTEM_HIBERNATE,
CK_LOG_EVENT_SYSTEM_RUNLEVEL_CHANGED,
CK_LOG_EVENT_SEAT_ADDED,
CK_LOG_EVENT_SEAT_REMOVED,
diff --git a/src/ck-manager.c b/src/ck-manager.c
index c6713b8..eff383c 100644
--- a/src/ck-manager.c
+++ b/src/ck-manager.c
@@ -501,6 +501,50 @@ log_system_restart_event (CkManager *manager)
}
static void
+log_system_suspend_event (CkManager *manager)
+{
+ CkLogEvent event;
+ gboolean res;
+ GError *error;
+
+ memset (&event, 0, sizeof (CkLogEvent));
+
+ event.type = CK_LOG_EVENT_SYSTEM_SUSPEND;
+ g_get_current_time (&event.timestamp);
+
+ error = NULL;
+ res = ck_event_logger_queue_event (manager->priv->logger, &event, &error);
+ if (! res) {
+ g_debug ("Unable to log event: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* FIXME: in this case we should block and wait for log to flush */
+}
+
+static void
+log_system_hibernate_event (CkManager *manager)
+{
+ CkLogEvent event;
+ gboolean res;
+ GError *error;
+
+ memset (&event, 0, sizeof (CkLogEvent));
+
+ event.type = CK_LOG_EVENT_SYSTEM_HIBERNATE;
+ g_get_current_time (&event.timestamp);
+
+ error = NULL;
+ res = ck_event_logger_queue_event (manager->priv->logger, &event, &error);
+ if (! res) {
+ g_debug ("Unable to log event: %s", error->message);
+ g_error_free (error);
+ }
+
+ /* FIXME: in this case we should block and wait for log to flush */
+}
+
+static void
log_seat_session_added_event (CkManager *manager,
CkSeat *seat,
const char *ssid)
@@ -1247,6 +1291,180 @@ ck_manager_can_stop (CkManager *manager,
}
static void
+do_suspend (CkManager *manager,
+ DBusGMethodInvocation *context)
+{
+ GError *error;
+ gboolean res;
+
+ g_debug ("ConsoleKit preforming Suspend");
+
+ log_system_suspend_event (manager);
+
+ error = NULL;
+ res = g_spawn_command_line_async (PREFIX "/lib/ConsoleKit/scripts/ck-system-suspend",
+ &error);
+ if (! res) {
+ GError *new_error;
+
+ g_warning ("Unable to suspend system: %s", error->message);
+
+ new_error = g_error_new (CK_MANAGER_ERROR,
+ CK_MANAGER_ERROR_GENERAL,
+ "Unable to suspend system: %s", error->message);
+ dbus_g_method_return_error (context, new_error);
+ g_error_free (new_error);
+
+ g_error_free (error);
+ } else {
+ dbus_g_method_return (context);
+ }
+}
+
+/*
+ Example:
+ dbus-send --system --dest=org.freedesktop.ConsoleKit \
+ --type=method_call --print-reply --reply-timeout=2000 \
+ /org/freedesktop/ConsoleKit/Manager \
+ org.freedesktop.ConsoleKit.Manager.Suspend
+*/
+gboolean
+ck_manager_suspend (CkManager *manager,
+ DBusGMethodInvocation *context)
+{
+ const char *action;
+
+ if (get_system_num_users (manager) > 1) {
+ action = "org.freedesktop.consolekit.system.suspend-multiple-users";
+ } else {
+ action = "org.freedesktop.consolekit.system.suspend";
+ }
+
+ g_debug ("ConsoleKit Suspend: %s", action);
+
+#if defined HAVE_POLKIT
+ check_polkit_permissions (manager, context, action, do_suspend);
+#elif defined ENABLE_RBAC_SHUTDOWN
+ check_rbac_permissions (manager, context, RBAC_SHUTDOWN_KEY, do_suspend);
+#else
+ g_warning ("Compiled without PolicyKit or RBAC support!");
+ do_suspend(manager, context);
+#endif
+
+ return TRUE;
+}
+
+gboolean
+ck_manager_can_suspend (CkManager *manager,
+ DBusGMethodInvocation *context)
+
+{
+ const char *action;
+
+ action = "org.freedesktop.consolekit.system.suspend";
+
+#if defined HAVE_POLKIT
+ get_polkit_permissions (manager, action, context);
+#elif defined ENABLE_RBAC_SHUTDOWN
+ if (check_rbac_permissions (manager, context, RBAC_SHUTDOWN_KEY,
+ NULL)) {
+ dbus_g_method_return (context, TRUE);
+ } else {
+ dbus_g_method_return (context, FALSE);
+ }
+#endif
+
+ return TRUE;
+}
+
+static void
+do_hibernate (CkManager *manager,
+ DBusGMethodInvocation *context)
+{
+ GError *error;
+ gboolean res;
+
+ g_debug ("ConsoleKit preforming Hibernate");
+
+ log_system_hibernate_event (manager);
+
+ error = NULL;
+ res = g_spawn_command_line_async (PREFIX "/lib/ConsoleKit/scripts/ck-system-hibernate",
+ &error);
+ if (! res) {
+ GError *new_error;
+
+ g_warning ("Unable to hibernate system: %s", error->message);
+
+ new_error = g_error_new (CK_MANAGER_ERROR,
+ CK_MANAGER_ERROR_GENERAL,
+ "Unable to hibernate system: %s", error->message);
+ dbus_g_method_return_error (context, new_error);
+ g_error_free (new_error);
+
+ g_error_free (error);
+ } else {
+ dbus_g_method_return (context);
+ }
+}
+
+/*
+ Example:
+ dbus-send --system --dest=org.freedesktop.ConsoleKit \
+ --type=method_call --print-reply --reply-timeout=2000 \
+ /org/freedesktop/ConsoleKit/Manager \
+ org.freedesktop.ConsoleKit.Manager.Hibernate
+*/
+gboolean
+ck_manager_hibernate (CkManager *manager,
+ DBusGMethodInvocation *context)
+{
+ const char *action;
+
+ if (get_system_num_users (manager) > 1) {
+ action = "org.freedesktop.consolekit.system.hibernate-multiple-users";
+ } else {
+ action = "org.freedesktop.consolekit.system.hibernate";
+ }
+
+ g_debug ("ConsoleKit Hibernate: %s", action);
+
+#if defined HAVE_POLKIT
+ check_polkit_permissions (manager, context, action, do_hibernate);
+#elif defined ENABLE_RBAC_SHUTDOWN
+ check_rbac_permissions (manager, context, RBAC_SHUTDOWN_KEY, do_hibernate);
+#else
+ g_warning ("Compiled without PolicyKit or RBAC support!");
+ do_hibernate(manager, context);
+#endif
+
+ return TRUE;
+}
+
+gboolean
+ck_manager_can_hibernate (CkManager *manager,
+ DBusGMethodInvocation *context)
+
+{
+ const char *action;
+
+ action = "org.freedesktop.consolekit.system.hibernate";
+
+#if defined HAVE_POLKIT
+ get_polkit_permissions (manager, action, context);
+#elif defined ENABLE_RBAC_SHUTDOWN
+ if (check_rbac_permissions (manager, context, RBAC_SHUTDOWN_KEY,
+ NULL)) {
+ dbus_g_method_return (context, TRUE);
+ } else {
+ dbus_g_method_return (context, FALSE);
+ }
+#endif
+
+ return TRUE;
+}
+
+static void
on_seat_active_session_changed_full (CkSeat *seat,
CkSession *old_session,
CkSession *session,
diff --git a/src/ck-manager.h b/src/ck-manager.h
index 4bd56e8..bfa2c01 100644
--- a/src/ck-manager.h
+++ b/src/ck-manager.h
@@ -83,10 +83,20 @@ gboolean ck_manager_stop (CkManager
gboolean ck_manager_restart (CkManager *manager,
DBusGMethodInvocation *context);
+gboolean ck_manager_suspend (CkManager *manager,
+ DBusGMethodInvocation *context);
+
+gboolean ck_manager_hibernate (CkManager *manager,
+ DBusGMethodInvocation *context);
+
gboolean ck_manager_can_stop (CkManager *manager,
DBusGMethodInvocation *context);
gboolean ck_manager_can_restart (CkManager *manager,
DBusGMethodInvocation *context);
+gboolean ck_manager_can_suspend (CkManager *manager,
+ DBusGMethodInvocation *context);
+gboolean ck_manager_can_hibernate (CkManager *manager,
+ DBusGMethodInvocation *context);
/* Authoritative properties */
gboolean ck_manager_open_session (CkManager *manager,
DBusGMethodInvocation *context);
diff --git a/src/org.freedesktop.ConsoleKit.Manager.xml b/src/org.freedesktop.ConsoleKit.Manager.xml
index f903b55..ae6a90c 100644
--- a/src/org.freedesktop.ConsoleKit.Manager.xml
+++ b/src/org.freedesktop.ConsoleKit.Manager.xml
@@ -32,6 +32,34 @@
<arg name="can_stop" type="b" direction="out"/>
</method>
+ <method name="Suspend">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>This method initiates a request to suspend the computer system.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </method>
+
+ <method name="CanSuspend">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg name="can_suspend" type="b" direction="out"/>
+ </method>
+
+ <method name="Hibernate">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <doc:doc>
+ <doc:description>
+ <doc:para>This method initiates a request to hibernate the computer system.</doc:para>
+ </doc:description>
+ </doc:doc>
+ </method>
+
+ <method name="CanHibernate">
+ <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+ <arg name="can_hibernate" type="b" direction="out"/>
+ </method>
+
<method name="OpenSession">
<annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
<arg name="cookie" direction="out" type="s">