From ae39f7001e5603010afc02de29787ade6d48ef14 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Fri, 22 Mar 2013 16:34:34 -0500 Subject: port indicator-session to GMenu/cmake. Code coverage increased from 0% to 95.4%. --- src/backend-dbus/guest.c | 570 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 570 insertions(+) create mode 100644 src/backend-dbus/guest.c (limited to 'src/backend-dbus/guest.c') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c new file mode 100644 index 0000000..516ba00 --- /dev/null +++ b/src/backend-dbus/guest.c @@ -0,0 +1,570 @@ +/* + * Copyright 2013 Canonical Ltd. + * + * Authors: + * Charles Kerr + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, 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, see . + */ + +#include + +#include "dbus-accounts.h" +#include "dbus-display-manager.h" +#include "dbus-user.h" +#include "dbus-consolekit-seat.h" +#include "dbus-consolekit-manager.h" +#include "dbus-consolekit-session.h" + +#include "guest.h" + +struct _IndicatorSessionGuestDbusPriv +{ + GCancellable * cancellable; + + Accounts * accounts; + AccountsUser * guest; + DisplayManagerSeat * display_manager_seat; + + ConsoleKitSeat * seat; + ConsoleKitSession * active_session; + guint active_uid; + + gboolean guest_is_active; + gboolean guest_is_allowed; +}; + +typedef IndicatorSessionGuestDbusPriv priv_t; + +G_DEFINE_TYPE (IndicatorSessionGuestDbus, + indicator_session_guest_dbus, + INDICATOR_TYPE_SESSION_GUEST) + +/*** +**** +***/ + +static void +check_for_active_guest (IndicatorSessionGuestDbus * self) +{ + gboolean guest_is_active; + priv_t * p = self->priv; + + guest_is_active = (p->active_uid) + && (p->guest != NULL) + && (p->active_uid == accounts_user_get_uid (p->guest)); + + if (p->guest_is_active != guest_is_active) + { + p->guest_is_active = guest_is_active; + + indicator_session_guest_notify_active (INDICATOR_SESSION_GUEST(self)); + } +} + +static void +set_active_uid (IndicatorSessionGuestDbus * self, guint uid) +{ + self->priv->active_uid = uid; + + check_for_active_guest (self); +} + +static void +on_active_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + guint uid; + GError * err; + IndicatorSessionGuestDbus * self; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + uid = 0; + err = NULL; + self = INDICATOR_SESSION_GUEST_DBUS (gself); + console_kit_session_call_get_unix_user_finish (self->priv->active_session, &uid, res, &err); + + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + set_active_uid (self, uid); + } +} + + +static void +set_active_session (IndicatorSessionGuestDbus * self, + ConsoleKitSession * session) +{ + priv_t * p = self->priv; + + if (p->active_session != NULL) + { + g_debug ("%s %s active_session refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->active_session)->ref_count); + + g_clear_object (&p->active_session); + } + + if (session != NULL) + { + p->active_session = g_object_ref (session); + + console_kit_session_call_get_unix_user (session, + p->cancellable, + on_active_uid_ready, + self); + } +} + +static void +on_active_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) +{ + GError * err; + ConsoleKitSession * session; + + err = NULL; + session = console_kit_session_proxy_new_finish (res, &err); + + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + } + else + { + set_active_session (gself, session); + } + + g_clear_object (&session); +} + + +static void +on_active_session_changed (ConsoleKitSeat * seat G_GNUC_UNUSED, + const gchar * ssid, + IndicatorSessionGuestDbus * self) +{ + console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.ConsoleKit", + ssid, + self->priv->cancellable, + on_active_session_proxy_ready, + self); +} + +static void +set_seat (IndicatorSessionGuestDbus * self, + ConsoleKitSeat * seat) +{ + priv_t * p = self->priv; + + if (p->seat != NULL) + { +g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)p->seat); + g_signal_handlers_disconnect_by_data (p->seat, self); +g_debug ("%s %s seat refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->seat)->ref_count); + + g_clear_object (&p->seat); + } + + if (seat != NULL) + { + p->seat = g_object_ref (seat); +g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)p->seat); + + g_signal_connect (seat, "active-session-changed", + G_CALLBACK(on_active_session_changed), self); + } +} + +/*** +**** +***/ + +static void +set_guest (IndicatorSessionGuestDbus * self, + AccountsUser * guest) +{ + priv_t * p = self->priv; + + if (p->guest != NULL) + { + g_debug ("%s %s guest refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->guest)->ref_count); + + g_clear_object (&p->guest); + } + + if (guest != NULL) + { + p->guest = g_object_ref (guest); + } + + g_debug ("%s %s guest proxy is now %p", G_STRLOC, G_STRFUNC, (void*)guest); + indicator_session_guest_notify_logged_in (INDICATOR_SESSION_GUEST(self)); + + check_for_active_guest (self); +} + +static void +on_user_deleted (IndicatorSessionGuestDbus * self, + const gchar * path) +{ + AccountsUser * guest = self->priv->guest; + g_debug ("%s %s %s", G_STRLOC, G_STRFUNC, path); + + if (guest != NULL) + if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (G_DBUS_PROXY(guest)))) + set_guest (self, NULL); +} + +static gboolean +is_guest (AccountsUser * user) +{ + /* a guest will look like this: + username:[guest-jjbEVV] realname:[Guest] system:[1] */ + return IS_ACCOUNTS_USER(user) + && accounts_user_get_system_account (user) + && !g_ascii_strcasecmp (accounts_user_get_real_name(user), "Guest"); +} + +static void +on_user_proxy_ready (GObject * o G_GNUC_UNUSED, + GAsyncResult * res, + gpointer self) +{ + GError * err; + AccountsUser * user; + + err = NULL; + user = accounts_user_proxy_new_for_bus_finish (res, &err); + + if (err != NULL) + { + g_warning ("%s: %s", G_STRFUNC, err->message); + g_error_free (err); + } + else if (is_guest (user)) + { + g_debug ("%s %s got guest", G_STRLOC, G_STRFUNC); + set_guest (INDICATOR_SESSION_GUEST_DBUS(self), user); + } + + g_clear_object (&user); +} + +static void +create_user_proxy_for_path (IndicatorSessionGuestDbus * self, + const char * path) +{ + const char * name = "org.freedesktop.Accounts"; + const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; + g_debug ("%s %s creating proxy for %s", G_STRLOC, G_STRFUNC, path); + + accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + flags, name, path, + self->priv->cancellable, + on_user_proxy_ready, self); +} + +static void +on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + gchar ** paths; + + err = NULL; + paths = NULL; + accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + int i; + + for (i=0; paths && paths[i]; ++i) + create_user_proxy_for_path (gself, paths[i]); + + g_strfreev (paths); + } +} + +static void +set_account_manager (IndicatorSessionGuestDbus * self, + Accounts * a) +{ + g_debug ("%s %s setting account manager to %p", G_STRLOC, G_STRFUNC, (void*)a); + + if (self->priv->accounts != NULL) + { +g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); + g_signal_handlers_disconnect_by_data (self->priv->accounts, self); +g_debug ("%s %s account manager refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->accounts)->ref_count); + g_clear_object (&self->priv->accounts); + } + + if (a != NULL) + { + self->priv->accounts = g_object_ref (a); + +g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); + g_signal_connect_swapped (a, "user-added", + G_CALLBACK(create_user_proxy_for_path), self); + + g_signal_connect_swapped (a, "user-deleted", + G_CALLBACK(on_user_deleted), self); + + accounts_call_list_cached_users (a, + self->priv->cancellable, + on_user_list_ready, + self); + } +} + +static void +set_guest_is_allowed (IndicatorSessionGuestDbus * self, gboolean guest_is_allowed) +{ + priv_t * p = self->priv; + g_debug ("%s %s guest_is_allowed: %d", G_STRLOC, G_STRFUNC, (int)guest_is_allowed); + + if (p->guest_is_allowed != guest_is_allowed) + { + p->guest_is_allowed = guest_is_allowed; + + indicator_session_guest_notify_allowed (INDICATOR_SESSION_GUEST (self)); + } +} + +static void +on_notify_has_guest_account (GObject * seat, GParamSpec * pspec G_GNUC_UNUSED, gpointer gself) +{ + set_guest_is_allowed (INDICATOR_SESSION_GUEST_DBUS (gself), + display_manager_seat_get_has_guest_account (DISPLAY_MANAGER_SEAT(seat))); +} + +static void +set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * seat) +{ + priv_t * p = self->priv; + + if (p->display_manager_seat != NULL) + { + g_signal_handlers_disconnect_by_data (p->display_manager_seat, self); + g_debug ("%s %s before we unref, dm seat's refcount is %d", G_STRLOC, G_STRFUNC, G_OBJECT(p->display_manager_seat)->ref_count); + g_clear_object (&p->display_manager_seat); + } + + if (seat != NULL) + { + p->display_manager_seat = g_object_ref (seat); + + g_signal_connect (seat, "notify::has-guest-account", G_CALLBACK(on_notify_has_guest_account), self); + + on_notify_has_guest_account (G_OBJECT(seat), NULL, self); + } +} + +#if 0 +static void +on_display_manager_seat_proxy_ready (GObject * o, GAsyncResult * res, gpointer gself) +{ + GError * err; + DisplayManagerSeat * seat; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + err = NULL; + seat = display_manager_seat_proxy_new_for_bus_finish (res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } + else + { + set_display_manager_seat (INDICATOR_SESSION_GUEST_DBUS(gself), seat); + } + + g_clear_object (&seat); +} +#endif + +static void +on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC_UNUSED) +{ + GError * err; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + err = NULL; + display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), res, &err); + if (err != NULL) + { + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); + } +} + +/*** +**** Virtual Functions +***/ + +static void +my_dispose (GObject * o) +{ + IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS (o); + + if (self->priv->cancellable != NULL) + { + g_cancellable_cancel (self->priv->cancellable); + g_clear_object (&self->priv->cancellable); + } + + set_seat (self, NULL); + set_active_session (self, NULL); + set_account_manager (self, NULL); + set_display_manager_seat (self, NULL); + g_clear_object (&self->priv->guest); + + G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); +} + +static void +my_finalize (GObject * o) +{ + /*IndicatorSessionGuestDbus * u = INDICATOR_SESSION_GUEST_DBUS (o);*/ + + G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->finalize (o); +} + +static gboolean +my_is_allowed (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); + + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_allowed; +} + +static gboolean +my_is_logged_in (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); + + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest != NULL; +} + +static gboolean +my_is_active (IndicatorSessionGuest * self) +{ + g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); + + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_active; +} + +static void +my_switch_to_guest (IndicatorSessionGuest * self) +{ + priv_t * p; + g_debug ("%s %s", G_STRLOC, G_STRFUNC); + + g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); + + p = INDICATOR_SESSION_GUEST_DBUS(self)->priv; + + if (p->display_manager_seat != NULL) + { + display_manager_seat_call_switch_to_guest (p->display_manager_seat, + "", + p->cancellable, + on_switch_to_guest_done, + self); + } +} + +/*** +**** GObject Boilerplate +***/ + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) +{ + GObjectClass * object_class; + IndicatorSessionGuestClass * guest_class; + + object_class = G_OBJECT_CLASS (klass); + object_class->dispose = my_dispose; + object_class->finalize = my_finalize; + + guest_class = INDICATOR_SESSION_GUEST_CLASS (klass); + guest_class->is_allowed = my_is_allowed; + guest_class->is_logged_in = my_is_logged_in; + guest_class->is_active = my_is_active; + guest_class->switch_to_guest = my_switch_to_guest; + + g_type_class_add_private (klass, sizeof (IndicatorSessionGuestDbusPriv)); +} + +static void +/* cppcheck-suppress unusedFunction */ +indicator_session_guest_dbus_init (IndicatorSessionGuestDbus * self) +{ + priv_t * p; + + p = G_TYPE_INSTANCE_GET_PRIVATE (self, + INDICATOR_TYPE_SESSION_GUEST_DBUS, + IndicatorSessionGuestDbusPriv); + p->cancellable = g_cancellable_new (); + self->priv = p; + +#if 0 + display_manager_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, + G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, + "org.freedesktop.DisplayManager", + g_getenv ("XDG_SEAT_PATH"), + self->priv->cancellable, + on_display_manager_seat_proxy_ready, + self); +#endif +} + +/*** +**** Public +***/ + +IndicatorSessionGuest * +indicator_session_guest_dbus_new (void) +{ + gpointer o = g_object_new (INDICATOR_TYPE_SESSION_GUEST_DBUS, NULL); + + return INDICATOR_SESSION_GUEST (o); +} + +void +indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus * self, + Accounts * accounts, + DisplayManagerSeat * dm_seat, + ConsoleKitSeat * seat, + ConsoleKitSession * session) +{ + g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); + g_debug ("%s %s accounts %p seat %p session %p", G_STRLOC, G_STRFUNC, (void*)accounts, (void*)seat, (void*)session); + + set_account_manager (self, accounts); + set_display_manager_seat (self, dm_seat); + set_seat (self, seat); + set_active_session (self, session); +} -- cgit v1.2.3 From 6ff4e525b7f1a090450b3ff40cff082888250323 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Thu, 18 Apr 2013 11:33:20 -0500 Subject: remove #if 0 code --- src/backend-dbus/guest.c | 34 ---------------------------------- 1 file changed, 34 deletions(-) (limited to 'src/backend-dbus/guest.c') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 516ba00..1559aa8 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -379,30 +379,6 @@ set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * } } -#if 0 -static void -on_display_manager_seat_proxy_ready (GObject * o, GAsyncResult * res, gpointer gself) -{ - GError * err; - DisplayManagerSeat * seat; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - err = NULL; - seat = display_manager_seat_proxy_new_for_bus_finish (res, &err); - if (err != NULL) - { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - g_error_free (err); - } - else - { - set_display_manager_seat (INDICATOR_SESSION_GUEST_DBUS(gself), seat); - } - - g_clear_object (&seat); -} -#endif - static void on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC_UNUSED) { @@ -529,16 +505,6 @@ indicator_session_guest_dbus_init (IndicatorSessionGuestDbus * self) IndicatorSessionGuestDbusPriv); p->cancellable = g_cancellable_new (); self->priv = p; - -#if 0 - display_manager_seat_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.DisplayManager", - g_getenv ("XDG_SEAT_PATH"), - self->priv->cancellable, - on_display_manager_seat_proxy_ready, - self); -#endif } /*** -- cgit v1.2.3 From 093aed6a5e8c35bfe5a3e187fed3e293e2d12183 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 19 Jun 2013 18:16:56 -0500 Subject: in our async callbacks, don't call g_warning() if the task was cancelled by the client --- src/backend-dbus/guest.c | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) (limited to 'src/backend-dbus/guest.c') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 1559aa8..317152d 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -95,7 +95,9 @@ on_active_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gse if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -140,7 +142,10 @@ on_active_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gp if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + + g_error_free (err); } else { @@ -253,7 +258,9 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, if (err != NULL) { - g_warning ("%s: %s", G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s: %s", G_STRFUNC, err->message); + g_error_free (err); } else if (is_guest (user)) @@ -290,7 +297,9 @@ on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } else @@ -389,7 +398,9 @@ on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), res, &err); if (err != NULL) { - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) + g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + g_error_free (err); } } @@ -418,14 +429,6 @@ my_dispose (GObject * o) G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); } -static void -my_finalize (GObject * o) -{ - /*IndicatorSessionGuestDbus * u = INDICATOR_SESSION_GUEST_DBUS (o);*/ - - G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->finalize (o); -} - static gboolean my_is_allowed (IndicatorSessionGuest * self) { @@ -483,7 +486,6 @@ indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) object_class = G_OBJECT_CLASS (klass); object_class->dispose = my_dispose; - object_class->finalize = my_finalize; guest_class = INDICATOR_SESSION_GUEST_CLASS (klass); guest_class->is_allowed = my_is_allowed; -- cgit v1.2.3 From d3fe504ae1f9936c508bfd95427767833044811a Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 24 Jun 2013 10:20:08 -0500 Subject: in IndicatorSessionGuest, update to login1 --- src/backend-dbus/guest.c | 466 ++++++++++++++++------------------------------- 1 file changed, 158 insertions(+), 308 deletions(-) (limited to 'src/backend-dbus/guest.c') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 317152d..fcb3604 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -19,28 +19,18 @@ #include -#include "dbus-accounts.h" -#include "dbus-display-manager.h" -#include "dbus-user.h" -#include "dbus-consolekit-seat.h" -#include "dbus-consolekit-manager.h" -#include "dbus-consolekit-session.h" - #include "guest.h" struct _IndicatorSessionGuestDbusPriv { GCancellable * cancellable; - Accounts * accounts; - AccountsUser * guest; - DisplayManagerSeat * display_manager_seat; - - ConsoleKitSeat * seat; - ConsoleKitSession * active_session; - guint active_uid; + Login1Manager * login1_manager; + Login1Seat * login1_seat; + DisplayManagerSeat * dm_seat; gboolean guest_is_active; + gboolean guest_is_logged_in; gboolean guest_is_allowed; }; @@ -55,143 +45,41 @@ G_DEFINE_TYPE (IndicatorSessionGuestDbus, ***/ static void -check_for_active_guest (IndicatorSessionGuestDbus * self) +set_guest_is_allowed_flag (IndicatorSessionGuestDbus * self, gboolean b) { - gboolean guest_is_active; priv_t * p = self->priv; - guest_is_active = (p->active_uid) - && (p->guest != NULL) - && (p->active_uid == accounts_user_get_uid (p->guest)); - - if (p->guest_is_active != guest_is_active) - { - p->guest_is_active = guest_is_active; - - indicator_session_guest_notify_active (INDICATOR_SESSION_GUEST(self)); - } -} - -static void -set_active_uid (IndicatorSessionGuestDbus * self, guint uid) -{ - self->priv->active_uid = uid; - - check_for_active_guest (self); -} - -static void -on_active_uid_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) -{ - guint uid; - GError * err; - IndicatorSessionGuestDbus * self; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - uid = 0; - err = NULL; - self = INDICATOR_SESSION_GUEST_DBUS (gself); - console_kit_session_call_get_unix_user_finish (self->priv->active_session, &uid, res, &err); - - if (err != NULL) + if (p->guest_is_allowed != b) { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + p->guest_is_allowed = b; - g_error_free (err); - } - else - { - set_active_uid (self, uid); + indicator_session_guest_notify_allowed (INDICATOR_SESSION_GUEST (self)); } } - static void -set_active_session (IndicatorSessionGuestDbus * self, - ConsoleKitSession * session) +set_guest_is_logged_in_flag (IndicatorSessionGuestDbus * self, gboolean b) { priv_t * p = self->priv; - if (p->active_session != NULL) + if (p->guest_is_logged_in != b) { - g_debug ("%s %s active_session refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->active_session)->ref_count); + p->guest_is_logged_in = b; - g_clear_object (&p->active_session); - } - - if (session != NULL) - { - p->active_session = g_object_ref (session); - - console_kit_session_call_get_unix_user (session, - p->cancellable, - on_active_uid_ready, - self); + indicator_session_guest_notify_logged_in (INDICATOR_SESSION_GUEST (self)); } } static void -on_active_session_proxy_ready (GObject * o G_GNUC_UNUSED, GAsyncResult * res, gpointer gself) -{ - GError * err; - ConsoleKitSession * session; - - err = NULL; - session = console_kit_session_proxy_new_finish (res, &err); - - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); - - g_error_free (err); - } - else - { - set_active_session (gself, session); - } - - g_clear_object (&session); -} - - -static void -on_active_session_changed (ConsoleKitSeat * seat G_GNUC_UNUSED, - const gchar * ssid, - IndicatorSessionGuestDbus * self) -{ - console_kit_session_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES, - "org.freedesktop.ConsoleKit", - ssid, - self->priv->cancellable, - on_active_session_proxy_ready, - self); -} - -static void -set_seat (IndicatorSessionGuestDbus * self, - ConsoleKitSeat * seat) +set_guest_is_active_flag (IndicatorSessionGuestDbus * self, gboolean b) { priv_t * p = self->priv; - if (p->seat != NULL) + if (p->guest_is_active != b) { -g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)p->seat); - g_signal_handlers_disconnect_by_data (p->seat, self); -g_debug ("%s %s seat refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->seat)->ref_count); + p->guest_is_active = b; - g_clear_object (&p->seat); - } - - if (seat != NULL) - { - p->seat = g_object_ref (seat); -g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)p->seat); - - g_signal_connect (seat, "active-session-changed", - G_CALLBACK(on_active_session_changed), self); + indicator_session_guest_notify_active (INDICATOR_SESSION_GUEST(self)); } } @@ -199,63 +87,21 @@ g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)p->sea **** ***/ +/* walk the sessions to see if guest is logged in or active */ static void -set_guest (IndicatorSessionGuestDbus * self, - AccountsUser * guest) -{ - priv_t * p = self->priv; - - if (p->guest != NULL) - { - g_debug ("%s %s guest refcount is %d before we unref", G_STRLOC, G_STRFUNC, G_OBJECT(p->guest)->ref_count); - - g_clear_object (&p->guest); - } - - if (guest != NULL) - { - p->guest = g_object_ref (guest); - } - - g_debug ("%s %s guest proxy is now %p", G_STRLOC, G_STRFUNC, (void*)guest); - indicator_session_guest_notify_logged_in (INDICATOR_SESSION_GUEST(self)); - - check_for_active_guest (self); -} - -static void -on_user_deleted (IndicatorSessionGuestDbus * self, - const gchar * path) -{ - AccountsUser * guest = self->priv->guest; - g_debug ("%s %s %s", G_STRLOC, G_STRFUNC, path); - - if (guest != NULL) - if (!g_strcmp0 (path, g_dbus_proxy_get_object_path (G_DBUS_PROXY(guest)))) - set_guest (self, NULL); -} - -static gboolean -is_guest (AccountsUser * user) -{ - /* a guest will look like this: - username:[guest-jjbEVV] realname:[Guest] system:[1] */ - return IS_ACCOUNTS_USER(user) - && accounts_user_get_system_account (user) - && !g_ascii_strcasecmp (accounts_user_get_real_name(user), "Guest"); -} - -static void -on_user_proxy_ready (GObject * o G_GNUC_UNUSED, - GAsyncResult * res, - gpointer self) +on_login1_manager_session_list_ready (GObject * o, + GAsyncResult * res, + gpointer gself) { + GVariant * sessions; GError * err; - AccountsUser * user; + sessions = NULL; err = NULL; - user = accounts_user_proxy_new_for_bus_finish (res, &err); - + login1_manager_call_list_sessions_finish (LOGIN1_MANAGER(o), + &sessions, + res, + &err); if (err != NULL) { if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -263,139 +109,141 @@ on_user_proxy_ready (GObject * o G_GNUC_UNUSED, g_error_free (err); } - else if (is_guest (user)) + else { - g_debug ("%s %s got guest", G_STRLOC, G_STRFUNC); - set_guest (INDICATOR_SESSION_GUEST_DBUS(self), user); + const gchar * const current_seat_id = g_getenv ("XDG_SEAT"); + const gchar * const current_session_id = g_getenv ("XDG_SESSION_ID"); + gboolean is_logged_in = FALSE; + gboolean is_active = FALSE; + const gchar * session_id = NULL; + guint32 uid = 0; + const gchar * user_name = NULL; + const gchar * seat_id = NULL; + const gchar * path = NULL; + GVariantIter iter; + + g_variant_iter_init (&iter, sessions); + while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, + &uid, + &user_name, + &seat_id, + &path)) + { + gboolean is_current_session; + gboolean is_guest; + + is_current_session = !g_strcmp0 (current_seat_id, seat_id) + && !g_strcmp0 (current_session_id, session_id); + + is_guest = g_str_has_prefix (user_name, "guest-") + && (uid < 1000); + + if (is_guest) + { + is_logged_in = TRUE; + + is_active = is_current_session; + } + } + + set_guest_is_logged_in_flag (gself, is_logged_in); + set_guest_is_active_flag (gself, is_active); + + g_variant_unref (sessions); } - - g_clear_object (&user); -} - -static void -create_user_proxy_for_path (IndicatorSessionGuestDbus * self, - const char * path) -{ - const char * name = "org.freedesktop.Accounts"; - const GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_GET_INVALIDATED_PROPERTIES; - g_debug ("%s %s creating proxy for %s", G_STRLOC, G_STRFUNC, path); - - accounts_user_proxy_new_for_bus (G_BUS_TYPE_SYSTEM, - flags, name, path, - self->priv->cancellable, - on_user_proxy_ready, self); } static void -on_user_list_ready (GObject * o, GAsyncResult * res, gpointer gself) +update_session_list (IndicatorSessionGuestDbus * self) { - GError * err; - gchar ** paths; - - err = NULL; - paths = NULL; - accounts_call_list_cached_users_finish (ACCOUNTS(o), &paths, res, &err); - if (err != NULL) - { - if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) - g_warning ("%s %s: %s", G_STRLOC, G_STRFUNC, err->message); + priv_t * p = self->priv; - g_error_free (err); - } - else + if (p->login1_manager != NULL) { - int i; - - for (i=0; paths && paths[i]; ++i) - create_user_proxy_for_path (gself, paths[i]); - - g_strfreev (paths); + login1_manager_call_list_sessions (p->login1_manager, + p->cancellable, + on_login1_manager_session_list_ready, + self); } } static void -set_account_manager (IndicatorSessionGuestDbus * self, - Accounts * a) +set_login1_manager (IndicatorSessionGuestDbus * self, + Login1Manager * login1_manager) { - g_debug ("%s %s setting account manager to %p", G_STRLOC, G_STRFUNC, (void*)a); + priv_t * p = self->priv; - if (self->priv->accounts != NULL) + if (p->login1_manager != NULL) { -g_debug ("%s %s guest-dbus disconnecting from %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); - g_signal_handlers_disconnect_by_data (self->priv->accounts, self); -g_debug ("%s %s account manager refcount is %d before our unref", G_STRLOC, G_STRFUNC, G_OBJECT(self->priv->accounts)->ref_count); - g_clear_object (&self->priv->accounts); + g_signal_handlers_disconnect_by_data (p->login1_manager, self); + + g_clear_object (&p->login1_manager); } - if (a != NULL) + if (login1_manager != NULL) { - self->priv->accounts = g_object_ref (a); - -g_debug ("%s %s guest-dbus connecting to %p", G_STRLOC, G_STRFUNC, (void*)self->priv->accounts); - g_signal_connect_swapped (a, "user-added", - G_CALLBACK(create_user_proxy_for_path), self); - - g_signal_connect_swapped (a, "user-deleted", - G_CALLBACK(on_user_deleted), self); + p->login1_manager = g_object_ref (login1_manager); - accounts_call_list_cached_users (a, - self->priv->cancellable, - on_user_list_ready, - self); + g_signal_connect_swapped (login1_manager, "session-new", + G_CALLBACK(update_session_list), self); + g_signal_connect_swapped (login1_manager, "session-removed", + G_CALLBACK(update_session_list), self); + update_session_list (self); } } static void -set_guest_is_allowed (IndicatorSessionGuestDbus * self, gboolean guest_is_allowed) +update_guest_allowed (IndicatorSessionGuestDbus * self) { priv_t * p = self->priv; - g_debug ("%s %s guest_is_allowed: %d", G_STRLOC, G_STRFUNC, (int)guest_is_allowed); - - if (p->guest_is_allowed != guest_is_allowed) - { - p->guest_is_allowed = guest_is_allowed; - indicator_session_guest_notify_allowed (INDICATOR_SESSION_GUEST (self)); - } -} + gboolean allowed = p->login1_seat + && login1_seat_get_can_multi_session (p->login1_seat); -static void -on_notify_has_guest_account (GObject * seat, GParamSpec * pspec G_GNUC_UNUSED, gpointer gself) -{ - set_guest_is_allowed (INDICATOR_SESSION_GUEST_DBUS (gself), - display_manager_seat_get_has_guest_account (DISPLAY_MANAGER_SEAT(seat))); + set_guest_is_allowed_flag (self, allowed); } static void -set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * seat) +set_login1_seat (IndicatorSessionGuestDbus * self, + Login1Seat * login1_seat) { priv_t * p = self->priv; - if (p->display_manager_seat != NULL) + if (p->login1_seat != NULL) { - g_signal_handlers_disconnect_by_data (p->display_manager_seat, self); - g_debug ("%s %s before we unref, dm seat's refcount is %d", G_STRLOC, G_STRFUNC, G_OBJECT(p->display_manager_seat)->ref_count); - g_clear_object (&p->display_manager_seat); + g_signal_handlers_disconnect_by_data (p->login1_seat, self); + g_clear_object (&p->login1_seat); } - if (seat != NULL) + if (login1_seat != NULL) { - p->display_manager_seat = g_object_ref (seat); + p->login1_seat = g_object_ref (login1_seat); - g_signal_connect (seat, "notify::has-guest-account", G_CALLBACK(on_notify_has_guest_account), self); + g_signal_connect_swapped (login1_seat, "notify::active-session", + G_CALLBACK(update_session_list), self); + update_session_list (self); - on_notify_has_guest_account (G_OBJECT(seat), NULL, self); + g_signal_connect_swapped (login1_seat, "notify::can-multi-session", + G_CALLBACK(update_guest_allowed), self); + update_guest_allowed (self); } } +/*** +**** +***/ + static void -on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC_UNUSED) +on_switch_to_guest_done (GObject * o, + GAsyncResult * res, + gpointer unused G_GNUC_UNUSED) { GError * err; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); err = NULL; - display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), res, &err); + display_manager_seat_call_switch_to_guest_finish (DISPLAY_MANAGER_SEAT(o), + res, + &err); if (err != NULL) { if (!g_error_matches (err, G_IO_ERROR, G_IO_ERROR_CANCELLED)) @@ -405,30 +253,35 @@ on_switch_to_guest_done (GObject * o, GAsyncResult * res, gpointer unused G_GNUC } } -/*** -**** Virtual Functions -***/ - static void -my_dispose (GObject * o) +my_switch_to_guest (IndicatorSessionGuest * guest) { - IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS (o); + IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS(guest); - if (self->priv->cancellable != NULL) - { - g_cancellable_cancel (self->priv->cancellable); - g_clear_object (&self->priv->cancellable); - } + g_return_if_fail (self != NULL); + g_return_if_fail (self->priv->dm_seat != NULL); - set_seat (self, NULL); - set_active_session (self, NULL); - set_account_manager (self, NULL); - set_display_manager_seat (self, NULL); - g_clear_object (&self->priv->guest); + display_manager_seat_call_switch_to_guest (self->priv->dm_seat, + "", + self->priv->cancellable, + on_switch_to_guest_done, + self); +} - G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); +static void +set_display_manager_seat (IndicatorSessionGuestDbus * self, + DisplayManagerSeat * dm_seat) +{ + g_clear_object (&self->priv->dm_seat); + + if (dm_seat != NULL) + self->priv->dm_seat = g_object_ref (dm_seat); } +/*** +**** IndiatorSessionGuest Virtual Functions +***/ + static gboolean my_is_allowed (IndicatorSessionGuest * self) { @@ -442,7 +295,7 @@ my_is_logged_in (IndicatorSessionGuest * self) { g_return_val_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self), FALSE); - return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest != NULL; + return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_logged_in; } static gboolean @@ -453,32 +306,33 @@ my_is_active (IndicatorSessionGuest * self) return INDICATOR_SESSION_GUEST_DBUS(self)->priv->guest_is_active; } +/*** +**** GObject Virtual Functions +***/ + static void -my_switch_to_guest (IndicatorSessionGuest * self) +my_dispose (GObject * o) { - priv_t * p; - g_debug ("%s %s", G_STRLOC, G_STRFUNC); - - g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); - - p = INDICATOR_SESSION_GUEST_DBUS(self)->priv; + IndicatorSessionGuestDbus * self = INDICATOR_SESSION_GUEST_DBUS (o); - if (p->display_manager_seat != NULL) + if (self->priv->cancellable != NULL) { - display_manager_seat_call_switch_to_guest (p->display_manager_seat, - "", - p->cancellable, - on_switch_to_guest_done, - self); + g_cancellable_cancel (self->priv->cancellable); + g_clear_object (&self->priv->cancellable); } + + set_login1_seat (self, NULL); + set_login1_manager (self, NULL); + set_display_manager_seat (self, NULL); + + G_OBJECT_CLASS (indicator_session_guest_dbus_parent_class)->dispose (o); } /*** -**** GObject Boilerplate +**** Instantiation ***/ static void -/* cppcheck-suppress unusedFunction */ indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) { GObjectClass * object_class; @@ -497,7 +351,6 @@ indicator_session_guest_dbus_class_init (IndicatorSessionGuestDbusClass * klass) } static void -/* cppcheck-suppress unusedFunction */ indicator_session_guest_dbus_init (IndicatorSessionGuestDbus * self) { priv_t * p; @@ -523,16 +376,13 @@ indicator_session_guest_dbus_new (void) void indicator_session_guest_dbus_set_proxies (IndicatorSessionGuestDbus * self, - Accounts * accounts, - DisplayManagerSeat * dm_seat, - ConsoleKitSeat * seat, - ConsoleKitSession * session) + Login1Manager * login1_manager, + Login1Seat * login1_seat, + DisplayManagerSeat * dm_seat) { g_return_if_fail (INDICATOR_IS_SESSION_GUEST_DBUS(self)); - g_debug ("%s %s accounts %p seat %p session %p", G_STRLOC, G_STRFUNC, (void*)accounts, (void*)seat, (void*)session); - set_account_manager (self, accounts); + set_login1_manager (self, login1_manager); + set_login1_seat (self, login1_seat); set_display_manager_seat (self, dm_seat); - set_seat (self, seat); - set_active_session (self, session); } -- cgit v1.2.3 From 9ed837fbafae3021d597508ba9272a54d3623534 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 12:32:16 -0500 Subject: test-guest's HelloWorld and Allowed tests now pass --- src/backend-dbus/guest.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) (limited to 'src/backend-dbus/guest.c') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index fcb3604..08ac648 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -192,17 +192,6 @@ set_login1_manager (IndicatorSessionGuestDbus * self, } } -static void -update_guest_allowed (IndicatorSessionGuestDbus * self) -{ - priv_t * p = self->priv; - - gboolean allowed = p->login1_seat - && login1_seat_get_can_multi_session (p->login1_seat); - - set_guest_is_allowed_flag (self, allowed); -} - static void set_login1_seat (IndicatorSessionGuestDbus * self, Login1Seat * login1_seat) @@ -222,10 +211,6 @@ set_login1_seat (IndicatorSessionGuestDbus * self, g_signal_connect_swapped (login1_seat, "notify::active-session", G_CALLBACK(update_session_list), self); update_session_list (self); - - g_signal_connect_swapped (login1_seat, "notify::can-multi-session", - G_CALLBACK(update_guest_allowed), self); - update_guest_allowed (self); } } @@ -268,14 +253,37 @@ my_switch_to_guest (IndicatorSessionGuest * guest) self); } +static void +on_notify_has_guest_account (DisplayManagerSeat * dm_seat, + GParamSpec * pspec G_GNUC_UNUSED, + IndicatorSessionGuestDbus * self) +{ + gboolean guest_exists = display_manager_seat_get_has_guest_account (dm_seat); + set_guest_is_allowed_flag (self, guest_exists); +} + static void set_display_manager_seat (IndicatorSessionGuestDbus * self, DisplayManagerSeat * dm_seat) { - g_clear_object (&self->priv->dm_seat); + priv_t * p = self->priv; + + if (p->dm_seat != NULL) + { + g_signal_handlers_disconnect_by_data (p->dm_seat, self); + + g_clear_object (&p->dm_seat); + } if (dm_seat != NULL) - self->priv->dm_seat = g_object_ref (dm_seat); + { + p->dm_seat = g_object_ref (dm_seat); + + g_signal_connect (dm_seat, "notify::has-guest-account", + G_CALLBACK(on_notify_has_guest_account), self); + on_notify_has_guest_account (dm_seat, NULL, self); + } + } /*** -- cgit v1.2.3 From 3cabab005963648247d8af74645c8e245efe13e8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Tue, 25 Jun 2013 13:36:02 -0500 Subject: everything in test-guest now passes --- src/backend-dbus/guest.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/backend-dbus/guest.c') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 08ac648..963bdc8 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -283,7 +283,6 @@ set_display_manager_seat (IndicatorSessionGuestDbus * self, G_CALLBACK(on_notify_has_guest_account), self); on_notify_has_guest_account (dm_seat, NULL, self); } - } /*** -- cgit v1.2.3 From 73a9ac42d15b01c6807eb5bdaee0c24431e7e539 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Mon, 1 Jul 2013 12:54:52 -0500 Subject: in src/backend-dbus/guest.c's on_login1_manager_session_list_ready(), remove unused variable 'path' --- src/backend-dbus/guest.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'src/backend-dbus/guest.c') diff --git a/src/backend-dbus/guest.c b/src/backend-dbus/guest.c index 963bdc8..3269097 100644 --- a/src/backend-dbus/guest.c +++ b/src/backend-dbus/guest.c @@ -119,15 +119,14 @@ on_login1_manager_session_list_ready (GObject * o, guint32 uid = 0; const gchar * user_name = NULL; const gchar * seat_id = NULL; - const gchar * path = NULL; GVariantIter iter; g_variant_iter_init (&iter, sessions); - while (g_variant_iter_loop (&iter, "(&su&s&s&o)", &session_id, + while (g_variant_iter_loop (&iter, "(&su&s&so)", &session_id, &uid, &user_name, &seat_id, - &path)) + NULL)) { gboolean is_current_session; gboolean is_guest; -- cgit v1.2.3