From b65cb6f48bfa768acafdb7b6dcee32f600925688 Mon Sep 17 00:00:00 2001 From: Eric Koegel Date: Mon, 13 Oct 2014 10:00:22 +0300 Subject: [PATCH] More Suspend DBUS API work We need a Can/Auth split for suspend/hibernate because the user may be authorized but the system is unable to perform those actions. Additionally start working the inhibit calls. We also need to actually add the suspend/hibernate tools. --- configure.ac | 3 +- src/ck-manager.c | 46 ++++++++++- src/ck-manager.h | 10 +++ src/ck-sysdeps-freebsd.c | 67 +++++++++++++++- src/ck-sysdeps-gnu.c | 14 ++++ src/ck-sysdeps-linux.c | 37 +++++++++ src/ck-sysdeps-openbsd.c | 12 +++ src/ck-sysdeps-solaris.c | 14 ++++ src/ck-sysdeps.h | 3 + src/org.freedesktop.ConsoleKit.Manager.xml | 122 +++++++++++++++++++++++++++++ 10 files changed, 322 insertions(+), 6 deletions(-) diff --git a/src/ck-manager.c b/src/ck-manager.c index eff383c..6d80304 100644 --- a/src/ck-manager.c +++ b/src/ck-manager.c @@ -1355,8 +1355,8 @@ ck_manager_suspend (CkManager *manager, } gboolean -ck_manager_can_suspend (CkManager *manager, - DBusGMethodInvocation *context) +ck_manager_auth_suspend (CkManager *manager, + DBusGMethodInvocation *context) { const char *action; @@ -1377,6 +1377,20 @@ ck_manager_can_suspend (CkManager *manager, return TRUE; } +gboolean +ck_manager_can_suspend (CkManager *manager, + DBusGMethodInvocation *context) + +{ + if (ck_system_can_suspend ()) { + dbus_g_method_return (context, TRUE); + } else { + dbus_g_method_return (context, FALSE); + } + + return TRUE; +} + static void do_hibernate (CkManager *manager, DBusGMethodInvocation *context, @@ -1442,8 +1456,8 @@ ck_manager_hibernate (CkManager *manager, } gboolean -ck_manager_can_hibernate (CkManager *manager, - DBusGMethodInvocation *context) +ck_manager_auth_hibernate (CkManager *manager, + DBusGMethodInvocation *context) { const char *action; @@ -1464,6 +1478,30 @@ ck_manager_can_hibernate (CkManager *manager, return TRUE; } +gboolean +ck_manager_can_hibernate (CkManager *manager, + DBusGMethodInvocation *context) + +{ + if (ck_system_can_hibernate ()) { + dbus_g_method_return (context, TRUE); + } else { + dbus_g_method_return (context, FALSE); + } + + return TRUE; +} + +gboolean +ck_manager_inhibit (CkManager *manager, + gchar *what, + gchar *who, + gchar *why, + DBusGMethodInvocation *context) +{ + return TRUE; +} + static void on_seat_active_session_changed_full (CkSeat *seat, CkSession *old_session, diff --git a/src/ck-manager.h b/src/ck-manager.h index bfa2c01..d464056 100644 --- a/src/ck-manager.h +++ b/src/ck-manager.h @@ -97,6 +97,16 @@ gboolean ck_manager_can_suspend (CkManager *manage DBusGMethodInvocation *context); gboolean ck_manager_can_hibernate (CkManager *manager, DBusGMethodInvocation *context); +gboolean ck_manager_auth_suspend (CkManager *manager, + DBusGMethodInvocation *context); +gboolean ck_manager_auth_hibernate (CkManager *manager, + DBusGMethodInvocation *context); +gboolean ck_manager_inhibit (CkManager *manager, + gchar *what, + gchar *who, + gchar *why, + DBusGMethodInvocation *context); + /* Authoritative properties */ gboolean ck_manager_open_session (CkManager *manager, DBusGMethodInvocation *context); diff --git a/src/ck-sysdeps-solaris.c b/src/ck-sysdeps-solaris.c index bb37e1e..63cb6e0 100644 --- a/src/ck-sysdeps-solaris.c +++ b/src/ck-sysdeps-solaris.c @@ -529,3 +529,17 @@ ck_get_active_console_num (int console_fd, return ret; } + +gboolean +ck_system_can_suspend (void) +{ + /* TODO: not implemented */ + return FALSE; +} + +gboolean +ck_system_can_hibernate (void) +{ + /* TODO: not implemented */ + return FALSE; +} diff --git a/src/ck-sysdeps.h b/src/ck-sysdeps.h index 644d053..73c2608 100644 --- a/src/ck-sysdeps.h +++ b/src/ck-sysdeps.h @@ -54,6 +54,9 @@ uid_t *uid, GError **error); +gboolean ck_system_can_suspend (void); +gboolean ck_system_can_hibernate (void); + int ck_get_a_console_fd (void); gboolean ck_fd_is_a_console (int fd); diff --git a/src/org.freedesktop.ConsoleKit.Manager.xml b/src/org.freedesktop.ConsoleKit.Manager.xml index ae6a90c..7070225 100644 --- a/src/org.freedesktop.ConsoleKit.Manager.xml +++ b/src/org.freedesktop.ConsoleKit.Manager.xml @@ -16,6 +16,11 @@ + + + This method returns whether the user is authorized to restart the computer system. + + @@ -30,6 +35,11 @@ + + + This method returns whether the user is authorized to shutdown the computer system. + + @@ -44,6 +54,21 @@ + + + This method returns whether the computer system is capable of suspending. + + + + + + + + + + This method returns whether the user is authorized to suspend the computer system. + + @@ -58,6 +83,103 @@ + + + This method returns whether the computer system is capable of hibernating. + + + + + + + + + + This method returns whether the user is authorized to hibernate the computer system. + + + + + + + + + What is a colon-separated list of lock types. The list of lock types are: shutdown, sleep, idle, handle-power-key, handle-suspend-key, handle-hibernate-key. Example: "shutdown:idle" + + + + + Who is a human-readable, descriptive string of who is taking the lock. Example: "Xfburn" + + + + + Why is a human-readable, descriptive string of why the program is taking the lock. Example: "Burning a DVD, interrupting now will ruin the DVD." + + + + + + Returns a file descriptor that encapsulates the lock, or -1 on failure. As soon as the file descriptor is closed (and all its duplicates) the lock is automatically released. If the client dies while the lock is taken it is automatically closed and the lock is automatically released. + + + + + + See this simple example: + + DBusConnection *bus_connection; + DBusMessage *message = NULL, *reply = NULL; + DBusError error; + gint fd = -1; + const char *what = "shutdown:sleep"; + const char *who = "Xfburn"; + const char *why = "Burning a DVD, interrupting now will ruin the DVD."; + + message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit", + "/org/freedesktop/ConsoleKit/Manager", + "org.freedesktop.ConsoleKit.Manager", + "Inhibit"); + + if (!message) + { + g_warning ("Unable to call Inhibit()"); + return fd; + } + + if (!dbus_message_append_args (message, + DBUS_TYPE_STRING, &what, + DBUS_TYPE_STRING, &who, + DBUS_TYPE_STRING, &why, + DBUS_TYPE_INVALID)) + { + g_warning ("Unable to call Inhibit()"); + dbus_message_unref (message); + return fd; + } + + reply = dbus_connection_send_with_reply_and_block (bus_connection, message, -1, &error); + if (!reply) + { + g_warning ("Unable to inhibit: %s", error.message); + dbus_message_unref (message); + return fd; + } + + if (!dbus_message_get_args (reply, &error, + DBUS_TYPE_UNIX_FD, &fd, + DBUS_TYPE_INVALID)) + { + g_warning ("Inhibit() reply parsing failed: %s", error.message); + } + + dbus_message_unref (message); + dbus_message_unref (reply); + dbus_error_free (&error); + return fd; + + +