## Description: Add gnome session restart support to ensure we always have
##              a authentication agent running
## Author: Michael Vogt <mvo@ubuntu.com>
## Origin: inspired by the at-spi dbus support code
## Bug: http://launchpad.net/bugs/623819
Index: ubuntu/src/polkit-gnome-authentication-agent-1.desktop.in.in
===================================================================
--- ubuntu.orig/src/polkit-gnome-authentication-agent-1.desktop.in.in	2010-08-30 09:58:30.895578001 +0200
+++ ubuntu/src/polkit-gnome-authentication-agent-1.desktop.in.in	2010-08-30 09:58:30.935578001 +0200
@@ -7,3 +7,4 @@
 Categories=
 NoDisplay=true
 OnlyShowIn=GNOME;XFCE;
+X-GNOME-AutoRestart=true
Index: ubuntu/src/main.c
===================================================================
--- ubuntu.orig/src/main.c	2010-08-30 09:58:30.925578001 +0200
+++ ubuntu/src/main.c	2010-08-30 09:58:59.525578001 +0200
@@ -27,6 +27,7 @@
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
 #include <polkitagent/polkitagent.h>
+#include <dbus/dbus-glib.h>
 
 #ifdef HAVE_APPINDICATOR
 #include <libappindicator/app-indicator.h>
@@ -250,11 +251,131 @@
   update_temporary_authorization_icon (authority);
 }
 
+// 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 DBusGConnection *bus_connection;
+static DBusGProxy      *sm_proxy;
+static DBusGProxy      *client_proxy = NULL;
+
+static  GMainLoop *loop;
+
+
+static void
+stop_cb (gpointer data)
+{
+        g_main_loop_quit (loop);
+}
+
+static gboolean
+end_session_response (gboolean is_okay, const gchar *reason)
+{
+        gboolean ret;
+        GError *error = NULL;
+
+        ret = dbus_g_proxy_call (client_proxy, "EndSessionResponse",
+                                 &error,
+                                 G_TYPE_BOOLEAN, is_okay,
+                                 G_TYPE_STRING, reason,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_INVALID);
+
+        if (!ret) {
+                g_warning ("Failed to send session response %s", error->message);
+                g_error_free (error);
+        }
+
+        return ret;
+}
+
+static void
+query_end_session_cb (guint flags, gpointer data)
+{
+        end_session_response (TRUE, NULL);
+}
+
+static void
+end_session_cb (guint flags, gpointer data)
+{
+        end_session_response (TRUE, NULL);
+        g_main_loop_quit (loop);
+}
+
+
+static gboolean
+register_client_to_gnome_session (void)
+{
+        GError     *error;
+        gboolean    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";
+
+        error = NULL;
+        bus_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+        if (bus_connection == NULL) {
+           g_message ("Failed to connect to the session bus: %s",
+                      error->message);
+           g_error_free (error);
+           return FALSE;
+        }
+
+        sm_proxy = dbus_g_proxy_new_for_name (bus_connection,
+                                              SM_DBUS_NAME,
+                                              SM_DBUS_PATH,
+                                              SM_DBUS_INTERFACE);
+        if (sm_proxy == NULL) {
+           g_message("Failed to get session manager");
+           return FALSE;
+        }
+
+        error = NULL;
+        res = dbus_g_proxy_call (sm_proxy,
+                                 "RegisterClient",
+                                 &error,
+                                 G_TYPE_STRING, app_id,
+                                 G_TYPE_STRING, startup_id,
+                                 G_TYPE_INVALID,
+                                 DBUS_TYPE_G_OBJECT_PATH, &client_id,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                g_warning ("Failed to register client: %s", error->message);
+                g_error_free (error);
+                return FALSE;
+        }
+
+        // implement the signals to fix "policykit agent not responding"
+        // error (LP: #623819)
+        client_proxy = dbus_g_proxy_new_for_name (bus_connection,
+                                                  SM_DBUS_NAME,
+                                                  client_id,
+                                                  SM_CLIENT_DBUS_INTERFACE);
+
+        dbus_g_proxy_add_signal (client_proxy, "Stop", G_TYPE_INVALID);
+        dbus_g_proxy_connect_signal (client_proxy, "Stop",
+                                     G_CALLBACK (stop_cb), NULL, NULL);
+
+        dbus_g_proxy_add_signal (client_proxy, "QueryEndSession", G_TYPE_UINT, G_TYPE_INVALID);
+        dbus_g_proxy_connect_signal (client_proxy, "QueryEndSession",
+                                     G_CALLBACK (query_end_session_cb), NULL, NULL);
+
+        dbus_g_proxy_add_signal (client_proxy, "EndSession", G_TYPE_UINT, G_TYPE_INVALID);
+        dbus_g_proxy_connect_signal (client_proxy, "EndSession",
+                                     G_CALLBACK (end_session_cb), NULL, NULL);
+
+        return TRUE;
+}
+
 int
 main (int argc, char **argv)
 {
   gint ret;
-  GMainLoop *loop;
   PolkitAgentListener *listener;
   GError *error;
 
@@ -305,6 +426,8 @@
 
   update_temporary_authorization_icon (authority);
 
+  register_client_to_gnome_session();
+
   g_main_loop_run (loop);
 
   ret = 0;
Index: ubuntu/src/Makefile.am
===================================================================
--- ubuntu.orig/src/Makefile.am	2010-08-30 09:58:30.925578001 +0200
+++ ubuntu/src/Makefile.am	2010-08-30 09:58:30.935578001 +0200
@@ -28,6 +28,7 @@
 	$(AM_CPPFLAGS)
 
 polkit_gnome_authentication_agent_1_CFLAGS = 		\
+	$(DBUS_GLIB_CFLAGS)				\
 	$(GTK_CFLAGS)					\
 	$(GCONF_CFLAGS)					\
 	$(POLKIT_AGENT_CFLAGS)				\
@@ -40,6 +41,7 @@
 	$(AM_LDFLAGS)
 
 polkit_gnome_authentication_agent_1_LDADD = 		\
+	$(DBUS_GLIB_LIBS)				\
 	$(GTK_LIBS)					\
 	$(GCONF_LIBS)					\
 	$(POLKIT_AGENT_LIBS)				\
