[gdm/session-selection-again: 6/11] session: support new accountsservice Session and SessionType props




commit 8ca580107c4536b0a9fc21fb910da861a9e49f9a
Author: Ray Strode <rstrode redhat com>
Date:   Tue Aug 14 14:52:41 2018 -0400

    session: support new accountsservice Session and SessionType props
    
    At the moment the user's session is stored in a property called
    "XSession".  This is pretty weird if the user is using wayland.
    
    AccountService now supports a more generic property "Session" and
    a related "SessionType" property to replace "XSession".
    
    This commit switches GDM over to use the new properties.

 daemon/gdm-session-settings.c | 61 ++++++++++++++++++++++++++++---
 daemon/gdm-session-settings.h |  3 ++
 daemon/gdm-session-worker.c   | 28 ++++++++++++++
 daemon/gdm-session-worker.xml |  3 ++
 daemon/gdm-session.c          | 85 +++++++++++++++++++++++++++++++------------
 5 files changed, 152 insertions(+), 28 deletions(-)
---
diff --git a/daemon/gdm-session-settings.c b/daemon/gdm-session-settings.c
index 484a3b5b4..5b64cb65b 100644
--- a/daemon/gdm-session-settings.c
+++ b/daemon/gdm-session-settings.c
@@ -39,6 +39,7 @@ struct _GdmSessionSettingsPrivate
         ActUserManager *user_manager;
         ActUser *user;
         char *session_name;
+        char *session_type;
         char *language_name;
 };
 
@@ -58,6 +59,7 @@ static void gdm_session_settings_get_property (GObject      *object,
 enum {
         PROP_0 = 0,
         PROP_SESSION_NAME,
+        PROP_SESSION_TYPE,
         PROP_LANGUAGE_NAME,
         PROP_IS_LOADED
 };
@@ -93,6 +95,11 @@ gdm_session_settings_class_install_properties (GdmSessionSettingsClass *settings
                                         NULL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
         g_object_class_install_property (object_class, PROP_SESSION_NAME, param_spec);
 
+        param_spec = g_param_spec_string ("session-type", "Session Type",
+                                          "The type of the session",
+                                          NULL, G_PARAM_READWRITE);
+        g_object_class_install_property (object_class, PROP_SESSION_TYPE, param_spec);
+
         param_spec = g_param_spec_string ("language-name", "Language Name",
                                         "The name of the language",
                                         NULL,
@@ -163,6 +170,19 @@ gdm_session_settings_set_session_name (GdmSessionSettings *settings,
         }
 }
 
+void
+gdm_session_settings_set_session_type (GdmSessionSettings *settings,
+                                       const char         *session_type)
+{
+        g_return_if_fail (GDM_IS_SESSION_SETTINGS (settings));
+
+        if (settings->priv->session_type == NULL ||
+            g_strcmp0 (settings->priv->session_type, session_type) != 0) {
+                settings->priv->session_type = g_strdup (session_type);
+                g_object_notify (G_OBJECT (settings), "session-type");
+        }
+}
+
 char *
 gdm_session_settings_get_language_name (GdmSessionSettings *settings)
 {
@@ -177,6 +197,13 @@ gdm_session_settings_get_session_name (GdmSessionSettings *settings)
         return g_strdup (settings->priv->session_name);
 }
 
+char *
+gdm_session_settings_get_session_type (GdmSessionSettings *settings)
+{
+        g_return_val_if_fail (GDM_IS_SESSION_SETTINGS (settings), NULL);
+        return g_strdup (settings->priv->session_type);
+}
+
 static void
 gdm_session_settings_set_property (GObject      *object,
                                   guint         prop_id,
@@ -196,6 +223,10 @@ gdm_session_settings_set_property (GObject      *object,
                         gdm_session_settings_set_session_name (settings, g_value_get_string (value));
                 break;
 
+                case PROP_SESSION_TYPE:
+                        gdm_session_settings_set_session_type (settings, g_value_get_string (value));
+                break;
+
                 default:
                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         }
@@ -216,6 +247,10 @@ gdm_session_settings_get_property (GObject    *object,
                         g_value_set_string (value, settings->priv->session_name);
                 break;
 
+                case PROP_SESSION_TYPE:
+                        g_value_set_string (value, settings->priv->session_type);
+                break;
+
                 case PROP_LANGUAGE_NAME:
                         g_value_set_string (value, settings->priv->language_name);
                 break;
@@ -254,6 +289,7 @@ static void
 load_settings_from_user (GdmSessionSettings *settings)
 {
         const char *session_name;
+        const char *session_type;
         const char *language_name;
 
         if (!act_user_is_loaded (settings->priv->user)) {
@@ -261,20 +297,31 @@ load_settings_from_user (GdmSessionSettings *settings)
                 return;
         }
 
-        session_name = act_user_get_x_session (settings->priv->user);
-        g_debug ("GdmSessionSettings: saved session is %s", session_name);
+        /* if the user doesn't have saved state, they don't have any settings worth reading */
+        if (!act_user_get_saved (settings->priv->user))
+                goto out;
+
+        session_type = act_user_get_session_type (settings->priv->user);
+        session_name = act_user_get_session (settings->priv->user);
 
-        if (session_name != NULL) {
+        g_debug ("GdmSessionSettings: saved session is %s (type %s)", session_name, session_type);
+
+        if (session_type != NULL && session_type[0] != '\0') {
+                gdm_session_settings_set_session_type (settings, session_type);
+        }
+
+        if (session_name != NULL && session_name[0] != '\0') {
                 gdm_session_settings_set_session_name (settings, session_name);
         }
 
         language_name = act_user_get_language (settings->priv->user);
 
         g_debug ("GdmSessionSettings: saved language is %s", language_name);
-        if (language_name != NULL) {
+        if (language_name != NULL && language_name[0] != '\0') {
                 gdm_session_settings_set_language_name (settings, language_name);
         }
 
+out:
         g_object_notify (G_OBJECT (settings), "is-loaded");
 }
 
@@ -349,7 +396,11 @@ gdm_session_settings_save (GdmSessionSettings  *settings,
         }
 
         if (settings->priv->session_name != NULL) {
-                act_user_set_x_session (user, settings->priv->session_name);
+                act_user_set_session (user, settings->priv->session_name);
+        }
+
+        if (settings->priv->session_type != NULL) {
+                act_user_set_session_type (user, settings->priv->session_type);
         }
 
         if (settings->priv->language_name != NULL) {
diff --git a/daemon/gdm-session-settings.h b/daemon/gdm-session-settings.h
index 20946bff1..db38ffc72 100644
--- a/daemon/gdm-session-settings.h
+++ b/daemon/gdm-session-settings.h
@@ -60,10 +60,13 @@ gboolean            gdm_session_settings_save               (GdmSessionSettings
 gboolean            gdm_session_settings_is_loaded          (GdmSessionSettings  *settings);
 char               *gdm_session_settings_get_language_name  (GdmSessionSettings *settings);
 char               *gdm_session_settings_get_session_name   (GdmSessionSettings *settings);
+char               *gdm_session_settings_get_session_type   (GdmSessionSettings *settings);
 void                gdm_session_settings_set_language_name  (GdmSessionSettings *settings,
                                                              const char         *language_name);
 void                gdm_session_settings_set_session_name   (GdmSessionSettings *settings,
                                                              const char         *session_name);
+void                gdm_session_settings_set_session_type   (GdmSessionSettings *settings,
+                                                             const char         *session_type);
 
 G_END_DECLS
 #endif /* GDM_SESSION_SETTINGS_H */
diff --git a/daemon/gdm-session-worker.c b/daemon/gdm-session-worker.c
index 6e307ac60..7d7d2496e 100644
--- a/daemon/gdm-session-worker.c
+++ b/daemon/gdm-session-worker.c
@@ -2583,6 +2583,20 @@ on_saved_session_name_read (GdmSessionWorker *worker)
         g_free (session_name);
 }
 
+static void
+on_saved_session_type_read (GdmSessionWorker *worker)
+{
+        char *session_type;
+
+        session_type = gdm_session_settings_get_session_type (worker->priv->user_settings);
+
+        g_debug ("GdmSessionWorker: Saved session type is %s", session_type);
+        gdm_dbus_worker_emit_saved_session_type_read (GDM_DBUS_WORKER (worker),
+                                                      session_type);
+        g_free (session_type);
+}
+
+
 static void
 do_setup (GdmSessionWorker *worker)
 {
@@ -3046,6 +3060,11 @@ gdm_session_worker_handle_initialize (GdmDBusWorker         *object,
                                           G_CALLBACK (on_saved_session_name_read),
                                           worker);
 
+                g_signal_connect_swapped (worker->priv->user_settings,
+                                          "notify::session-type",
+                                          G_CALLBACK (on_saved_session_type_read),
+                                          worker);
+
                 if (worker->priv->username) {
                         wait_for_settings = !gdm_session_settings_load (worker->priv->user_settings,
                                                                         worker->priv->username);
@@ -3102,6 +3121,11 @@ gdm_session_worker_handle_setup (GdmDBusWorker         *object,
                                   "notify::session-name",
                                   G_CALLBACK (on_saved_session_name_read),
                                   worker);
+        g_signal_connect_swapped (worker->priv->user_settings,
+                                  "notify::session-type",
+                                  G_CALLBACK (on_saved_session_type_read),
+                                  worker);
+
         return TRUE;
 }
 
@@ -3144,6 +3168,10 @@ gdm_session_worker_handle_setup_for_user (GdmDBusWorker         *object,
                                   "notify::session-name",
                                   G_CALLBACK (on_saved_session_name_read),
                                   worker);
+        g_signal_connect_swapped (worker->priv->user_settings,
+                                  "notify::session-type",
+                                  G_CALLBACK (on_saved_session_type_read),
+                                  worker);
 
         /* Load settings from accounts daemon before continuing
          */
diff --git a/daemon/gdm-session-worker.xml b/daemon/gdm-session-worker.xml
index 4280fe095..a215779c8 100644
--- a/daemon/gdm-session-worker.xml
+++ b/daemon/gdm-session-worker.xml
@@ -78,6 +78,9 @@
     <signal name="SavedSessionNameRead">
       <arg name="session_name" type="s"/>
     </signal>
+    <signal name="SavedSessionTypeRead">
+      <arg name="session_type" type="s"/>
+    </signal>
     <signal name="UsernameChanged">
       <arg name="new_username" type="s"/>
     </signal>
diff --git a/daemon/gdm-session.c b/daemon/gdm-session.c
index ce49a8df4..dcdbb40a6 100644
--- a/daemon/gdm-session.c
+++ b/daemon/gdm-session.c
@@ -88,6 +88,7 @@ struct _GdmSession
         char                *selected_program;
         char                *selected_session;
         char                *saved_session;
+        char                *saved_session_type;
         char                *saved_language;
         char                *selected_user;
         char                *user_x11_authority_file;
@@ -355,7 +356,8 @@ supports_session_type (GdmSession *self,
 }
 
 static char **
-get_system_session_dirs (GdmSession *self)
+get_system_session_dirs (GdmSession *self,
+                         const char *type)
 {
         GArray *search_array = NULL;
         char **search_dirs;
@@ -376,7 +378,8 @@ get_system_session_dirs (GdmSession *self)
         for (j = 0; self->supported_session_types[j] != NULL; j++) {
                 const char *supported_type = self->supported_session_types[j];
 
-                if (g_str_equal (supported_type, "x11")) {
+                if (g_str_equal (supported_type, "x11") ||
+                    (type == NULL || g_str_equal (type, supported_type))) {
                         for (i = 0; system_data_dirs[i]; i++) {
                                 gchar *dir = g_build_filename (system_data_dirs[i], "xsessions", NULL);
                                 g_array_append_val (search_array, dir);
@@ -386,13 +389,14 @@ get_system_session_dirs (GdmSession *self)
                 }
 
 #ifdef ENABLE_WAYLAND_SUPPORT
-                if (g_str_equal (supported_type, "wayland")) {
-                        g_array_prepend_val (search_array, wayland_search_dir);
-
+                if (g_str_equal (supported_type, "wayland") ||
+                    (type == NULL || g_str_equal (type, supported_type))) {
                         for (i = 0; system_data_dirs[i]; i++) {
                                 gchar *dir = g_build_filename (system_data_dirs[i], "wayland-sessions", 
NULL);
                                 g_array_append_val (search_array, dir);
                         }
+
+                        g_array_append_val (search_array, wayland_search_dir);
                 }
 #endif
         }
@@ -419,16 +423,18 @@ is_prog_in_path (const char *prog)
 static GKeyFile *
 load_key_file_for_file (GdmSession   *self,
                         const char   *file,
+                        const char   *type,
                         char        **full_path)
 {
         GKeyFile   *key_file;
-        GError     *error;
+        GError     *error = NULL;
         gboolean    res;
         char      **search_dirs;
 
         key_file = g_key_file_new ();
 
-        search_dirs = get_system_session_dirs (self),
+        search_dirs = get_system_session_dirs (self, type);
+
         error = NULL;
         res = g_key_file_load_from_dirs (key_file,
                                          file,
@@ -437,8 +443,11 @@ load_key_file_for_file (GdmSession   *self,
                                          G_KEY_FILE_NONE,
                                          &error);
         if (! res) {
-                g_debug ("GdmSession: File '%s' not found: %s", file, error->message);
-                g_error_free (error);
+                g_debug ("GdmSession: File '%s' not found in search dirs", file);
+                if (error != NULL) {
+                        g_debug ("GdmSession: %s", error->message);
+                        g_error_free (error);
+                }
                 g_key_file_free (key_file);
                 key_file = NULL;
         }
@@ -451,6 +460,7 @@ load_key_file_for_file (GdmSession   *self,
 static gboolean
 get_session_command_for_file (GdmSession  *self,
                               const char  *file,
+                              const char  *type,
                               char       **command)
 {
         GKeyFile   *key_file;
@@ -465,8 +475,14 @@ get_session_command_for_file (GdmSession  *self,
                 *command = NULL;
         }
 
+        if (!supports_session_type (self, type)) {
+                g_debug ("GdmSession: ignoring %s session command request for file '%s'",
+                         type, file);
+                goto out;
+        }
+
         g_debug ("GdmSession: getting session command for file '%s'", file);
-        key_file = load_key_file_for_file (self, file, NULL);
+        key_file = load_key_file_for_file (self, file, type, NULL);
         if (key_file == NULL) {
                 goto out;
         }
@@ -524,13 +540,14 @@ out:
 static gboolean
 get_session_command_for_name (GdmSession  *self,
                               const char  *name,
+                              const char  *type,
                               char       **command)
 {
         gboolean res;
         char    *filename;
 
         filename = g_strdup_printf ("%s.desktop", name);
-        res = get_session_command_for_file (self, filename, command);
+        res = get_session_command_for_file (self, filename, type, command);
         g_free (filename);
 
         return res;
@@ -566,13 +583,13 @@ get_fallback_session_name (GdmSession *self)
 
         if (self->fallback_session_name != NULL) {
                 /* verify that the cached version still exists */
-                if (get_session_command_for_name (self, self->fallback_session_name, NULL)) {
+                if (get_session_command_for_name (self, self->fallback_session_name, NULL, NULL)) {
                         goto out;
                 }
         }
 
         name = g_strdup ("gnome");
-        if (get_session_command_for_name (self, name, NULL)) {
+        if (get_session_command_for_name (self, name, NULL, NULL)) {
                 g_free (self->fallback_session_name);
                 self->fallback_session_name = name;
                 goto out;
@@ -581,7 +598,7 @@ get_fallback_session_name (GdmSession *self)
 
         sessions = g_sequence_new (g_free);
 
-        search_dirs = get_system_session_dirs (self);
+        search_dirs = get_system_session_dirs (self, NULL);
         for (i = 0; search_dirs[i] != NULL; i++) {
                 GDir       *dir;
                 const char *base_name;
@@ -603,7 +620,7 @@ get_fallback_session_name (GdmSession *self)
                                 continue;
                         }
 
-                        if (get_session_command_for_file (self, base_name, NULL)) {
+                        if (get_session_command_for_file (self, base_name, NULL, NULL)) {
                                 name = g_strndup (base_name, strlen (base_name) - strlen (".desktop"));
                                 g_sequence_insert_sorted (sessions, name, (GCompareDataFunc) g_strcmp0, 
NULL);
                         }
@@ -676,6 +693,9 @@ gdm_session_select_user (GdmSession *self,
         g_free (self->saved_session);
         self->saved_session = NULL;
 
+        g_free (self->saved_session_type);
+        self->saved_session_type = NULL;
+
         g_free (self->saved_language);
         self->saved_language = NULL;
 }
@@ -996,7 +1016,7 @@ worker_on_saved_session_name_read (GdmDBusWorker          *worker,
 {
         GdmSession *self = conversation->session;
 
-        if (! get_session_command_for_name (self, session_name, NULL)) {
+        if (! get_session_command_for_name (self, session_name, self->saved_session_type, NULL)) {
                 /* ignore sessions that don't exist */
                 g_debug ("GdmSession: not using invalid .dmrc session: %s", session_name);
                 g_free (self->saved_session);
@@ -1016,6 +1036,17 @@ worker_on_saved_session_name_read (GdmDBusWorker          *worker,
 
 }
 
+static void
+worker_on_saved_session_type_read (GdmDBusWorker          *worker,
+                                   const char             *session_type,
+                                   GdmSessionConversation *conversation)
+{
+        GdmSession *self = conversation->session;
+
+        g_free (self->saved_session_type);
+        self->saved_session_type = g_strdup (session_type);
+}
+
 static GdmSessionConversation *
 find_conversation_by_pid (GdmSession *self,
                           GPid        pid)
@@ -1149,6 +1180,9 @@ register_worker (GdmDBusWorkerManager  *worker_manager_interface,
         g_signal_connect (conversation->worker_proxy,
                           "saved-session-name-read",
                           G_CALLBACK (worker_on_saved_session_name_read), conversation);
+        g_signal_connect (conversation->worker_proxy,
+                          "saved-session-type-read",
+                          G_CALLBACK (worker_on_saved_session_type_read), conversation);
         g_signal_connect (conversation->worker_proxy,
                           "cancel-pending-query",
                           G_CALLBACK (worker_on_cancel_pending_query), conversation);
@@ -1945,6 +1979,9 @@ free_conversation (GdmSessionConversation *conversation)
                 g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
                                                       G_CALLBACK (worker_on_saved_session_name_read),
                                                       conversation);
+                g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
+                                                      G_CALLBACK (worker_on_saved_session_type_read),
+                                                      conversation);
                 g_signal_handlers_disconnect_by_func (conversation->worker_proxy,
                                                       G_CALLBACK (worker_on_cancel_pending_query),
                                                       conversation);
@@ -2557,7 +2594,7 @@ get_session_command (GdmSession *self)
         session_name = get_session_name (self);
 
         command = NULL;
-        res = get_session_command_for_name (self, session_name, &command);
+        res = get_session_command_for_name (self, session_name, NULL, &command);
         if (! res) {
                 g_critical ("Cannot find a command for specified session: %s", session_name);
                 exit (EXIT_FAILURE);
@@ -2579,7 +2616,7 @@ get_session_desktop_names (GdmSession *self)
 
         filename = g_strdup_printf ("%s.desktop", get_session_name (self));
         g_debug ("GdmSession: getting desktop names for file '%s'", filename);
-        keyfile = load_key_file_for_file (self, filename, NULL);
+        keyfile = load_key_file_for_file (self, filename, NULL, NULL);
         if (keyfile != NULL) {
               gchar **names;
 
@@ -3175,7 +3212,7 @@ gdm_session_is_wayland_session (GdmSession *self)
         filename = get_session_filename (self);
 
         if (supports_session_type (self, "wayland")) {
-               key_file = load_key_file_for_file (self, filename, &full_path);
+               key_file = load_key_file_for_file (self, filename, "wayland", &full_path);
 
                if (key_file == NULL) {
                        goto out;
@@ -3198,9 +3235,11 @@ static void
 update_session_type (GdmSession *self)
 {
 #ifdef ENABLE_WAYLAND_SUPPORT
-        gboolean is_wayland_session;
+        gboolean is_wayland_session = FALSE;
+
+        if (supports_session_type (self, "wayland"))
+                is_wayland_session = gdm_session_is_wayland_session (self);
 
-        is_wayland_session = gdm_session_is_wayland_session (self);
         if (is_wayland_session) {
                 set_session_type (self, "wayland");
         } else {
@@ -3222,7 +3261,7 @@ gdm_session_session_registers (GdmSession *self)
 
         filename = get_session_filename (self);
 
-        key_file = load_key_file_for_file (self, filename, NULL);
+        key_file = load_key_file_for_file (self, filename, NULL, NULL);
 
         session_registers = g_key_file_get_boolean (key_file,
                                                     G_KEY_FILE_DESKTOP_GROUP,
@@ -3262,7 +3301,7 @@ gdm_session_bypasses_xsession (GdmSession *self)
 
         filename = get_session_filename (self);
 
-        key_file = load_key_file_for_file (self, filename, NULL);
+        key_file = load_key_file_for_file (self, filename, "x11",  NULL);
 
         error = NULL;
         res = g_key_file_has_key (key_file, G_KEY_FILE_DESKTOP_GROUP, "X-GDM-BypassXsession", NULL);


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