## Description: Add gnome session restart support to ensure we always have ## a authentication agent running ## Author: Michael Vogt ## Origin: inspired by the at-spi dbus support code ## Bug: http://launchpad.net/bugs/623819 Index: policykit-1-gnome-0.105/src/main.c =================================================================== --- policykit-1-gnome-0.105.orig/src/main.c 2011-10-25 11:30:59.000000000 -0400 +++ policykit-1-gnome-0.105/src/main.c 2011-12-19 09:23:47.635697248 -0500 @@ -38,11 +38,150 @@ static GDBusConnection *session_bus_connection = NULL; +// session management support for auto-restart +#define SM_DBUS_NAME "org.gnome.SessionManager" +#define SM_DBUS_PATH "/org/gnome/SessionManager" +#define SM_DBUS_INTERFACE "org.gnome.SessionManager" +#define SM_CLIENT_DBUS_INTERFACE "org.gnome.SessionManager.ClientPrivate" + +static GDBusProxy *sm_proxy; +static GDBusProxy *client_proxy = NULL; + +static GMainLoop *loop; + + +static void +stop_cb (void) +{ + g_main_loop_quit (loop); +} + +static gboolean +end_session_response (gboolean is_okay, const gchar *reason) +{ + GVariant *res; + GError *error = NULL; + + res = g_dbus_proxy_call_sync (client_proxy, + "EndSessionResponse", + g_variant_new ("(bs)", + is_okay, + reason), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + NULL, /* GCancellable */ + &error); + if (! res) { + g_warning ("Failed to call EndSessionResponse: %s", error->message); + g_error_free (error); + return FALSE; + } + + g_variant_unref (res); + return TRUE; +} + +static void +query_end_session_cb (void) +{ + end_session_response (TRUE, ""); +} + +static void +end_session_cb (void) +{ + end_session_response (TRUE, ""); + g_main_loop_quit (loop); +} + +static void +signal_cb (GDBusProxy *proxy, gchar *sender_name, gchar *signal_name, + GVariant *parameters, gpointer user_data) +{ + if (strcmp (signal_name, "Stop") == 0) { + stop_cb (); + } else if (strcmp (signal_name, "QueryEndSession") == 0) { + query_end_session_cb (); + } else if (strcmp (signal_name, "EndSession") == 0) { + end_session_cb (); + } +} + +static gboolean +register_client_to_gnome_session (void) +{ + GError *error = NULL; + GVariant *res; + const char *startup_id; + const char *app_id; + char *client_id; + + startup_id = g_getenv ("DESKTOP_AUTOSTART_ID"); + app_id = "polkit-gnome-authentication-agent-1.desktop"; + + sm_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo */ + SM_DBUS_NAME, + SM_DBUS_PATH, + SM_DBUS_INTERFACE, + NULL, /* GCancellable */ + &error); + if (sm_proxy == NULL) { + g_message("Failed to get session manager: %s", error->message); + g_error_free (error); + return FALSE; + } + + res = g_dbus_proxy_call_sync (sm_proxy, + "RegisterClient", + g_variant_new ("(ss)", + app_id, + startup_id), + G_DBUS_CALL_FLAGS_NONE, + -1, /* timeout */ + NULL, /* GCancellable */ + &error); + if (! res) { + g_warning ("Failed to register client: %s", error->message); + g_error_free (error); + return FALSE; + } + + if (! g_variant_is_of_type (res, G_VARIANT_TYPE ("(o)"))) { + g_warning ("RegisterClient returned unexpected type %s", + g_variant_get_type_string (res)); + return FALSE; + } + + g_variant_get (res, "(&o)", &client_id); + + // implement the signals to fix "policykit agent not responding" + // error (LP: #623819) + client_proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION, + G_DBUS_PROXY_FLAGS_NONE, + NULL, /* GDBusInterfaceInfo */ + SM_DBUS_NAME, + client_id, + SM_CLIENT_DBUS_INTERFACE, + NULL, /* GCancellable */ + &error); + g_variant_unref (res); + if (client_proxy == NULL) { + g_message("Failed to get client proxy: %s", error->message); + g_error_free (error); + return FALSE; + } + + g_signal_connect (client_proxy, "g-signal", G_CALLBACK (signal_cb), NULL); + + return TRUE; +} + int main (int argc, char **argv) { gint ret; - GMainLoop *loop; PolkitAgentListener *listener; GError *error; @@ -101,6 +240,8 @@ */ session_bus_connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); + register_client_to_gnome_session(); + g_main_loop_run (loop); ret = 0;