[gnome-session] Move suspend API to GsmSystem



commit 2e69a0cba171f6dfe762147f2c690f157664ad45
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Jun 1 00:51:20 2012 -0400

    Move suspend API to GsmSystem
    
    This allows us to add a systemd-based suspend/hibernate
    implementation.

 gnome-session/gsm-consolekit.c |   71 ++++++++++++++++++----
 gnome-session/gsm-manager.c    |   93 ++++++-----------------------
 gnome-session/gsm-system.c     |   24 ++++++++
 gnome-session/gsm-system.h     |   12 ++++
 gnome-session/gsm-systemd.c    |  126 ++++++++++++++++++++++++++++++++++++++++
 5 files changed, 239 insertions(+), 87 deletions(-)
---
diff --git a/gnome-session/gsm-consolekit.c b/gnome-session/gsm-consolekit.c
index b45f56a..d1cb945 100644
--- a/gnome-session/gsm-consolekit.c
+++ b/gnome-session/gsm-consolekit.c
@@ -31,6 +31,8 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
+#include <upower.h>
+
 #include "gsm-system.h"
 #include "gsm-consolekit.h"
 
@@ -53,6 +55,7 @@ struct _GsmConsolekitPrivate
         DBusGConnection *dbus_connection;
         DBusGProxy      *bus_proxy;
         DBusGProxy      *ck_proxy;
+        UpClient        *up_client;
 };
 
 static void     gsm_consolekit_class_init   (GsmConsolekitClass *klass);
@@ -215,12 +218,12 @@ gsm_consolekit_on_name_owner_changed (DBusGProxy    *bus_proxy,
                 return;
         }
 
-        if (manager->priv->ck_proxy != NULL) {
-                g_object_unref (manager->priv->ck_proxy);
-                manager->priv->ck_proxy = NULL;
-        }
+        g_clear_object (&manager->priv->ck_proxy);
+        g_clear_object (&manager->priv->up_client);
 
         gsm_consolekit_ensure_ck_connection (manager, NULL);
+        manager->priv->up_client = up_client_new ();
+
 }
 
 static void
@@ -242,15 +245,9 @@ gsm_consolekit_init (GsmConsolekit *manager)
 static void
 gsm_consolekit_free_dbus (GsmConsolekit *manager)
 {
-        if (manager->priv->bus_proxy != NULL) {
-                g_object_unref (manager->priv->bus_proxy);
-                manager->priv->bus_proxy = NULL;
-        }
-
-        if (manager->priv->ck_proxy != NULL) {
-                g_object_unref (manager->priv->ck_proxy);
-                manager->priv->ck_proxy = NULL;
-        }
+        g_clear_object (&manager->priv->bus_proxy);
+        g_clear_object (&manager->priv->ck_proxy);
+        g_clear_object (&manager->priv->up_client);
 
         if (manager->priv->dbus_connection != NULL) {
                 DBusConnection *connection;
@@ -814,14 +811,62 @@ gsm_consolekit_is_login_session (GsmSystem *system)
         return ret;
 }
 
+static gboolean
+gsm_consolekit_can_suspend (GsmSystem *system)
+{
+        GsmConsolekit *consolekit = GSM_CONSOLEKIT (system);
+
+        return up_client_get_can_suspend (consolekit->priv->up_client);
+}
+
+static gboolean
+gsm_consolekit_can_hibernate (GsmSystem *system)
+{
+        GsmConsolekit *consolekit = GSM_CONSOLEKIT (system);
+
+        return up_client_get_can_hibernate (consolekit->priv->up_client);
+}
+
+static void
+gsm_consolekit_suspend (GsmSystem *system)
+{
+        GsmConsolekit *consolekit = GSM_CONSOLEKIT (system);
+        GError *error = NULL;
+        gboolean ret;
+
+        ret = up_client_suspend_sync (consolekit->priv->up_client, NULL, &error);
+        if (!ret) {
+                g_warning ("Unexpected suspend failure: %s", error->message);
+                g_error_free (error);
+        }
+}
+
+static void
+gsm_consolekit_hibernate (GsmSystem *system)
+{
+        GsmConsolekit *consolekit = GSM_CONSOLEKIT (system);
+        GError *error = NULL;
+        gboolean ret;
+
+        ret = up_client_hibernate_sync (consolekit->priv->up_client, NULL, &error);
+        if (!ret) {
+                g_warning ("Unexpected hibernate failure: %s", error->message);
+                g_error_free (error);
+        }
+}
+
 static void
 gsm_consolekit_system_init (GsmSystemInterface *iface)
 {
         iface->can_switch_user = gsm_consolekit_can_switch_user;
         iface->can_stop = gsm_consolekit_can_stop;
         iface->can_restart = gsm_consolekit_can_restart;
+        iface->can_suspend = gsm_consolekit_can_suspend;
+        iface->can_hibernate = gsm_consolekit_can_hibernate;
         iface->attempt_stop = gsm_consolekit_attempt_stop;
         iface->attempt_restart = gsm_consolekit_attempt_restart;
+        iface->suspend = gsm_consolekit_suspend;
+        iface->hibernate = gsm_consolekit_hibernate;
         iface->set_session_idle = gsm_consolekit_set_session_idle;
         iface->is_login_session = gsm_consolekit_is_login_session;
 }
diff --git a/gnome-session/gsm-manager.c b/gnome-session/gsm-manager.c
index 0f0f491..14957f0 100644
--- a/gnome-session/gsm-manager.c
+++ b/gnome-session/gsm-manager.c
@@ -38,8 +38,6 @@
 #include <dbus/dbus-glib.h>
 #include <dbus/dbus-glib-lowlevel.h>
 
-#include <upower.h>
-
 #include <gtk/gtk.h> /* for logout dialog */
 
 #include "gsm-manager.h"
@@ -150,13 +148,11 @@ struct GsmManagerPrivate
         GSettings              *screensaver_settings;
         GSettings              *lockdown_settings;
 
+        GsmSystem              *system;
         DBusGProxy             *bus_proxy;
         DBusGConnection        *connection;
         gboolean                dbus_disconnected : 1;
 
-        /* Interface with other parts of the system */
-        UpClient               *up_client;
-
         GsmShell               *shell;
         guint                   shell_end_session_dialog_canceled_id;
         guint                   shell_end_session_dialog_open_failed_id;
@@ -276,7 +272,6 @@ on_required_app_failure (GsmManager  *manager,
 {
         const gchar *app_id;
         gboolean allow_logout;
-        GsmSystem *system;
         GsmShellExtensions *extensions;
 
         app_id = gsm_app_peek_app_id (app);
@@ -288,13 +283,11 @@ on_required_app_failure (GsmManager  *manager,
                 extensions = NULL;
         }
 
-        system = gsm_get_system ();
-        if (gsm_system_is_login_session (system)) {
+        if (gsm_system_is_login_session (manager->priv->system)) {
                 allow_logout = FALSE;
         } else {
                 allow_logout = !_log_out_is_locked_down (manager);
         }
-        g_object_unref (system);
 
         gsm_fail_whale_dialog_we_failed (FALSE,
                                          allow_logout,
@@ -479,16 +472,12 @@ quit_request_completed (GsmSystem *system,
                 gdm_set_logout_action (fallback_action);
         }
 
-        g_object_unref (system);
-
         gtk_main_quit ();
 }
 
 static void
 gsm_manager_quit (GsmManager *manager)
 {
-        GsmSystem *system;
-
         /* See the comment in request_reboot() for some more details about how
          * this works. */
 
@@ -500,12 +489,11 @@ gsm_manager_quit (GsmManager *manager)
         case GSM_MANAGER_LOGOUT_REBOOT_INTERACT:
                 gdm_set_logout_action (GDM_LOGOUT_ACTION_NONE);
 
-                system = gsm_get_system ();
-                g_signal_connect (system,
+                g_signal_connect (manager->priv->system,
                                   "request-completed",
                                   G_CALLBACK (quit_request_completed),
                                   GINT_TO_POINTER (GDM_LOGOUT_ACTION_REBOOT));
-                gsm_system_attempt_restart (system);
+                gsm_system_attempt_restart (manager->priv->system);
                 break;
         case GSM_MANAGER_LOGOUT_REBOOT_GDM:
                 gdm_set_logout_action (GDM_LOGOUT_ACTION_REBOOT);
@@ -515,12 +503,11 @@ gsm_manager_quit (GsmManager *manager)
         case GSM_MANAGER_LOGOUT_SHUTDOWN_INTERACT:
                 gdm_set_logout_action (GDM_LOGOUT_ACTION_NONE);
 
-                system = gsm_get_system ();
-                g_signal_connect (system,
+                g_signal_connect (manager->priv->system,
                                   "request-completed",
                                   G_CALLBACK (quit_request_completed),
                                   GINT_TO_POINTER (GDM_LOGOUT_ACTION_SHUTDOWN));
-                gsm_system_attempt_stop (system);
+                gsm_system_attempt_stop (manager->priv->system);
                 break;
         case GSM_MANAGER_LOGOUT_SHUTDOWN_GDM:
                 gdm_set_logout_action (GDM_LOGOUT_ACTION_SHUTDOWN);
@@ -1156,46 +1143,20 @@ manager_perhaps_lock (GsmManager *manager)
 static void
 manager_attempt_hibernate (GsmManager *manager)
 {
-        gboolean  can_hibernate;
-        GError   *error;
-        gboolean  ret;
-
-        can_hibernate = up_client_get_can_hibernate (manager->priv->up_client);
-        if (can_hibernate) {
-
+        if (gsm_system_can_hibernate (manager->priv->system)) {
                 /* lock the screen before we suspend */
                 manager_perhaps_lock (manager);
-
-                error = NULL;
-                ret = up_client_hibernate_sync (manager->priv->up_client, NULL, &error);
-                if (!ret) {
-                        g_warning ("Unexpected hibernate failure: %s",
-                                   error->message);
-                        g_error_free (error);
-                }
+                gsm_system_hibernate (manager->priv->system);
         }
 }
 
 static void
 manager_attempt_suspend (GsmManager *manager)
 {
-        gboolean  can_suspend;
-        GError   *error;
-        gboolean  ret;
-
-        can_suspend = up_client_get_can_suspend (manager->priv->up_client);
-        if (can_suspend) {
-
+        if (gsm_system_can_suspend (manager->priv->system)) {
                 /* lock the screen before we suspend */
                 manager_perhaps_lock (manager);
-
-                error = NULL;
-                ret = up_client_suspend_sync (manager->priv->up_client, NULL, &error);
-                if (!ret) {
-                        g_warning ("Unexpected suspend failure: %s",
-                                   error->message);
-                        g_error_free (error);
-                }
+                gsm_system_suspend (manager->priv->system);
         }
 }
 
@@ -2196,14 +2157,9 @@ auto_save_is_enabled (GsmManager *manager)
 static void
 maybe_save_session (GsmManager *manager)
 {
-        GsmSystem *system;
         GError *error;
-        gboolean is_login;
 
-        system = gsm_get_system ();
-        is_login = gsm_system_is_login_session (system);
-        g_object_unref (system);
-        if (is_login)
+        if (gsm_system_is_login_session (manager->priv->system))
                 return;
 
         /* We only allow session saving when session is running or when
@@ -2594,9 +2550,9 @@ gsm_manager_dispose (GObject *object)
                 manager->priv->lockdown_settings = NULL;
         }
 
-        if (manager->priv->up_client != NULL) {
-                g_object_unref (manager->priv->up_client);
-                manager->priv->up_client = NULL;
+        if (manager->priv->system != NULL) {
+                g_object_unref (manager->priv->system);
+                manager->priv->system = NULL;
         }
 
         if (manager->priv->shell != NULL) {
@@ -2804,7 +2760,7 @@ gsm_manager_init (GsmManager *manager)
                                       NULL,
                                       NULL, NULL);
 
-        manager->priv->up_client = up_client_new ();
+        manager->priv->system = gsm_get_system ();
 
         manager->priv->shell = gsm_get_shell ();
 }
@@ -3444,26 +3400,15 @@ gsm_manager_can_shutdown (GsmManager *manager,
                           gboolean   *shutdown_available,
                           GError    **error)
 {
-        GsmSystem *system;
-        gboolean can_suspend;
-        gboolean can_hibernate;
-
-        g_object_get (manager->priv->up_client,
-                      "can-suspend", &can_suspend,
-                      "can-hibernate", &can_hibernate,
-                      NULL);
-
         g_debug ("GsmManager: CanShutdown called");
 
         g_return_val_if_fail (GSM_IS_MANAGER (manager), FALSE);
 
-        system = gsm_get_system ();
         *shutdown_available = !_log_out_is_locked_down (manager) &&
-                              (gsm_system_can_stop (system)
-                               || gsm_system_can_restart (system)
-                               || can_suspend
-                               || can_hibernate);
-        g_object_unref (system);
+                              (gsm_system_can_stop (manager->priv->system)
+                               || gsm_system_can_restart (manager->priv->system)
+                               || gsm_system_can_suspend (manager->priv->system)
+                               || gsm_system_can_hibernate (manager->priv->system));
 
         return TRUE;
 }
diff --git a/gnome-session/gsm-system.c b/gnome-session/gsm-system.c
index 9e7f155..9a522f0 100644
--- a/gnome-session/gsm-system.c
+++ b/gnome-session/gsm-system.c
@@ -81,6 +81,18 @@ gsm_system_can_restart (GsmSystem *system)
         return GSM_SYSTEM_GET_IFACE (system)->can_restart (system);
 }
 
+gboolean
+gsm_system_can_suspend (GsmSystem *system)
+{
+        return GSM_SYSTEM_GET_IFACE (system)->can_suspend (system);
+}
+
+gboolean
+gsm_system_can_hibernate (GsmSystem *system)
+{
+        return GSM_SYSTEM_GET_IFACE (system)->can_hibernate (system);
+}
+
 void
 gsm_system_attempt_stop (GsmSystem *system)
 {
@@ -94,6 +106,18 @@ gsm_system_attempt_restart (GsmSystem *system)
 }
 
 void
+gsm_system_suspend (GsmSystem *system)
+{
+        GSM_SYSTEM_GET_IFACE (system)->suspend (system);
+}
+
+void
+gsm_system_hibernate (GsmSystem *system)
+{
+        GSM_SYSTEM_GET_IFACE (system)->hibernate (system);
+}
+
+void
 gsm_system_set_session_idle (GsmSystem *system,
                              gboolean   is_idle)
 {
diff --git a/gnome-session/gsm-system.h b/gnome-session/gsm-system.h
index c3975e7..e93505f 100644
--- a/gnome-session/gsm-system.h
+++ b/gnome-session/gsm-system.h
@@ -50,8 +50,12 @@ struct _GsmSystemInterface
         gboolean (* can_switch_user)  (GsmSystem *system);
         gboolean (* can_stop)         (GsmSystem *system);
         gboolean (* can_restart)      (GsmSystem *system);
+        gboolean (* can_suspend)      (GsmSystem *system);
+        gboolean (* can_hibernate)    (GsmSystem *system);
         void     (* attempt_stop)     (GsmSystem *system);
         void     (* attempt_restart)  (GsmSystem *system);
+        void     (* suspend)          (GsmSystem *system);
+        void     (* hibernate)        (GsmSystem *system);
         void     (* set_session_idle) (GsmSystem *system,
                                        gboolean   is_idle);
         gboolean (* is_login_session) (GsmSystem *system);
@@ -74,10 +78,18 @@ gboolean   gsm_system_can_stop         (GsmSystem *system);
 
 gboolean   gsm_system_can_restart      (GsmSystem *system);
 
+gboolean   gsm_system_can_suspend      (GsmSystem *system);
+
+gboolean   gsm_system_can_hibernate    (GsmSystem *system);
+
 void       gsm_system_attempt_stop     (GsmSystem *system);
 
 void       gsm_system_attempt_restart  (GsmSystem *system);
 
+void       gsm_system_suspend          (GsmSystem *system);
+
+void       gsm_system_hibernate        (GsmSystem *system);
+
 void       gsm_system_set_session_idle (GsmSystem *system,
                                         gboolean   is_idle);
 
diff --git a/gnome-session/gsm-systemd.c b/gnome-session/gsm-systemd.c
index 7ceb478..3c83329 100644
--- a/gnome-session/gsm-systemd.c
+++ b/gnome-session/gsm-systemd.c
@@ -364,14 +364,140 @@ gsm_systemd_is_login_session (GsmSystem *system)
         return ret;
 }
 
+static gboolean
+gsm_systemd_can_suspend (GsmSystem *system)
+{
+        GsmSystemd *manager = GSM_SYSTEMD (system);
+        gchar *rv;
+        GVariant *res;
+        gboolean can_suspend;
+
+        res = g_dbus_proxy_call_sync (manager->priv->sd_proxy,
+                                      "CanSuspend",
+                                      NULL,
+                                      0,
+                                      G_MAXINT,
+                                      NULL,
+                                      NULL);
+        g_variant_get (res, "(s)", &rv);
+        g_variant_unref (res);
+
+        can_suspend = g_strcmp0 (rv, "yes") == 0 ||
+                      g_strcmp0 (rv, "challenge") == 0;
+
+        g_free (rv);
+
+        return can_suspend;
+}
+
+static gboolean
+gsm_systemd_can_hibernate (GsmSystem *system)
+{
+        GsmSystemd *manager = GSM_SYSTEMD (system);
+        gchar *rv;
+        GVariant *res;
+        gboolean can_hibernate;
+
+        res = g_dbus_proxy_call_sync (manager->priv->sd_proxy,
+                                      "CanHibernate",
+                                      NULL,
+                                      0,
+                                      G_MAXINT,
+                                      NULL,
+                                      NULL);
+        g_variant_get (res, "(s)", &rv);
+        g_variant_unref (res);
+
+        can_hibernate = g_strcmp0 (rv, "yes") == 0 ||
+                        g_strcmp0 (rv, "challenge") == 0;
+
+        g_free (rv);
+
+        return can_hibernate;
+}
+
+static void
+suspend_done (GObject      *source,
+              GAsyncResult *result,
+              gpointer      user_data)
+{
+        GDBusProxy *proxy = G_DBUS_PROXY (source);
+        GsmSystemd *manager = user_data;
+        GError *error = NULL;
+        GVariant *res;
+
+        res = g_dbus_proxy_call_finish (proxy, result, &error);
+
+        if (!res) {
+                g_warning ("Unable to suspend system: %s", error->message);
+                g_error_free (error);
+        } else {
+                g_variant_unref (res);
+        }
+}
+
+static void
+hibernate_done (GObject      *source,
+                GAsyncResult *result,
+              gpointer      user_data)
+{
+        GDBusProxy *proxy = G_DBUS_PROXY (source);
+        GsmSystemd *manager = user_data;
+        GError *error = NULL;
+        GVariant *res;
+
+        res = g_dbus_proxy_call_finish (proxy, result, &error);
+
+        if (!res) {
+                g_warning ("Unable to hibernate system: %s", error->message);
+                g_error_free (error);
+        } else {
+                g_variant_unref (res);
+        }
+}
+
+static void
+gsm_systemd_suspend (GsmSystem *system)
+{
+        GsmSystemd *manager = GSM_SYSTEMD (system);
+
+        g_dbus_proxy_call (manager->priv->sd_proxy,
+                           "Suspend",
+                           g_variant_new ("(b)", TRUE),
+                           0,
+                           G_MAXINT,
+                           NULL,
+                           hibernate_done,
+                           manager);
+}
+
+static void
+gsm_systemd_hibernate (GsmSystem *system)
+{
+        GsmSystemd *manager = GSM_SYSTEMD (system);
+
+        g_dbus_proxy_call (manager->priv->sd_proxy,
+                           "Hibernate",
+                           g_variant_new ("(b)", TRUE),
+                           0,
+                           G_MAXINT,
+                           NULL,
+                           suspend_done,
+                           manager);
+}
+
 static void
 gsm_systemd_system_init (GsmSystemInterface *iface)
 {
         iface->can_switch_user = gsm_systemd_can_switch_user;
         iface->can_stop = gsm_systemd_can_stop;
         iface->can_restart = gsm_systemd_can_restart;
+        iface->can_suspend = gsm_systemd_can_suspend;
+        iface->can_hibernate = gsm_systemd_can_hibernate;
         iface->attempt_stop = gsm_systemd_attempt_stop;
         iface->attempt_restart = gsm_systemd_attempt_restart;
+        iface->suspend = gsm_systemd_suspend;
+        iface->hibernate = gsm_systemd_hibernate;
         iface->set_session_idle = gsm_systemd_set_session_idle;
         iface->is_login_session = gsm_systemd_is_login_session;
 }



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]