gnome-session r4760 - in branches/dbus_based: . gnome-session



Author: mccann
Date: Wed Jun 18 20:02:37 2008
New Revision: 4760
URL: http://svn.gnome.org/viewvc/gnome-session?rev=4760&view=rev

Log:
2008-06-18  William Jon McCann  <jmccann redhat com>

	* gnome-session/Makefile.am:
	* gnome-session/gsm-app.c (gsm_app_class_init),
	(gsm_app_get_autorestart), (gsm_app_restart):
	* gnome-session/gsm-app.h:
	* gnome-session/gsm-autostart-app.c (gsm_autostart_app_dispose),
	(gsm_autostart_app_stop), (gsm_autostart_app_start),
	(gsm_autostart_app_restart), (gsm_autostart_app_get_autorestart),
	(gsm_autostart_app_class_init):
	* gnome-session/gsm-client.c (gsm_client_class_init):
	* gnome-session/gsm-client.h:
	* gnome-session/gsm-dbus-client.c (gsm_dbus_client_set_bus_name),
	(gsm_dbus_client_get_bus_name), (gsm_dbus_client_set_property),
	(gsm_dbus_client_get_property), (gsm_dbus_client_class_init):
	* gnome-session/gsm-dbus-client.h:
	* gnome-session/gsm-manager.c (gsm_manager_error_get_type),
	(find_app_for_app_id), (disconnect_client),
	(_disconnect_dbus_client), (remove_clients_for_connection),
	(on_client_disconnected), (on_xsmp_client_register_request),
	(gsm_manager_register_client), (gsm_manager_unregister_client):
	* gnome-session/gsm-manager.h:
	* gnome-session/gsm-manager.xml:
	* gnome-session/gsm-method-client.c (gsm_method_client_class_init):
	* gnome-session/gsm-resumed-app.c (app_exited),
	(gsm_resumed_app_start), (gsm_resumed_app_restart),
	(gsm_resumed_app_dispose), (gsm_resumed_app_class_init):
	* gnome-session/gsm-service-client.c
	(gsm_service_client_class_init):
	* gnome-session/gsm-xsmp-client.c (gsm_xsmp_client_class_init),
	(register_client_callback):
	* gnome-session/test-client-method.c (session_manager_connect),
	(register_client), (session_manager_disconnect),
	(unregister_client), (main):
	Add dbus method client support.  Add test client.  Fix up
	restart handling.



Added:
   branches/dbus_based/gnome-session/test-client-method.c
Modified:
   branches/dbus_based/ChangeLog
   branches/dbus_based/gnome-session/Makefile.am
   branches/dbus_based/gnome-session/gsm-app.c
   branches/dbus_based/gnome-session/gsm-app.h
   branches/dbus_based/gnome-session/gsm-autostart-app.c
   branches/dbus_based/gnome-session/gsm-client.c
   branches/dbus_based/gnome-session/gsm-client.h
   branches/dbus_based/gnome-session/gsm-dbus-client.c
   branches/dbus_based/gnome-session/gsm-dbus-client.h
   branches/dbus_based/gnome-session/gsm-manager.c
   branches/dbus_based/gnome-session/gsm-manager.h
   branches/dbus_based/gnome-session/gsm-manager.xml
   branches/dbus_based/gnome-session/gsm-method-client.c
   branches/dbus_based/gnome-session/gsm-resumed-app.c
   branches/dbus_based/gnome-session/gsm-service-client.c
   branches/dbus_based/gnome-session/gsm-xsmp-client.c

Modified: branches/dbus_based/gnome-session/Makefile.am
==============================================================================
--- branches/dbus_based/gnome-session/Makefile.am	(original)
+++ branches/dbus_based/gnome-session/Makefile.am	Wed Jun 18 20:02:37 2008
@@ -1,7 +1,13 @@
+NULL =
+
 bin_PROGRAMS = gnome-session
 
 noinst_LTLIBRARIES = libgsmutil.la
 
+noinst_PROGRAMS = 		\
+	test-client-method	\
+	$(NULL)
+
 INCLUDES =					\
 	$(WARN_CFLAGS)				\
 	$(GNOME_SESSION_CFLAGS)			\
@@ -16,6 +22,14 @@
 	-DGCONF_SANITY_CHECK=\""$(GCONF_SANITY_CHECK)"\" \
 	-DGCONFTOOL_CMD=\"$(GCONFTOOL)\"
 
+test_client_method_SOURCES = 	\
+	test-client-method.c	\
+	$(NULL)
+
+test_client_method_LDADD =			\
+	$(DBUS_GLIB_LIBS)			\
+	$(NULL)
+
 gnome_session_LDADD =				\
 	-lSM -lICE				\
 	libgsmutil.la 				\

Modified: branches/dbus_based/gnome-session/gsm-app.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-app.c	(original)
+++ branches/dbus_based/gnome-session/gsm-app.c	Wed Jun 18 20:02:37 2008
@@ -142,6 +142,7 @@
 
         klass->get_id = NULL;
         klass->start = NULL;
+        klass->get_autorestart = NULL;
         klass->provides = NULL;
         klass->is_running = NULL;
 
@@ -254,6 +255,18 @@
 }
 
 gboolean
+gsm_app_get_autorestart (GsmApp *app)
+{
+        g_return_val_if_fail (GSM_IS_APP (app), FALSE);
+
+        if (GSM_APP_GET_CLASS (app)->get_autorestart) {
+                return GSM_APP_GET_CLASS (app)->get_autorestart (app);
+        } else {
+                return FALSE;
+        }
+}
+
+gboolean
 gsm_app_provides (GsmApp *app, const char *service)
 {
 
@@ -274,6 +287,15 @@
 }
 
 gboolean
+gsm_app_restart (GsmApp  *app,
+                 GError **error)
+{
+        g_debug ("Re-starting app: %s", app->priv->id);
+
+        return GSM_APP_GET_CLASS (app)->restart (app, error);
+}
+
+gboolean
 gsm_app_stop (GsmApp  *app,
               GError **error)
 {

Modified: branches/dbus_based/gnome-session/gsm-app.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-app.h	(original)
+++ branches/dbus_based/gnome-session/gsm-app.h	Wed Jun 18 20:02:37 2008
@@ -59,26 +59,33 @@
         void        (*registered)   (GsmApp *app);
 
         /* virtual methods */
-        gboolean    (*start)         (GsmApp     *app,
-                                      GError    **error);
-        gboolean    (*stop)          (GsmApp     *app,
-                                      GError    **error);
-        gboolean    (*provides)      (GsmApp     *app,
-                                      const char *service);
-        gboolean    (*is_running)    (GsmApp     *app);
-
-        const char *(*get_id)       (GsmApp *app);
-        gboolean    (*is_disabled)  (GsmApp *app);
-        void        (*set_client)   (GsmApp    *app,
-                                     GsmClient *client);
+        gboolean    (*start)           (GsmApp     *app,
+                                        GError    **error);
+        gboolean    (*restart)         (GsmApp     *app,
+                                        GError    **error);
+        gboolean    (*stop)            (GsmApp     *app,
+                                        GError    **error);
+        gboolean    (*provides)        (GsmApp     *app,
+                                        const char *service);
+        gboolean    (*is_running)      (GsmApp     *app);
+
+        gboolean    (*get_autorestart) (GsmApp     *app);
+        const char *(*get_id)          (GsmApp     *app);
+        gboolean    (*is_disabled)     (GsmApp     *app);
+        void        (*set_client)      (GsmApp     *app,
+                                        GsmClient  *client);
 };
 
 GType            gsm_app_get_type        (void) G_GNUC_CONST;
 
 gboolean         gsm_app_start           (GsmApp     *app,
                                           GError    **error);
+gboolean         gsm_app_restart         (GsmApp     *app,
+                                          GError    **error);
 gboolean         gsm_app_stop            (GsmApp     *app,
                                           GError    **error);
+gboolean         gsm_app_get_autorestart (GsmApp     *app);
+
 const char      *gsm_app_get_id          (GsmApp     *app);
 const char      *gsm_app_get_client_id   (GsmApp     *app);
 GsmManagerPhase  gsm_app_get_phase       (GsmApp     *app);

Modified: branches/dbus_based/gnome-session/gsm-autostart-app.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-autostart-app.c	(original)
+++ branches/dbus_based/gnome-session/gsm-autostart-app.c	Wed Jun 18 20:02:37 2008
@@ -26,6 +26,7 @@
 #include <ctype.h>
 #include <string.h>
 #include <sys/wait.h>
+#include <glib.h>
 #include <gio/gio.h>
 
 #include "gsm-autostart-app.h"
@@ -33,12 +34,12 @@
 
 struct _GsmAutostartAppPrivate {
         char                 *desktop_id;
+        char                 *startup_id;
         GFileMonitor         *monitor;
         gboolean              condition;
         EggDesktopFile       *desktop_file;
         GPid                  pid;
         guint                 child_watch_id;
-        char                 *startup_id;
 };
 
 enum {
@@ -186,6 +187,11 @@
                 priv->desktop_id = NULL;
         }
 
+        if (priv->child_watch_id > 0) {
+                g_source_remove (priv->child_watch_id);
+                priv->child_watch_id = 0;
+        }
+
         if (priv->monitor) {
                 g_file_monitor_cancel (priv->monitor);
         }
@@ -465,11 +471,22 @@
 }
 
 static gboolean
-launch (GsmApp  *app,
-        GError **error)
+gsm_autostart_app_stop (GsmApp  *app,
+                        GError **error)
+{
+        /* FIXME: */
+        /* first try to stop client */
+
+        /* then try to stop pid */
+        return TRUE;
+}
+
+static gboolean
+gsm_autostart_app_start (GsmApp  *app,
+                         GError **error)
 {
-        char    *env[2] = { NULL, NULL };
-        gboolean success;
+        char            *env[2] = { NULL, NULL };
+        gboolean         success;
         GsmAutostartApp *aapp;
 
         aapp = GSM_AUTOSTART_APP (app);
@@ -497,7 +514,7 @@
 
         if (success) {
                 g_debug ("GsmAutostartApp: started pid:%d", aapp->priv->pid);
-                aapp->priv->child_watch_id = g_child_watch_add ((GPid) aapp->priv->pid,
+                aapp->priv->child_watch_id = g_child_watch_add (aapp->priv->pid,
                                                                 (GChildWatchFunc)app_exited,
                                                                 app);
 
@@ -508,6 +525,29 @@
 }
 
 static gboolean
+gsm_autostart_app_restart (GsmApp  *app,
+                           GError **error)
+{
+        GError  *local_error;
+        gboolean res;
+
+        local_error = NULL;
+        res = gsm_app_stop (app, &local_error);
+        if (! res) {
+                g_propagate_error (error, local_error);
+                return FALSE;
+        }
+
+        res = gsm_app_start (app, &local_error);
+        if (! res) {
+                g_propagate_error (error, local_error);
+                return FALSE;
+        }
+
+        return TRUE;
+}
+
+static gboolean
 gsm_autostart_app_provides (GsmApp     *app,
                             const char *service)
 {
@@ -542,6 +582,30 @@
         return FALSE;
 }
 
+static gboolean
+gsm_autostart_app_get_autorestart (GsmApp *app)
+{
+        gboolean res;
+        gboolean autorestart;
+
+        if (GSM_AUTOSTART_APP (app)->priv->desktop_file == NULL) {
+                return FALSE;
+        }
+
+        autorestart = FALSE;
+
+        res = egg_desktop_file_has_key (GSM_AUTOSTART_APP (app)->priv->desktop_file,
+                                        "X-GNOME-AutoRestart",
+                                        NULL);
+        if (res) {
+                autorestart = egg_desktop_file_get_boolean (GSM_AUTOSTART_APP (app)->priv->desktop_file,
+                                                            "X-GNOME-AutoRestart",
+                                                            NULL);
+        }
+
+        return autorestart;
+}
+
 static const char *
 gsm_autostart_app_get_id (GsmApp *app)
 {
@@ -594,9 +658,12 @@
 
         app_class->is_disabled = is_disabled;
         app_class->is_running = is_running;
-        app_class->start = launch;
+        app_class->start = gsm_autostart_app_start;
+        app_class->restart = gsm_autostart_app_restart;
+        app_class->stop = gsm_autostart_app_stop;
         app_class->provides = gsm_autostart_app_provides;
         app_class->get_id = gsm_autostart_app_get_id;
+        app_class->get_autorestart = gsm_autostart_app_get_autorestart;
 
         g_object_class_install_property (object_class,
                                          PROP_DESKTOP_FILE,

Modified: branches/dbus_based/gnome-session/gsm-client.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-client.c	(original)
+++ branches/dbus_based/gnome-session/gsm-client.c	Wed Jun 18 20:02:37 2008
@@ -242,7 +242,7 @@
                                                            "status",
                                                            -1,
                                                            G_MAXINT,
-                                                           -1,
+                                                           GSM_CLIENT_UNREGISTERED,
                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
 
         g_type_class_add_private (klass, sizeof (GsmClientPrivate));
@@ -273,14 +273,6 @@
         return client->priv->app_id;
 }
 
-gboolean
-gsm_client_get_autorestart (GsmClient *client)
-{
-        g_return_val_if_fail (GSM_IS_CLIENT (client), FALSE);
-
-        return GSM_CLIENT_GET_CLASS (client)->get_autorestart (client);
-}
-
 void
 gsm_client_notify_session_over (GsmClient *client)
 {
@@ -289,16 +281,6 @@
         GSM_CLIENT_GET_CLASS (client)->notify_session_over (client);
 }
 
-
-gboolean
-gsm_client_restart (GsmClient *client,
-                    GError   **error)
-{
-        g_return_val_if_fail (GSM_IS_CLIENT (client), FALSE);
-
-        return GSM_CLIENT_GET_CLASS (client)->restart (client, error);
-}
-
 gboolean
 gsm_client_stop (GsmClient *client,
                  GError   **error)

Modified: branches/dbus_based/gnome-session/gsm-client.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-client.h	(original)
+++ branches/dbus_based/gnome-session/gsm-client.h	Wed Jun 18 20:02:37 2008
@@ -40,8 +40,8 @@
 typedef struct GsmClientPrivate GsmClientPrivate;
 
 typedef enum {
-        GSM_CLIENT_UNMANAGED = 0,
-        GSM_CLIENT_MANAGED,
+        GSM_CLIENT_UNREGISTERED = 0,
+        GSM_CLIENT_REGISTERED,
         GSM_CLIENT_FINISHED,
         GSM_CLIENT_FAILED,
 } GsmClientStatus;
@@ -63,9 +63,6 @@
         void         (*notify_session_over) (GsmClient *client);
         gboolean     (*stop)                (GsmClient *client,
                                              GError   **error);
-        gboolean     (*restart)             (GsmClient *client,
-                                             GError   **error);
-        gboolean     (*get_autorestart)     (GsmClient *client);
 };
 
 GType       gsm_client_get_type             (void) G_GNUC_CONST;
@@ -83,10 +80,6 @@
 
 gboolean    gsm_client_stop                 (GsmClient  *client,
                                              GError    **error);
-gboolean    gsm_client_restart              (GsmClient  *client,
-                                             GError    **error);
-gboolean    gsm_client_get_autorestart      (GsmClient  *client);
-
 
 void        gsm_client_disconnected         (GsmClient  *client);
 

Modified: branches/dbus_based/gnome-session/gsm-dbus-client.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-dbus-client.c	(original)
+++ branches/dbus_based/gnome-session/gsm-dbus-client.c	Wed Jun 18 20:02:37 2008
@@ -70,6 +70,26 @@
 }
 
 static void
+gsm_dbus_client_set_bus_name (GsmDBusClient  *client,
+                              const char     *bus_name)
+{
+        g_return_if_fail (GSM_IS_DBUS_CLIENT (client));
+
+        g_free (client->priv->bus_name);
+
+        client->priv->bus_name = g_strdup (bus_name);
+        g_object_notify (G_OBJECT (client), "bus-name");
+}
+
+const char *
+gsm_dbus_client_get_bus_name (GsmDBusClient  *client)
+{
+        g_return_val_if_fail (GSM_IS_DBUS_CLIENT (client), NULL);
+
+        return client->priv->bus_name;
+}
+
+static void
 gsm_dbus_client_set_property (GObject       *object,
                               guint          prop_id,
                               const GValue  *value,
@@ -80,6 +100,9 @@
         self = GSM_DBUS_CLIENT (object);
 
         switch (prop_id) {
+        case PROP_BUS_NAME:
+                gsm_dbus_client_set_bus_name (self, g_value_get_string (value));
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -97,6 +120,9 @@
         self = GSM_DBUS_CLIENT (object);
 
         switch (prop_id) {
+        case PROP_BUS_NAME:
+                g_value_set_string (value, self->priv->bus_name);
+                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
                 break;
@@ -124,5 +150,13 @@
         object_class->get_property         = gsm_dbus_client_get_property;
         object_class->set_property         = gsm_dbus_client_set_property;
 
+        g_object_class_install_property (object_class,
+                                         PROP_BUS_NAME,
+                                         g_param_spec_string ("bus-name",
+                                                              "bus-name",
+                                                              "bus-name",
+                                                              NULL,
+                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
+
         g_type_class_add_private (klass, sizeof (GsmDBusClientPrivate));
 }

Modified: branches/dbus_based/gnome-session/gsm-dbus-client.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-dbus-client.h	(original)
+++ branches/dbus_based/gnome-session/gsm-dbus-client.h	Wed Jun 18 20:02:37 2008
@@ -51,6 +51,8 @@
 
 GType          gsm_dbus_client_get_type           (void) G_GNUC_CONST;
 
+const char *   gsm_dbus_client_get_bus_name       (GsmDBusClient  *client);
+
 G_END_DECLS
 
 #endif /* __GSM_DBUS_CLIENT_H__ */

Modified: branches/dbus_based/gnome-session/gsm-manager.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-manager.c	(original)
+++ branches/dbus_based/gnome-session/gsm-manager.c	Wed Jun 18 20:02:37 2008
@@ -58,9 +58,8 @@
 
 #define GSM_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GSM_TYPE_MANAGER, GsmManagerPrivate))
 
-#define GSM_DBUS_PATH         "/org/gnome/SessionManager"
-#define GSM_MANAGER_DBUS_PATH GSM_DBUS_PATH
-#define GSM_MANAGER_DBUS_NAME "org.gnome.DisplayManager"
+#define GSM_MANAGER_DBUS_PATH "/org/gnome/SessionManager"
+#define GSM_MANAGER_DBUS_NAME "org.gnome.SessionManager"
 
 #define GSM_MANAGER_PHASE_TIMEOUT 10 /* seconds */
 
@@ -140,6 +139,7 @@
                         ENUM_ENTRY (GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION, "NotInInitialization"),
                         ENUM_ENTRY (GSM_MANAGER_ERROR_NOT_IN_RUNNING, "NotInRunning"),
                         ENUM_ENTRY (GSM_MANAGER_ERROR_ALREADY_REGISTERED, "AlreadyRegistered"),
+                        ENUM_ENTRY (GSM_MANAGER_ERROR_NOT_REGISTERED, "NotRegistered"),
                         { 0, 0, 0 }
                 };
 
@@ -362,26 +362,109 @@
         start_phase (manager);
 }
 
+static GsmApp *
+find_app_for_app_id (GsmManager *manager,
+                     const char *app_id)
+{
+        GsmApp *app;
+        app = g_hash_table_lookup (manager->priv->apps_by_id, app_id);
+        return app;
+}
+
+static void
+disconnect_client (GsmManager *manager,
+                   GsmClient  *client)
+{
+        gboolean    is_condition_client;
+        GsmApp     *app;
+        GError     *error;
+        gboolean    res;
+        const char *app_id;
+
+        g_debug ("GsmManager: disconnect client");
+
+        /* take a ref so it doesn't get finalized */
+        g_object_ref (client);
+
+        gsm_client_store_remove (manager->priv->store, client);
+
+        is_condition_client = FALSE;
+        if (g_slist_find (manager->priv->condition_clients, client)) {
+                manager->priv->condition_clients = g_slist_remove (manager->priv->condition_clients, client);
+
+                is_condition_client = TRUE;
+        }
+
+        app_id = gsm_client_get_app_id (client);
+        if (app_id == NULL) {
+                g_debug ("GsmManager: no application associated with client, not restarting application");
+                goto out;
+        }
+
+        g_debug ("GsmManager: disconnect for app '%s'", app_id);
+        app = find_app_for_app_id (manager, app_id);
+        if (app == NULL) {
+                g_debug ("GsmManager: invalid application id, not restarting application");
+                goto out;
+        }
+
+        if (manager->priv->phase == GSM_MANAGER_PHASE_SHUTDOWN) {
+                g_debug ("GsmManager: in shutdown, not restarting application");
+                goto out;
+        }
+
+        if (! gsm_app_get_autorestart (app)) {
+                g_debug ("GsmManager: autorestart not set, not restarting application");
+                goto out;
+        }
+
+        if (is_condition_client) {
+                g_debug ("GsmManager: app conditionally disabled, not restarting application");
+                goto out;
+        }
+
+        g_debug ("GsmManager: restarting app");
+
+        error = NULL;
+        res = gsm_app_restart (app, &error);
+        if (error != NULL) {
+                g_warning ("Error on restarting session managed app: %s", error->message);
+                g_error_free (error);
+        }
+
+ out:
+        g_object_unref (client);
+
+        if (manager->priv->phase == GSM_MANAGER_PHASE_SHUTDOWN
+            && gsm_client_store_size (manager->priv->store) == 0) {
+                gtk_main_quit ();
+        }
+}
+
 typedef struct {
         const char *service_name;
         GsmManager *manager;
 } RemoveClientData;
 
 static gboolean
-remove_client_for_connection (char             *id,
-                              GsmClient        *client,
-                              RemoveClientData *data)
+_disconnect_dbus_client (const char       *id,
+                         GsmClient        *client,
+                         RemoveClientData *data)
 {
-        g_assert (client != NULL);
-        g_assert (data->service_name != NULL);
+        const char *name;
 
-        /* FIXME: compare service name to that of client */
-#if 0
-        if (strcmp (info->service_name, data->service_name) == 0) {
+        if (! GSM_IS_DBUS_CLIENT (client)) {
+                return FALSE;
+        }
+
+        name = gsm_dbus_client_get_bus_name (GSM_DBUS_CLIENT (client));
+        if (name == NULL) {
+                return FALSE;
+        }
 
-                return TRUE;
+        if (strcmp (data->service_name, name) == 0) {
+                disconnect_client (data->manager, client);
         }
-#endif
 
         return FALSE;
 }
@@ -395,7 +478,10 @@
         data.service_name = service_name;
         data.manager = manager;
 
-        /* FIXME */
+        /* disconnect dbus clients for name */
+        gsm_client_store_foreach (manager->priv->store,
+                                  (GsmClientStoreFunc)_disconnect_dbus_client,
+                                  &data);
 }
 
 static void
@@ -491,43 +577,8 @@
 on_client_disconnected (GsmClient  *client,
                         GsmManager *manager)
 {
-        gboolean is_condition_client = FALSE;
-
-        g_debug ("GsmManager: client disconnected");
-
-        /* take a ref so it doesn't get finalized */
-        g_object_ref (client);
-
-        gsm_client_store_remove (manager->priv->store, client);
-
-        if (g_slist_find (manager->priv->condition_clients, client)) {
-                manager->priv->condition_clients = g_slist_remove (manager->priv->condition_clients, client);
-
-                is_condition_client = TRUE;
-        }
-
-        if (manager->priv->phase != GSM_MANAGER_PHASE_SHUTDOWN
-            && gsm_client_get_autorestart (client)
-            && !is_condition_client) {
-                GError *error = NULL;
-
-                g_debug ("GsmManager: restarting client");
-
-                /* FIXME: need to link to app here too */
-                gsm_client_restart (client, &error);
-
-                if (error != NULL) {
-                        g_warning ("Error on restarting session client: %s", error->message);
-                        g_clear_error (&error);
-                }
-        }
-
-        g_object_unref (client);
-
-        if (manager->priv->phase == GSM_MANAGER_PHASE_SHUTDOWN
-            && gsm_client_store_size (manager->priv->store) == 0) {
-                gtk_main_quit ();
-        }
+        g_debug ("GsmManager: disconnect client");
+        disconnect_client (manager, client);
 }
 
 static GsmApp *
@@ -566,15 +617,6 @@
         return found_app;
 }
 
-static GsmApp *
-find_app_for_app_id (GsmManager *manager,
-                     const char *app_id)
-{
-        GsmApp *app;
-        app = g_hash_table_lookup (manager->priv->apps_by_id, app_id);
-        return app;
-}
-
 static gboolean
 on_xsmp_client_register_request (GsmXSMPClient *client,
                                  char         **id,
@@ -633,6 +675,7 @@
 
         app = find_app_for_client_id (manager, new_id);
         if (app != NULL) {
+                gsm_client_set_app_id (client, gsm_app_get_id (app));
                 gsm_app_registered (app);
                 goto out;
         }
@@ -1605,7 +1648,8 @@
                 return FALSE;
         }
 
-        if (client_startup_id == NULL) {
+        if (client_startup_id == NULL
+            || client_startup_id[0] == '\0') {
                 client_id = gsm_util_generate_client_id ();
         } else {
                 GsmClient *client;
@@ -1632,12 +1676,13 @@
 
         g_debug ("GsmManager: Adding new client %s to session", client_id);
 
-        if (client_startup_id == NULL && app_id == NULL) {
+        if ((client_startup_id == NULL || client_startup_id[0] == '\0')
+            && app_id == NULL) {
                 /* just accept the client - we can't associate with an
                    existing App */
-                g_free (client_id);
                 goto out;
-        } else if (client_startup_id != NULL) {
+        } else if (client_startup_id != NULL
+                   && client_startup_id[0] != '\0') {
                 app = find_app_for_client_id (manager, client_startup_id);
         } else if (app_id != NULL) {
                 /* try to associate this app id with a known app */
@@ -1647,7 +1692,6 @@
         sender = dbus_g_method_get_sender (context);
         client = gsm_method_client_new (client_id, sender);
         g_free (sender);
-        g_free (client_id);
         if (client == NULL) {
                 GError *new_error;
 
@@ -1672,8 +1716,12 @@
                 gsm_client_set_app_id (client, app_id);
         }
 
+        gsm_client_set_status (client, GSM_CLIENT_REGISTERED);
+
  out:
+        g_assert (client_id != NULL);
         dbus_g_method_return (context, client_id);
+        g_free (client_id);
 
         return TRUE;
 }
@@ -1683,20 +1731,35 @@
                                const char            *session_client_id,
                                DBusGMethodInvocation *context)
 {
+        GsmClient *client;
+
         g_debug ("GsmManager: UnregisterClient %s", session_client_id);
-        if (1) {
+
+        client = gsm_client_store_find (manager->priv->store,
+                                        (GsmClientStoreFunc)_client_has_client_id,
+                                        (char *)session_client_id);
+
+        if (client == NULL) {
                 GError *new_error;
 
-                g_debug ("Unable to unregister client");
+                g_debug ("Unable to unregister client: not registered");
 
                 new_error = g_error_new (GSM_MANAGER_ERROR,
-                                         GSM_MANAGER_ERROR_GENERAL,
+                                         GSM_MANAGER_ERROR_NOT_REGISTERED,
                                          "Unable to unregister client");
                 dbus_g_method_return_error (context, new_error);
                 g_error_free (new_error);
+                return FALSE;
         }
 
-        return FALSE;
+
+        /* don't disconnect client here, only change the status.
+           Wait until it leaves the bus before disconnecting it */
+        gsm_client_set_status (client, GSM_CLIENT_UNREGISTERED);
+
+        dbus_g_method_return (context);
+
+        return TRUE;
 }
 
 gboolean

Modified: branches/dbus_based/gnome-session/gsm-manager.h
==============================================================================
--- branches/dbus_based/gnome-session/gsm-manager.h	(original)
+++ branches/dbus_based/gnome-session/gsm-manager.h	Wed Jun 18 20:02:37 2008
@@ -86,6 +86,7 @@
         GSM_MANAGER_ERROR_NOT_IN_INITIALIZATION,
         GSM_MANAGER_ERROR_NOT_IN_RUNNING,
         GSM_MANAGER_ERROR_ALREADY_REGISTERED,
+        GSM_MANAGER_ERROR_NOT_REGISTERED,
         GSM_MANAGER_NUM_ERRORS
 } GsmManagerError;
 

Modified: branches/dbus_based/gnome-session/gsm-manager.xml
==============================================================================
--- branches/dbus_based/gnome-session/gsm-manager.xml	(original)
+++ branches/dbus_based/gnome-session/gsm-manager.xml	Wed Jun 18 20:02:37 2008
@@ -23,6 +23,7 @@
       <arg type="s" name="session_client_id" direction="out"/>
     </method>
     <method name="UnregisterClient">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
       <arg type="s" name="session_client_id" direction="in"/>
     </method>
 
@@ -33,6 +34,7 @@
       <arg type="u" name="inhibit_cookie" direction="out"/>
     </method>
     <method name="Uninhibit">
+      <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
       <arg type="u" name="inhibit_cookie" direction="in"/>
     </method>
 

Modified: branches/dbus_based/gnome-session/gsm-method-client.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-method-client.c	(original)
+++ branches/dbus_based/gnome-session/gsm-method-client.c	Wed Jun 18 20:02:37 2008
@@ -37,6 +37,7 @@
 
 struct GsmMethodClientPrivate
 {
+        gpointer dummy;
 };
 
 enum {
@@ -114,13 +115,6 @@
         return FALSE;
 }
 
-static gboolean
-gsm_method_client_restart (GsmClient *client,
-                           GError   **error)
-{
-        return FALSE;
-}
-
 static void
 gsm_method_client_class_init (GsmMethodClientClass *klass)
 {
@@ -133,7 +127,6 @@
         object_class->set_property         = gsm_method_client_set_property;
 
         client_class->stop                 = gsm_method_client_stop;
-        client_class->restart              = gsm_method_client_restart;
 
         g_type_class_add_private (klass, sizeof (GsmMethodClientPrivate));
 }

Modified: branches/dbus_based/gnome-session/gsm-resumed-app.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-resumed-app.c	(original)
+++ branches/dbus_based/gnome-session/gsm-resumed-app.c	Wed Jun 18 20:02:37 2008
@@ -23,6 +23,9 @@
 #include <config.h>
 #endif
 
+#include <sys/wait.h>
+#include <glib.h>
+
 #include <X11/SM/SMlib.h>
 
 #include "gsm-resumed-app.h"
@@ -35,6 +38,8 @@
         char    *restart_command;
         char    *discard_command;
         gboolean discard_on_resume;
+        GPid     pid;
+        guint    child_watch_id;
 };
 
 G_DEFINE_TYPE (GsmResumedApp, gsm_resumed_app, GSM_TYPE_APP)
@@ -45,9 +50,34 @@
         app->priv = GSM_RESUMED_APP_GET_PRIVATE (app);
 }
 
+static void
+app_exited (GPid           pid,
+            int            status,
+            GsmResumedApp *app)
+{
+        g_debug ("GsmResumedApp: (pid:%d) done (%s:%d)",
+                 (int) pid,
+                 WIFEXITED (status) ? "status"
+                 : WIFSIGNALED (status) ? "signal"
+                 : "unknown",
+                 WIFEXITED (status) ? WEXITSTATUS (status)
+                 : WIFSIGNALED (status) ? WTERMSIG (status)
+                 : -1);
+
+        g_spawn_close_pid (app->priv->pid);
+        app->priv->pid = -1;
+        app->priv->child_watch_id = 0;
+
+        if (WIFEXITED (status)) {
+                gsm_app_exited (GSM_APP (app));
+        } else if (WIFSIGNALED (status)) {
+                gsm_app_died (GSM_APP (app));
+        }
+}
+
 static gboolean
-launch (GsmApp  *app,
-        GError **err)
+gsm_resumed_app_start (GsmApp  *app,
+                       GError **error)
 {
         const char *restart_command;
         int         argc;
@@ -55,14 +85,17 @@
         gboolean    success;
         gboolean    res;
         pid_t       pid;
+        GsmResumedApp *rapp;
+
+        rapp = GSM_RESUMED_APP (app);
 
-        restart_command = GSM_RESUMED_APP (app)->priv->restart_command;
+        restart_command = rapp->priv->restart_command;
 
         if (restart_command == NULL) {
                 return FALSE;
         }
 
-        res = g_shell_parse_argv (restart_command, &argc, &argv, err);
+        res = g_shell_parse_argv (restart_command, &argc, &argv, error);
         if (!res) {
                 return FALSE;
         }
@@ -82,12 +115,43 @@
                                  NULL,
                                  NULL,
                                  &pid,
-                                 err);
+                                 error);
         g_strfreev (argv);
 
+        if (success) {
+                g_debug ("GsmResumedApp: started pid:%d",
+                         rapp->priv->pid);
+                rapp->priv->child_watch_id = g_child_watch_add (rapp->priv->pid,
+                                                                (GChildWatchFunc)app_exited,
+                                                                app);
+        }
+
         return success;
 }
 
+static gboolean
+gsm_resumed_app_restart (GsmApp  *app,
+                         GError **error)
+{
+        GError  *local_error;
+        gboolean res;
+
+        local_error = NULL;
+        res = gsm_app_stop (app, &local_error);
+        if (! res) {
+                g_propagate_error (error, local_error);
+                return FALSE;
+        }
+
+        res = gsm_app_start (app, &local_error);
+        if (! res) {
+                g_propagate_error (error, local_error);
+                return FALSE;
+        }
+
+        return TRUE;
+}
+
 static const char *
 gsm_resumed_app_get_id (GsmApp *app)
 {
@@ -95,12 +159,36 @@
 }
 
 static void
+gsm_resumed_app_dispose (GObject *object)
+{
+        GsmResumedAppPrivate *priv;
+
+        priv = GSM_RESUMED_APP (object)->priv;
+
+        g_free (priv->program);
+        priv->program = NULL;
+        g_free (priv->restart_command);
+        priv->restart_command = NULL;
+        g_free (priv->discard_command);
+        priv->discard_command = NULL;
+
+        if (priv->child_watch_id > 0) {
+                g_source_remove (priv->child_watch_id);
+                priv->child_watch_id = 0;
+        }
+}
+
+static void
 gsm_resumed_app_class_init (GsmResumedAppClass *klass)
 {
-        GsmAppClass *app_class = GSM_APP_CLASS (klass);
+        GObjectClass *object_class = G_OBJECT_CLASS (klass);
+        GsmAppClass  *app_class = GSM_APP_CLASS (klass);
+
+        object_class->dispose = gsm_resumed_app_dispose;
 
         app_class->get_id = gsm_resumed_app_get_id;
-        app_class->start = launch;
+        app_class->start = gsm_resumed_app_start;
+        app_class->restart = gsm_resumed_app_restart;
 
         g_type_class_add_private (klass, sizeof (GsmResumedAppPrivate));
 }

Modified: branches/dbus_based/gnome-session/gsm-service-client.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-service-client.c	(original)
+++ branches/dbus_based/gnome-session/gsm-service-client.c	Wed Jun 18 20:02:37 2008
@@ -114,13 +114,6 @@
         return FALSE;
 }
 
-static gboolean
-gsm_service_client_restart (GsmClient *client,
-                            GError   **error)
-{
-        return FALSE;
-}
-
 static void
 gsm_service_client_class_init (GsmServiceClientClass *klass)
 {
@@ -133,7 +126,6 @@
         object_class->set_property         = gsm_service_client_set_property;
 
         client_class->stop                 = gsm_service_client_stop;
-        client_class->restart              = gsm_service_client_restart;
 
         g_type_class_add_private (klass, sizeof (GsmServiceClientPrivate));
 }

Modified: branches/dbus_based/gnome-session/gsm-xsmp-client.c
==============================================================================
--- branches/dbus_based/gnome-session/gsm-xsmp-client.c	(original)
+++ branches/dbus_based/gnome-session/gsm-xsmp-client.c	Wed Jun 18 20:02:37 2008
@@ -632,9 +632,7 @@
         object_class->get_property         = gsm_xsmp_client_get_property;
         object_class->set_property         = gsm_xsmp_client_set_property;
 
-        client_class->get_autorestart      = xsmp_get_autorestart;
         client_class->stop                 = xsmp_stop;
-        client_class->restart              = xsmp_restart;
 
         signals[REGISTER_REQUEST] =
                 g_signal_new ("register-request",
@@ -783,7 +781,7 @@
                 free (previous_id);
         }
 
-        gsm_client_set_status (GSM_CLIENT (client), GSM_CLIENT_MANAGED);
+        gsm_client_set_status (GSM_CLIENT (client), GSM_CLIENT_REGISTERED);
 
         return TRUE;
 }

Added: branches/dbus_based/gnome-session/test-client-method.c
==============================================================================
--- (empty file)
+++ branches/dbus_based/gnome-session/test-client-method.c	Wed Jun 18 20:02:37 2008
@@ -0,0 +1,160 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+
+#define SM_DBUS_NAME      "org.gnome.SessionManager"
+#define SM_DBUS_PATH      "/org/gnome/SessionManager"
+#define SM_DBUS_INTERFACE "org.gnome.SessionManager"
+
+static DBusGConnection *bus_connection = NULL;
+static DBusGProxy      *sm_proxy = NULL;
+static char            *client_id = NULL;
+
+static gboolean
+session_manager_connect (void)
+{
+
+        if (bus_connection == NULL) {
+                GError *error;
+
+                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);
+                        exit (1);
+                }
+        }
+
+        sm_proxy = dbus_g_proxy_new_for_name (bus_connection,
+                                              SM_DBUS_NAME,
+                                              SM_DBUS_PATH,
+                                              SM_DBUS_INTERFACE);
+        return (sm_proxy != NULL);
+}
+
+#define NO_NULLS(x) (
+
+static gboolean
+register_client (void)
+{
+        GError     *error;
+        gboolean    res;
+        const char *startup_id;
+        const char *app_id;
+
+        startup_id = g_getenv ("DESKTOP_AUTOSTART_ID");
+        app_id = "test-client-method";
+
+        error = NULL;
+        res = dbus_g_proxy_call (sm_proxy,
+                                 "RegisterClient",
+                                 &error,
+                                 G_TYPE_STRING, startup_id,
+                                 G_TYPE_STRING, app_id,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_STRING, &client_id,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                g_warning ("Failed to register client: %s", error->message);
+                g_error_free (error);
+                return FALSE;
+        }
+
+        g_debug ("Client registered with session manager: %s", client_id);
+
+        return TRUE;
+}
+
+static gboolean
+session_manager_disconnect (void)
+{
+        if (sm_proxy != NULL) {
+                g_object_unref (sm_proxy);
+                sm_proxy = NULL;
+        }
+
+        return TRUE;
+}
+
+static gboolean
+unregister_client (void)
+{
+        GError  *error;
+        gboolean res;
+
+        error = NULL;
+        res = dbus_g_proxy_call (sm_proxy,
+                                 "UnregisterClient",
+                                 &error,
+                                 G_TYPE_STRING, client_id,
+                                 G_TYPE_INVALID,
+                                 G_TYPE_INVALID);
+        if (! res) {
+                g_warning ("Failed to unregister client: %s", error->message);
+                g_error_free (error);
+                return FALSE;
+        }
+
+        g_free (client_id);
+        client_id = NULL;
+
+        return TRUE;
+}
+
+int
+main (int   argc,
+      char *argv[])
+{
+        gboolean res;
+
+        g_log_set_always_fatal (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING);
+
+        g_type_init ();
+
+        res = session_manager_connect ();
+        if (! res) {
+                g_warning ("Unable to connect to session manager");
+                exit (1);
+        }
+
+        res = register_client ();
+        if (! res) {
+                g_warning ("Unable to register client with session manager");
+        }
+
+        sleep (30);
+
+        unregister_client ();
+        session_manager_disconnect ();
+
+        return 0;
+}



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