[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