[Spice-devel] [vdagent-linux v2 3/5] console-kit: implement check for locked session

Jonathon Jongsma jjongsma at redhat.com
Wed Apr 27 21:47:23 UTC 2016


On Sat, 2016-04-23 at 12:53 +0200, Victor Toso wrote:
> We register to read the Lock, Unlock and IdleHintChanged signals from
> ConsoleKit.Session. The Lock/Unlock signals should be the right signals for
> the
> job but not all Desktop Managers implement its locking in a way that trigger
> those signals. That's why we double-check with IdleHintChanged signal that it
> might be triggered by other services like screen savers.
> ---
>  src/console-kit.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
> -
>  1 file changed, 81 insertions(+), 4 deletions(-)
> 
> diff --git a/src/console-kit.c b/src/console-kit.c
> index 9662d3d..748a6bc 100644
> --- a/src/console-kit.c
> +++ b/src/console-kit.c
> @@ -35,6 +35,9 @@ struct session_info {
>      char *active_session;
>      int verbose;
>      gchar *match_seat_signals;
> +    gchar *match_session_signals;
> +    gboolean session_is_locked;
> +    gboolean session_idle_hint;
>  };
>  
>  #define INTERFACE_CONSOLE_KIT "org.freedesktop.ConsoleKit"
> @@ -45,8 +48,15 @@ struct session_info {
>  
>  #define INTERFACE_CK_SEAT       INTERFACE_CONSOLE_KIT ".Seat"
>  
> +#define INTERFACE_CK_SESSION    INTERFACE_CONSOLE_KIT ".Session"
> +#define OBJ_PATH_CK_SESSION     OBJ_PATH_CONSOLE_KIT "/Session"
> +
>  #define CK_SEAT_SIGNAL_ACTIVE_SESSION_CHANGED       "ActiveSessionChanged"
>  
> +#define CK_SESSION_SIGNAL_LOCK                      "Lock"
> +#define CK_SESSION_SIGNAL_UNLOCK                    "Unlock"
> +#define CK_SESSION_SIGNAL_IDLE_HINT_CHANGED         "IdleHintChanged"
> +
>  static char *console_kit_get_first_seat(struct session_info *si);
>  static char *console_kit_check_active_session_change(struct session_info
> *si);
>  
> @@ -63,6 +73,18 @@ static void si_dbus_match_remove(struct session_info *si)
>                     si->match_seat_signals);
>          g_free(si->match_seat_signals);
>      }
> +
> +    if (si->match_session_signals != NULL) {
> +        dbus_error_init(&error);
> +        dbus_bus_remove_match(si->connection,
> +                              si->match_session_signals,
> +                              &error);
> +
> +        if (si->verbose)
> +            syslog(LOG_DEBUG, "(console-kit) session match removed: %s",
> +                   si->match_session_signals);
> +        g_free(si->match_session_signals);
> +    }
>  }
>  
>  static void si_dbus_match_rule_update(struct session_info *si)
> @@ -96,6 +118,28 @@ static void si_dbus_match_rule_update(struct session_info
> *si)
>              g_free(si->match_seat_signals);
>          }
>      }
> +
> +    /* Session signals */
> +    if (si->active_session != NULL) {
> +        si->match_session_signals =
> +            g_strdup_printf ("type='signal',interface='%s',path='%s'",
> +                             INTERFACE_CK_SESSION,
> +                             si->active_session);
> +        if (si->verbose)
> +            syslog(LOG_DEBUG, "(console-kit) session match: %s",
> +                   si->match_session_signals);
> +
> +        dbus_error_init(&error);
> +        dbus_bus_add_match(si->connection,
> +                           si->match_session_signals,
> +                           &error);
> +        if (dbus_error_is_set(&error)) {
> +            syslog(LOG_WARNING, "Unable to add dbus rule match: %s",
> +                   error.message);
> +            dbus_error_free(&error);
> +            g_free(si->match_session_signals);
> +        }
> +    }
>  }
>  
>  static void
> @@ -129,6 +173,7 @@ si_dbus_read_signals(struct session_info *si)
>                  dbus_message_iter_get_basic(&iter, &session);
>                  if (session != NULL && session[0] != '\0') {
>                      si->active_session = g_strdup(session);
> +                    si_dbus_match_rule_update(si);
>                  } else if (si->verbose) {
>                      syslog(LOG_WARNING, "(console-kit) received invalid
> session. "
>                             "No active-session at the moment");
> @@ -141,6 +186,25 @@ si_dbus_read_signals(struct session_info *si)
>                         "ActiveSessionChanged message has unexpected type:
> '%c'",
>                         type);
>              }
> +        } else if (g_strcmp0(member, CK_SESSION_SIGNAL_LOCK) == 0) {
> +            si->session_is_locked = TRUE;
> +        } else if (g_strcmp0(member, CK_SESSION_SIGNAL_UNLOCK) == 0) {
> +            si->session_is_locked = FALSE;
> +        } else if (g_strcmp0(member, CK_SESSION_SIGNAL_IDLE_HINT_CHANGED) ==
> 0) {
> +            DBusMessageIter iter;
> +            gint type;
> +            dbus_bool_t idle_hint;
> +
> +            dbus_message_iter_init(message, &iter);
> +            type = dbus_message_iter_get_arg_type(&iter);
> +            if (type == DBUS_TYPE_BOOLEAN) {
> +                dbus_message_iter_get_basic(&iter, &idle_hint);
> +                si->session_idle_hint = (idle_hint);
> +            } else {
> +                syslog(LOG_ERR,
> +                       "(console-kit) IdleHintChanged has unexpected type:
> '%c'",
> +                       type);
> +            }
>          } else if (si->verbose) {
>              syslog(LOG_DEBUG, "(console-kit) Signal not handled: %s",
> member);
>          }
> @@ -161,6 +225,8 @@ struct session_info *session_info_create(int verbose)
>          return NULL;
>  
>      si->verbose = verbose;
> +    si->session_is_locked = FALSE;
> +    si->session_idle_hint = FALSE;
>  
>      dbus_error_init(&error);
>      si->connection = dbus_bus_get_private(DBUS_BUS_SYSTEM, &error);
> @@ -324,6 +390,7 @@ const char *session_info_get_active_session(struct
> session_info *si)
>      }
>  
>      si->active_session = strdup(session);
> +    si_dbus_match_rule_update(si);
>  
>  exit:
>      if (reply != NULL) {
> @@ -413,13 +480,23 @@ static char
> *console_kit_check_active_session_change(struct session_info *si)
>      if (si->verbose)
>          syslog(LOG_DEBUG, "(console-kit) active-session: '%s'",
>                 (si->active_session ? si->active_session : "None"));
> -

unnecessary whitespace change

>      return si->active_session;
>  }
>  
>  gboolean session_info_session_is_locked(struct session_info *si)
>  {
> -    /* TODO: It could be implemented based on Lock/Unlock signals from
> Session
> -     * interface. */
> -    return FALSE;
> +    if (si == NULL)
> +        return FALSE;
> +
> +    /* Not every system does emit Lock and Unlock signals (for instance, such
> +     * is the case for RHEL6) but most of the systems seems to emit the
> +     * IdleHintChanged. So, we give priority to the Lock signal, if it is
> Locked
> +     * we return that the session is locked, otherwise we double check with
> the
> +     * IdleHint value */
> +    si_dbus_read_signals(si);
> +    if (si->verbose) {
> +        syslog(LOG_DEBUG, "(console-kit) session is locked: %s",
> +               (si->session_is_locked || si->session_idle_hint) ? "yes" :
> "no");
> +    }
> +    return (si->session_is_locked || si->session_idle_hint);
>  }

Looks reasonable.

Acked-by: Jonathon Jongsma <jjongsma at redhat.com>


More information about the Spice-devel mailing list